<?php
/**
 * Created by PhpStorm.
 * User: Kavand
 * Date: 7/27/2018
 * Time: 9:28 AM
 */

class ApplicationSystem
{
    private $object = [];
    private $DLA = null;
    private $SMS = null;
    private $Crypter = null;
    private $WebServices = null;

    private $LoginDataWebServices = array("User" => "romouzi", "Pass" => "zmr_13111363rmz", 'GroupCode' => 3131);

    private $limit_load = 50;

    private $def_zoom = 10;
    private $EndDistance = 2000;// ta fasle 10 kilometers
    private $StartDistance = 500;// az fasele 500 metre

    private $R = 6371392.896;//shoa zamin az meter // 6371 kilo meter // 3959 miles

    private $sms_limit_per_day = 10; // tedad sms haye ersali bare yek shomare dar roz

    public function ApplicationSystem($object, $option = 'HEADER')
    {
        $this->SetupSystem($object, $option);
    }


    public function __construct($object, $option = 'HEADER')
    {
        $this->SetupSystem($object, $option);
    }


    private function SetupSystem($object, $option = 'HEADER')
    {
        //        ini_set('display_errors', 1);
//        error_reporting(~0);
        if ($option == 'HEADER') {
            header('Content-Type: text/event-stream');
            header("Content-Type: application/json; charset=UTF-8");
        }
        error_reporting(1);
        require_once('DAL/DAL.php');
        require_once('DAL/sms/SendMessage.php');
        require_once('DAL/Crypter.php');
        require_once("WebServiceSystem.php");
        require_once('DAL/public-function.php');
        $this->WebServices = new WebServiceSystem();
        $this->DLA = new DAL('constant.php');
        $this->Crypter = new Crypter();
        $this->SMS = new SendMessage();
        $this->object = $object;
    }

    private function OutputData($data, $request, $error)
    {
        ob_clean();
        ob_end_clean();
        $time = time();
        $return = array(
            'id' => $time . '-' . uniqid(),
            'server-time' => date("h:i:s", $time),
            'type' => $_SERVER['REQUEST_METHOD'],
            'request' => $request,
            'error' => $error,
            'response' => $data
        );
        print_r("[" . json_encode($return, JSON_UNESCAPED_UNICODE) . "]");
        ob_flush();
        flush();
        return;
    }

    public function run()
    {

        $request = $this->object['request-app'];
        $data = "";
        $error = "";
        if (isset($this->object) and isset($request)) {
            switch ($request) {
                case 'test':
                    sleep(2);
                    $data = array('id' => uniqid());
                    break;
                case 'main-slid-show':
                    $data = $this->MainSlideShow();
                    break;
                case 'notification-list':
                    $data = $this->LoadNotificationList();
                    break;
                case 'notification-load':
                    $data = $this->LoadNotification($this->object['key']);
                    break;
                case 'load-acceptors-by-category':
                    $data = $this->LoadAcceptorsByTag($this->object['cat-id'], $this->object['from'], $this->limit_load, $this->object);
                    break;
                case 'category':
                    $data = $this->LoadCategory($this->object);
                    break;
                case 'bus_load':
                    $data = $this->BusLoad($this->object);
                    break;
                case 'main-item-menu':
                    $data = $this->ShopMenu($this->object['key'], $this->object['from'], $this->limit_load);
                    break;
                case 'shop-close-to-me':
                    $data = $this->ShopCloseToMe($this->object['location'], $this->object['from'], $this->object['distance'], $this->limit_load);
                    break;
                case 'acceptor-register':
                    $data = $this->AcceptorRegister($this->object);
                    break;
                case 'client-register':
                    $data = $this->ClientRegister($this->object);
                    break;
                case 'client-login':
                    $data = $this->ClientLogin($this->object);
                    break;
                case 'load-acceptor-by-id':
                    $data = $this->LoadSingleAcceptor($this->object['id']);
                    break;
                case 'acceptor-plus-visit':
                    $data = $this->PlusToVisit($this->object['item-id']);
                    break;
                case 'acceptor-plus-like':
                    $data = $this->PlusToLike($this->object['item-id']);
                    break;
                case 'our-last-client':
                    $data = $this->OurLastClient();
                    break;
                //push notification
                case 'list-notification-broadcast':
                    $data = $this->ListBroadcastNotification();
                    break;
                case 'send-notification-broadcast':
                    $data = $this->SendBroadcastNotification(@$this->object['sessions_id']);
                    break;
                //activate sms
                case 'send-active-sms':
                    $data = $this->SendActivateSms($this->object);
                    break;
                //html content
                case 'main-menu-web-panel':
                    $data = $this->WebPanel($this->object['key']);
                    break;
                case 'acceptor-panel':
                    $data = $this->AcceptorPage($this->object['user'], $this->object['pass']);
                    break;
                case 'about-us':
                    $data = $this->AboutUs();
                    break;
                case 'test-acceptor':
                    $data = $_REQUEST;
                    break;
                /*managment system*/
                case 'app-is-alive':
                    $data = $this->AppIsAlive();
                    break;
                /*client*/
                case 'app-client-panel-is-alive':
                    $data = $this->AppCheckPanel('client');
                    break;
                case 'app-clientregister-panel-is-alive':
                    $data = $this->AppCheckPanel('clientregister');
                    break;
                case 'app-acceptor-panel-is-alive':
                    $data = $this->AppCheckPanel('acceptor');
                    break;
                case 'app-visitor-panel-is-alive':
                    $data = $this->AppCheckPanel('visitor');
                    break;
                /*client*/

                /*app v2 new function*/
                case 'second-slid-show':
                    $data = $this->AppSecondSlideShow(7, (int)($this->limit_load / 2));
                    break;
                case 'installments-slid-show':
                    $data = $this->AppSecondSlideShow(8, (int)($this->limit_load / 2));
                    break;
                case 'add-new-card-nafis':
                    $data = $this->AppAddNewCard($this->object);
                    break;
                case 'update-user-profile':
                    $data = $this->AppEditProfile($this->object);
                    break;
                case 'report-system':
                    $data = $this->AppReportClientCard($this->object);
                    break;
                case 'city-load':
                    $data = $this->AppLoadCity($this->object);
                    break;
                /*warning so important*/
                case 'check-for-update':
                    $data = $this->AppCheckForUpdate($this->object);
                    break;
                /*warning so important*/
                case'bon-report-system':
                    $data = $this->AppBonServiceNafis($this->object);
                    break;
                case 'abi-report-system':
                    $data = $this->AppAbiServices($this->object, $_SERVER);
                    break;
                case 'external-function-caller':
                    $data = $this->ExternalCaller($this->object);
                    break;
                case 'user-card-list':
                    $data = $this->AppUserClientCard($this->object);
                    break;
                /*app v2 new function*/

                /*custom services*/
                case 'recycles-load-type-weight':
                    $data = $this->LodRecyclingMaterialOption($this->object);
                    break;
                case'add-recycling-request':
                    $data = $this->AddRecyclingRequest($this->object);
                    break;
                case 'load-recycling-request':
                    $data = $this->AppLoadRecyclingRequest($this->object);
                    break;
                case 'add-satisfaction-recycling' :
                    $data = $this->AppAddSatisfaction($this->object);
                    break;
                case 'remove-recycling-item' :
                    $data = $this->AppRemoveRecyclingItem($this->object);
                    break;
                case 'check-is-agent' :
                    $data = $this->AppCheckIsAgent($this->object);
                    break;
                /*custom services*/

                /*client-peyment*/
                case 'payment':
                    $data = $this->payment($this->object);
                    break;
                /*managment system*/
                default:
                    $this->OutputData("", $request, "Request not found [" . $request . "]");
                    return;
            }
            if (strlen($error) === 0 and $data) {
                $error = "no error";
            } elseif (strlen($error) === 0 and !$data) {
                $error = 'empty body';
            }
            $this->OutputData($data, $request, $error);
        } else {
            $this->OutputData("", "", "Request Empty");
        }
    }

    /*payment*/
    protected function payment($input)
    {
        require_once 'PaymentSystem.php';
        return (new PaymentSystem($input))->PayToCompany();
    }
    /*payment*/


    //slideShow aval barname
    protected function MainSlideShow()
    {

//        param.put("request", "app");
//        param.put("request-app", "slider-1");
        $select = $this->DLA->Select("SELECT `ID` ,`URL`, `POST_ID` FROM `app_slide_show` ");
        $outArr = array();
        if ($select) {
            foreach ($select as $item) {
                $outArr[] = array(
                    'id' => $item['ID'],
                    'url' => $item['URL'],
                    'post' => (strlen($item['POST_ID']) > 0 ? $item['POST_ID'] : "")
                );

            }
        }
        return $outArr;
    }

    //maghaze haye nazdike be man
    protected function ShopCloseToMe($location, $from, $custom_distance, $limit)
    {
        $outArr = array();
        $location = explode(',', $location);
        $lat = $location[0];
        $lng = $location[1];
        $distance = '';
        $distance .= "(";
        $distance .= "$this->R * acos (";
        $distance .= "        cos(radians($lat))";
        $distance .= "        * cos(radians(`Lat`))";
        $distance .= "        * cos(radians(`Lng`)-radians($lng))";
        $distance .= "        + sin(radians($lat))";
        $distance .= "        * sin(radians(`Lat`))";
        $distance .= "    )";
        $distance .= ")";


        $index = 1;
        if ($custom_distance == -1) $Distance = $this->StartDistance;
        else $Distance = $custom_distance;
        Query:
        $query = "SELECT *, $distance AS `distance` FROM `app_acceptor_list` WHERE `IsActive`=true HAVING `distance` < $Distance ORDER BY `distance`";
        $select = $this->DLA->Select($query);
        if ($select) {
            foreach ($select as $item) {
                $outArr[] = array(
                    'ID' => $item['ID'],
                    'url' => $this->ConvertStringToImageArray($item['sPhoto'], true),
                    'iName' => $item['sName'],
                    'address' => $item['sAddress'],
                    'dis-text' => $item['sDiscount'] . '%',
                    'dis' => $item['sDiscount'],
                    'location' => $item['sLocation'],
                    'lat' => $item['Lat'],
                    'lng' => $item['Lng'],
                    'zoom' => $this->def_zoom,
                );
            }
        } else {
            if ($custom_distance == -1) {
                if ($Distance < $this->EndDistance) {
                    $index += 1;
                    $Distance = ($this->StartDistance * $index);
                    goto Query;
                }
            }
        }

        return $outArr;
    }

    //shish ta menuye aval barname
    protected function ShopMenu($key, $from, $limit)
    {
        $outArr = array();
        $select = $this->DLA->Select("SELECT `content` FROM `app_main_panel_item` WHERE `ID`=$key AND `isActive`=true");
        if ($select AND count($select) === 1) {
            $content = json_decode($select[0]['content'], true);
            if (count($content) > 0) {
                foreach ($content as $item) {//for ($i = 0; $i < count($content); $i += 1) {
                    if (--$limit == 0) goto END;
                    if (--$from >= 0) continue;
                    $query = "SELECT * FROM `app_acceptor_list` WHERE `ID`=" . $item['id'] . " AND `IsActive`=true";
                    $shop = $this->DLA->Select($query);
                    if ($shop) {
                        $shop = $shop[0];
                        $outArr[] = array(
                            'ID' => $shop['ID'],
                            'url' => $this->ConvertStringToImageArray($shop['sPhoto'], true),
                            'iName' => $shop['sName'],
                            'address' => $shop['sAddress'],
                            'dis-text' => $shop['sDiscount'] . '%',
                            'dis' => $shop['sDiscount'],
                            'lat' => $shop['Lat'],
                            'lng' => $shop['Lng'],
                            'zoom' => $this->def_zoom,
                        );
                    }
                }
            }
        }
        END:
        return $outArr;
    }

    //ezafe kardan be teadad vsit haye pazirande
    protected function PlusToVisit($ID)
    {
        return (is_numeric($ID) ? ($this->DLA->DoCommand("UPDATE `app_acceptor_list` SET `sVisit`=`sVisit`+1 WHERE `ID`='{$ID}'") ? '1' : '0') : '0');
    }


    //ezafe kardan be teadad like haye pazirande
    protected function PlusToLike($ID)
    {
        return (is_numeric($ID) ? ($this->DLA->DoCommand("UPDATE `app_acceptor_list` SET `sLike`=`sLike`+1 WHERE `ID`='{$ID}'") ? '1' : '0') : '0');
    }

    //akharin client haye narma fzar 9 taye akhar
    protected function OurLastClient()
    {
        $query = "SELECT `app_acceptor_list`.`ID`,sPhoto,sName,(SELECT `gName` FROM `app_guild_list`WHERE ID=`app_acceptor_list`.`sGuild` ) as `cat-name` FROM `app_acceptor_list` WHERE `IsActive`=true ORDER BY `db-time` DESC LIMIT 6";
        $select = $this->DLA->Select($query);
        $outArr = array();
        if ($select) {
            foreach ($select as $item) {
                $outArr[] = array(
                    'ID' => $item['ID'],
                    'icon' => $this->ConvertStringToImageArray($item['sPhoto'], true),
                    'shop-name' => $item['sName'],
                    'cat-name'=>$item['cat-name']
                );
            }
        }
        return $outArr;
    }

    //se ta menoye web base avale barname
    protected function WebPanel($key)
    {
        //html page
        $outArr = array();

        return $outArr;
    }

    //liste khat haye otobos rani vala .....
    protected function BusLoad($param)
    {//bus_load
        require_once("WebServiceSystem.php");
        $this->WebServices = new WebServiceSystem();

        $function = $param['function'];
        unset($param['request']);
        unset($param['function']);
        unset($param['request-app']);
        unset($param['developer']);
        $parameter = array();
        foreach ($param as $key => $value)
            if (strlen($value) > 0)
                $parameter[$key] = $value;
        $response = $this->WebServices->BusApi()->json($function, $parameter);//, $parameter
        $response = json_decode($response)[0];
        return ($response->response != null ? $response->response : array());
    }

    //namayesh panel pazirandegan (asnaf)
    protected function AcceptorPage($use, $pass)
    {
        //html page
        $outArr = array();

        return $outArr;
    }

    //sabte name pazirandegan (asnaf)
    public function AcceptorRegister($data)
    {
        $outArr = array(
            'error' => 0,
            'msg' => ''
        );
        try {

            foreach ($data as $key => $item) {
                $data[$key] = convert($item, true);
            }

            $object = $data;
            /*        $location = $object['sLocation'];
                $location = str_replace('(', '', $location);
                $location = str_replace(')', '', $location);
                $location = explode(',', $location);
                $lat = $location[0];
                $lng = $location[1];
                */

            if (!$this->DLA->Select("SELECT * FROM `app_request_list` WHERE `arlPhoneNumber`='{$object['cell-number']}'")) {
                $query = "INSERT INTO `app_request_list` ";
//                $query .= '(`fName`, `lName`, `pNumber`, `sName`, `sGuild`, `sNumber`, `sPhoto`, `sAP`, `sLocation`, `sAddress`, `sStart`, `sEnd`, `sDiscount`, `sTelegram`, `sSite`, `sInstagram`, `sFacebook`, `Lat`, `Lng`, `IsActive`, `IsApp`)';
                $query .= '(`arlFName`, `arlLName`, `arlPhoneNumber`, `arlFixNumber`, `arlGuildName`, `arlShopName`, `arlAddress`, `arlMoreDetailes`, `arlRead`, `device-id`)';
                $query .= ' VALUES ';
                $query .= "('{$object['fName']}', '{$object['lName']}', '{$object['cell-number']}', '{$object['fix-number']}', '{$object['category']}', '{$object['shop-name']}', '{$object['address']}', '{$object['more-details']}','0','{$object['DEVICE-KEY']}')";
                if ($this->DLA->DoCommand($query)) {
                    $outArr['error'] = 0;
                    $outArr['msg'] = "درخواست شما ثبت شد. \n پس از برسی نتیجه به شما اعلام میگردد.";
                } else {
                    $outArr['error'] = 3;
                    $outArr['msg'] = "خطایی رخ داده است. \n لطفا با پشتیبانی تماس حاصل نمایید.";
                }
            } else {
                $outArr['error'] = 2;
                $outArr['msg'] = "خطایی رخ داده است. \n لطفا با پشتیبانی تماس حاصل نمایید.";
            }
        } catch (Exception $e) {
            $outArr['error'] = 1;
            $outArr['msg'] = "خطایی رخ داده است. \n لطفا با پشتیبانی تماس حاصل نمایید.";
        }
        return $outArr;
    }

    //sabte name karbaran
    public function ClientRegister($data)
    {
        //'fName', 'lName', 'nCode', 'bnCode', 'bank', 'mobile'
        $outArr = array(
            'error' => 0,
            'msg' => ''
        );
        foreach ($data as $key => $item) {
            $data[$key] = convert($item, true);
        }
        try {
            if (!$this->DLA->Select("SELECT * FROM `app_client_register` WHERE `NationalCode`='{$data['nCode']}'")) {
                $query = "INSERT INTO `app_client_register` (FirstName, LastName, NationalCode, NationalSecurityCode, BankCardNumber, Mobile, Mode) VALUES ";
                $query .= "('{$data['fName']}', '{$data['lName']}', '{$data['nCode']}', '{$data['bnCode']}', '{$data['bank']}', '{$data['mobile']}','0')";
                if ($this->DLA->DoCommand($query)) {
                    $outArr['error'] = 0;
                    $outArr['msg'] = "درخواست شما ثبت شد. \n پس از برسی نتیجه به شما اعلام میگردد.";
                } else {
                    $outArr['error'] = 3;
                    $outArr['msg'] = "خطایی رخ داده است. \n لطفا با پشتیبانی تماس حاصل نمایید.";
                }
            } else {
                $outArr['error'] = 2;
                $outArr['msg'] = "خطایی رخ داده است. \n لطفا با پشتیبانی تماس حاصل نمایید.";
            }
        } catch (Exception $e) {
            $outArr['error'] = 1;
            $outArr['msg'] = "خطایی رخ داده است. \n لطفا با پشتیبانی تماس حاصل نمایید.";
        }

        return $outArr;
    }


    //vorod be pael karbari android
    public function ClientLogin($data)
    {
        // 'nCode' ,'mobile'
        $outArr = array(
            'error' => 0,
            'id' => -1,
            'mode' => -1,
            'msg' => ''
        );
        foreach ($data as $key => $item) {
            $data[$key] = convert($item, true);
        }
        try {
            $select = $this->DLA->Select("SELECT `ID`, `Mode` FROM `app_client_register` WHERE (`NationalCode`='{$data['nCode']}') AND (`Mobile`='{$data['mobile']}')");
            if ($select) {
                if (count($select) === 1) {
                    $select = $select[0];
                    $outArr['error'] = 0;
                    $outArr['mode'] = $select['Mode'];
                    switch ($select['Mode']) {
                        case '0':
                            $outArr['error'] = 5;
                            $outArr['msg'] = "حساب شما در دست برسی است.";
                            break;
                        case '1':
                            $outArr['msg'] = "خوش آمدید";
                            $outArr['id'] = $select['ID'];
                            break;
                        case '2':
                            $outArr['msg'] = "خوش آمدید";
                            $outArr['id'] = $select['ID'];
                            break;
                        default:
                            $outArr['error'] = 4;
                            break;
                    }
                } else {
                    $outArr['error'] = 3;
                    $outArr['msg'] = "لطفا با پشتیبانی تماس حاصل نمایید.";
                }
            } else {
                $outArr['error'] = 2;
                $outArr['msg'] = "نام کاربری و رمز عبور یافت نشد.";
            }
        } catch (Exception $e) {
            $outArr['error'] = 1;
            $outArr['msg'] = "خطایی رخ داده است. \n لطفا با پشتیبانی تماس حاصل نمایید.";
        }
        return $outArr;
    }

    //vorod be pael asnaf android
    public function AcceptorLogin($data)
    {
        // 'nCode' ,'mobile'
        $outArr = array(
            'error' => 0,
            'id' => -1,
            'mode' => -1,
            'msg' => ''
        );
        foreach ($data as $key => $item) {
            $data[$key] = convert($item, true);
        }
        try {
            $select = $this->DLA->Select("SELECT `ID` , `IsActive` FROM `app_acceptor_list` WHERE (`NationalCode`='{$data['nCode']}') AND (`Mobile`='{$data['mobile']}')");
            if ($select) {
                if (count($select) === 1) {
                    $select = $select[0];
                    $outArr['error'] = 0;
                    $outArr['mode'] = $select['IsActive'];
                    switch ($select['Mode']) {
                        case '0':
                            $outArr['error'] = 5;
                            $outArr['msg'] = "حساب شما در دست برسی است.";
                            break;
                        case '1':
                            $outArr['msg'] = "خوش آمدید";
                            $outArr['id'] = $select['ID'];
                            break;
                        default:
                            $outArr['error'] = 4;
                            break;
                    }
                } else {
                    $outArr['error'] = 3;
                    $outArr['msg'] = "لطفا با پشتیبانی تماس حاصل نمایید.";
                }
            } else {
                $outArr['error'] = 2;
                $outArr['msg'] = "نام کاربری و رمز عبور یافت نشد.";
            }
        } catch (Exception $e) {
            $outArr['error'] = 1;
            $outArr['msg'] = "خطایی رخ داده است. \n لطفا با پشتیبانی تماس حاصل نمایید.";
        }
        return $outArr;
    }

    /// load category ha
    protected function LoadCategory($request)
    {
        $origin = array(
            'county' => -1,
            'province' => -1
        );
        if (array_key_exists("county", $request) AND array_key_exists("province", $request)) {
            $origin['county'] = $request['county'];
            $origin['province'] = $request['province'];
        }

        if ($origin['province'] != -1 AND $origin['county'] != -1)
            $origin_condition = "AND `ID` IN (SELECT sGuild FROM `app_acceptor_list` WHERE county='{$origin['county']}' AND province='{$origin['province']}' AND IsActive=true GROUP BY sGuild)";
        else $origin_condition = '';

        query:
        $query = "SELECT `ID`, `gName`, `gTabIndex`, `gIcon` FROM `app_guild_list` WHERE `gActive`=1 $origin_condition order by `gTabIndex` desc";
        $array = array();
        $select = $this->DLA->Select($query);
        if ($select) {
            foreach ($select as $row) {
                if ($row['gIcon'] == '' OR strlen($row['gIcon']) == 0 OR $row['gIcon'] == null) $row['gIcon'] = defaultImageUrl;
                $array[] = array(
                    'ID' => $row['ID'],
                    'gName' => $row['gName'],
                    'gTabIndex' => $row['gTabIndex'],
                    'gIcon' => $row['gIcon']
                );
            }
            return $array;
        }
//        $origin_condition = "";
//        goto query;
        return $array;
    }

    //load maghaze haye takhfifi bar asas Tag(ID categorye) ha
    protected function LoadAcceptorsByTag($categoryID, $from, $limit, $object)
    {

        $origin = array(
            'county' => -1,
            'province' => -1
        );
        if (array_key_exists("county", $object) AND array_key_exists("province", $object)) {
            $origin['county'] = $object['county'];
            $origin['province'] = $object['province'];
        }

        if ($origin['province'] != -1 AND $origin['county'] != -1)
            $origin_condition = "`province`='{$origin['province']}' AND county='{$origin['county']}' AND ";
        else $origin_condition = '';
        $outArr = array();
        $select = $this->DLA->Select("SELECT * FROM `app_acceptor_list` WHERE " . $origin_condition . " `sGuild`='{$categoryID}' AND `IsActive`=true ORDER BY `sDiscount` DESC LIMIT $limit OFFSET $from");
        if ($select) {
            for ($i = 0; $i < count($select); $i += 1) {
                $item = $select[$i];
                $outArr[] = array(
                    'ID' => $item['ID'],
                    'url' => $this->ConvertStringToImageArray($item['sPhoto'], true),
                    'iName' => $item['sName'],
                    'address' => $item['sAddress'],
                    'dis-text' => $item['sDiscount'] . '%',
                    'dis' => $item['sDiscount'],
                    'location' => $item['sLocation'],
                    'lat' => $item['Lat'],
                    'lng' => $item['Lng'],
                    'zoom' => $this->def_zoom,
                );
            }
        }
        return $outArr;
    }

    //load darbareye ma
    protected function AboutUs()
    {
        //html page
        $outArr = array();

        return $outArr;
    }

    //load kardan list notification ha
    protected function LoadNotificationList()
    {
        //        param.put("request", "app");
        //        param.put("request-app", "notification");
        //        param.put("type", "public-show");
        $select = $this->DLA->Select("SELECT `ID`,`nTitle` FROM `app_notification` WHERE (`IsActive`='1' AND `nMode`='0')");
        $outArr = array();
        if ($select) {
            foreach ($select as $item) {
                $outArr[] = array(
                    'nID' => $item['ID'],
                    'nTitle' => $item['nTitle'],
                );

            }
        }
        return $outArr;
    }

    //load kardan 1 notification
    protected function LoadNotification($key)
    {
        $outArr = '';
        $select = $this->DLA->Select("SELECT `nContent` FROM `app_notification` WHERE (`IsActive`='1' AND `nMode`='0' AND `ID`='{$key}')");
        if ($select) {
            if (count($select) == 1) {
                $outArr = $select[0]['nContent'];
            }
        }
        return $outArr;
    }

    //baraye load 1 pazirande ba ID
    protected function LoadSingleAcceptor($ID)
    {
        $outArr = array();
        $shop = $this->DLA->Select("SELECT * FROM `app_acceptor_list` WHERE `ID`='{$ID}' AND `IsActive`=true");
        if ($shop AND count($shop) === 1) {
            $shop = $shop[0];


            $number = strpos($shop['sNumber'], " ");
            if ($number != 0 AND $number != (strlen($shop['sNumber']) - 1)) {
                $number = str_replace(" ", "<br>", $shop['sNumber']);
            } else {
                $number = $shop['sNumber'];
            }
            $slide = array();
            $slideShow = $this->DLA->Select("SELECT `imgSrc` FROM `app_acceptor_image_slider` WHERE (`imgFor`='{$shop['ID']}') AND (`isLocked`=false) ORDER BY `imgIndex` DESC LIMIT " . $shop['image_limit']);

            if ($slideShow) {
                foreach ($slideShow as $item)
                    $slide[] = array('url' => $item['imgSrc'], 'post' => '');
            } else {
                $slide[] = array('url' => $this->ConvertStringToImageArray($shop['sPhoto'], true), 'post' => '');
            }

            $outArr = array(
                'id' => $shop['ID'],
                'like' => $shop['sLike'],
                'visit' => $shop['sVisit'],
                'location' => $shop['sLocation'],
                'discount' => $shop['sDiscount'] . '%',
                'shop-name' => $shop['sName'],
                'about-place' => $shop['sAP'],
                'time' => " از تاریخ " . $shop['sStart'] . " \t تا تاریخ \t " . $shop['sEnd'] . " ",
                'address' => $shop['sAddress'],
                'phone-number' => $number,
                'lat' => $shop['Lat'],
                'lng' => $shop['Lng'],
                'url' => $this->ConvertStringToImageArray($shop['sPhoto'], true),
                'slide' => $slide,
                'zoom' => $this->def_zoom,
                'instagram' => $shop['sInstagram'],
                'telegram' => $shop['sTelegram'],
                'internet' => $shop['sSite'],
                'facebook' => $shop['sFacebook']
            );
        }
        return $outArr;
    }
    /*
     * public function
     **/
    /**
     * convert string array image to one arrat
     */
    protected function ConvertStringToImageArray($string, $first_item = false, $KeyToArray = '[#]')
    {
        $return = [];
        $oneItem = "";
        $flag = true;
        if (strlen($string) > 0) {
            if (substr_count($string, $KeyToArray) > 0) {
                if (strpos($string, $KeyToArray) == 0 AND strrpos($string, $KeyToArray) == 0) {
                    $return[] = array('url' => str_replace($KeyToArray, '', $string));
                    if ($flag) {
                        $flag = false;
                        $oneItem = str_replace($KeyToArray, '', $string);
                    }
                } else {
                    $array = explode($KeyToArray, $string);
                    if (count($array) > 0) {
                        for ($i = 0; $i < count($array); $i += 1) {
                            if (strlen($array[$i]) > 0) {
                                if ($flag) {
                                    $flag = false;
                                    $oneItem = str_replace($KeyToArray, '', $array[$i]);
                                }
                                $return[] = array('url' => str_replace($KeyToArray, '', $array[$i]));
                            }
                        }
                    }
                }
            } else {
                $return[] = array('url' => str_replace($KeyToArray, '', $string));
                if ($flag) {
                    $flag = false;
                    $oneItem = str_replace($KeyToArray, '', $string);
                }
            }
        }
        if ($first_item AND strlen($oneItem) == 0) {
            $oneItem = defaultImageUrl;
        }
        return ($first_item ? $oneItem : $return);
    }

    protected function is_image($path)
    {
        $a = getimagesize($path);
        $image_type = $a[2];

        if (in_array($image_type, array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_BMP))) {
            return true;
        }
        return false;
    }

    protected function DistanceBetween($lat1, $lon1, $lat2, $lon2, $unit /*= ["M", "K", "N"]*/)
    {
//        echo distance(32.9697, -96.80322, 29.46786, -98.53506, "M") . " Miles<br>";
//        echo distance(32.9697, -96.80322, 29.46786, -98.53506, "K") . " Kilometers<br>";
//        echo distance(32.9697, -96.80322, 29.46786, -98.53506, "N") . " Nautical Miles<br>";

        if (($lat1 == $lat2) && ($lon1 == $lon2)) {
            return 0;
        } else {
            $theta = $lon1 - $lon2;
            $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
            $dist = acos($dist);
            $dist = rad2deg($dist);
            $miles = $dist * 60 * 1.1515;
            $unit = strtoupper($unit);
            if ($unit == "K") {
                return ($miles * 1.609344);
            } else if ($unit == "N") {
                return ($miles * 0.8684);
            } else {
                return $miles;
            }
        }
    }


    /*activate sms function*/
    protected function SendActivateSms($object)
    {

        $for = $object['for'];
        $fName = $object['fName'];
        $lName = $object['lName'];
        $province = $object['province-id'];
        $county = $object['county-id'];
        $nc = $object['nc'];

        $code = mt_rand(111111, 999999);
        $for = convert($for, true);
        $nc = convert($nc, true);

        $num1 = '';
        $num2 = '';
        $id = 0;

        if (count($fName) > 0 AND count($lName) > 0 AND strlen((string)$nc) == 10 AND (int)$province != -1 AND (int)$county != -1) {
            if (strlen($for) === 11) $num2 = substr(($num1 = $for), 1);
            else $num1 = '0' . ($num2 = $for);
            $CLIENT = $this->DLA->cSelect("SELECT `ID` FROM `app_acceptor_profile` WHERE pNumber IN (?, ?)", array('s' => $num1), array('s' => $num2));
            if ($CLIENT) {
                if (count($CLIENT) == 1) {
                    $CLIENT = $CLIENT[0];
                    $id = $CLIENT['ID'];
//                    $this->DLA->DoCommand("UPDATE `app_acceptor_profile` SET `fName`='{$fName}', `lName`='{$lName}', `pNC`='{$nc}', `province_id`=$province, `county_id`=$county WHERE `ID`=$id");
                } else {
                    //more then one user
                    $id = -1;
                }
            } else {
                //user not found insert
                $id = $this->DLA->DoCommandID(
                    "INSERT INTO `app_acceptor_profile` (fName, lName, pNumber, pNC, province_id, county_id) VALUE('{$fName}','{$lName}','{$for}','{$nc}','{$province}','{$county}')");
            }
        } else {
            //error
            $id = -1;
        }


        $text = "کد تایید ورود شما :";
        $text .= "\n";
        $text .= $code;
        $text .= "\n";
        $text .= "می باشد.";
        $text .= "\n";
        $text .= "\n";
        $text .= "*باشگاه شهروندی نفیس*";


        $outArr = array(
            "error" => !((boolean)((int)$id > 0)),
            "code" => $code,
            "id" => "{$id}",
            "number" => $for,
            "from" => (boolean)((int)$id > 0) ? $this->SMS->SendOneMessage($for, $text) : -1
        );

        if ($outArr['error']) return null;
        else return $outArr;
    }
    /*activate sms function*/

    /*managment system*/

    protected function AppIsAlive()
    {
        $state = false;
        $select = $this->DLA->Select("SELECT `ControllerValue` FROM `app_panel_state` WHERE  `ControllerKey`='app'");
        if ($select) {
            if ($select[0]['ControllerValue'] === '1') {
                $state = true;
            }
        }
        return ($state ? "1" : "0");
    }

    protected function AppCheckPanel($ControllerKey)
    {
        $state = false;
        $select = $this->DLA->Select("SELECT IF(`ControllerValue`=1,1,0) as `state` FROM `app_panel_state` WHERE `ControllerKey`='{$ControllerKey}'");
        if ($select) if ($select[0]['state'] === '1') $state = true;
        return ($state ? "1" : "0");
    }
    /*managment system*/


    /*End service push notification*/
    protected function ListBroadcastNotification()
    {
        $outArr = array();
        $select = $this->DLA->Select("SELECT * FROM `app_broadcast_push_notification` WHERE `bn_active`=true");
        if ($select) {
            foreach ($select as $item) {
                $outArr[] = array(
                    "error" => 0,
                    "ID" => $item['ID'],
                    "msg_id" => $item['bn_msg_id']
                );
            }
        }
        return $outArr;
    }

    protected function SendBroadcastNotification($msg_id)
    {
        $outArr = '';
        if (strlen($msg_id) > 0) {
            $select = $this->DLA->Select("SELECT * FROM `app_broadcast_push_notification` WHERE (`bn_active`=true) AND (`bn_msg_id`='{$msg_id}')");
            if ($select AND count($select) === 1) {
                $select = $select[0];
                $param_array = array();
                if (isset($select['bn_parameter']) AND strlen($select['bn_parameter']) > 3) {
                    $tArray = explode("|", $select['bn_parameter']);
                    for ($i = 0; $i < count($tArray); $i += 1) {
                        $tsArray = explode("=", $tArray[$i]);
                        $param_array[] = array(
                            "key" => $tsArray[0],
                            "value" => $tsArray[1]
                        );
                    }
                }
                $this->DLA->DoCommand("UPDATE `app_broadcast_push_notification` SET `bn_visit`= `bn_visit`+1 WHERE `ID`='{$select['ID']}'");
                $outArr = array
                (
                    'ID' => $select['ID'],
                    'msg_id' => $select['bn_msg_id'],
                    'message' => $select['bn_message'],
                    'title' => $select['bn_title'],
                    'subtitle' => $select['bn_subtitle'],
                    'tickerText' => $select['bn_ticker'],
                    'vibrate' => $select['bn_vibrate'],
                    'sound' => $select['bn_sound'],
                    'largeIcon' => $select['bn_largeicon'],
                    'smallIcon' => $select['bn_smallicon'],
                    'vibrateArray' => $select['bn_vibrate_array'],
                    'requestCode' => $select['bn_request_code'],
                    'requestFlag' => $select['bn_request_flag'],
                    'number' => $select['bn_number'],
                    'going' => $select['bn_going'],
                    'autoCancel' => $select['bn_auto_cancel'],
                    'package' => $select['bn_package'],
                    'parameter' => $param_array,
                );
            }
        }
        return $outArr;
    }
    /*End service push notification*/


    /*android v2 function */
    protected function AppSecondSlideShow($ID, $limit)
    {
        $defaultImage = 'ResourcesHolder/resource/images/card.png';
        $defaultImageUrl = 'https://android.kashancard.digihelp.net/' . $defaultImage;

        $outArr = array();
        $select = $this->DLA->Select("SELECT `content` FROM `app_main_panel_item` WHERE `ID`=$ID AND `isActive`=true");
        if ($select AND count($select) === 1) {
            $content = json_decode($select[0]['content'], true);
            if (count($content) > 0) {
                foreach ($content as $item) {//for ($i = 0; $i < count($content); $i += 1) {
                    $limit -= 1;
                    $query = "SELECT * FROM `app_acceptor_list` WHERE `ID`=" . $item['id'] . " AND `IsActive`=true";
                    $shop = $this->DLA->Select($query);
                    if ($shop) {
                        $shop = $shop[0];
                        $outArr[] = array(
                            'id' => $shop['ID'],
                            'url' => $this->ConvertStringToImageArray($shop['sPhoto'], true),
                            'post' => ''
                        );
                    }
                    if ($limit == 0) goto END;
                }
            }
        }
        END:
        if (count($outArr) == 0) {
            $outArr[] = array(
                'id' => -1,
                'url' => $defaultImageUrl,
                'post' => ''
            );
        }
        return $outArr;
    }

    protected function AppAddNewCard($param)
    {
        $data = array(
            'object' => array(
                'Mode' => 1,
                'GroupCode' => 3131,
                'CategoryCode' => 220744,
                'RegFrom' => -13,
                'bnCode' => '',//bus card number
                'CardPan' => $param['card'],
                'FirstName' => $param['fName'],
                'LastName' => $param['lName'],
                'FatherName' => 'نام پدر',
                'NationalCode' => $param['nc'],
                'Mobile' => $param['mobile'],
                'CardExpireDate' => '1400/01/01'
            ),
        );
        return json_decode($this->post($this->siteURL() . 'ResourcesHolder/core/index.php?request=proxy&action=WebServicesController&data-header=NoCodeCustomerServiceNafis-json', $data), true);
    }


    protected function post($url, $data = array())
    {
        $payload = json_encode($data, JSON_UNESCAPED_UNICODE);
        $request = $url . "&json=" . rtrim(strtr(base64_encode($payload), '+/', '-_'), '=');


        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $request);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $result = curl_exec($ch);
        if (curl_errno($ch)) {
            return curl_error($ch);
        }
        curl_close($ch);
        return $result;


    }


    protected function siteURL()
    {
        $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
        $domainName = $_SERVER['HTTP_HOST'] . '/';
        return $protocol . $domainName;
    }

    protected function AppEditProfile($request)
    {
        $outArr = array('error' => true, 'value' => array());
        $mode = $request['request-mode'];

        if (isset($mode) && $mode != null && strlen($mode) > 0) {
            switch ($mode) {
                case 'load-profile':
                    if ($request['user'] != null && strlen($request['user']) > 0 && is_numeric($request['user'])) {
                        $select = $this->DLA->cSelect("SELECT `fName`, `lName`, `pNumber`, `pNC` FROM `app_acceptor_profile` WHERE `ID`=?", array('s' => $request['user']));
                        $outArr['error'] = !($select && count($select) == 1);
                        $outArr['value'] = (($select && count($select) == 1) ? $select[0] : array());
                    }
                    break;
                case 'update-profile':
                    $outArr['origin-change'] = array('status', false, 'province' => -1, 'county' => -1, 'city' => -1);
                    if ($request['user'] != null && strlen($request['user']) > 0 && is_numeric($request['user'])) {
                        $select = $this->DLA->cSelect("SELECT `fName`, `lName`, `pNumber`, `pNC` FROM `app_acceptor_profile` WHERE `ID`=?", array('s' => $request['user']));
                        if ($select && count($select) == 1) {
                            if (!is_null($request['fn']) && !is_null($request['ln']) && strlen($request['fn']) > 0 && strlen($request['ln']) > 0) {
                                $state = $this->DLA->DoCommand("UPDATE `app_acceptor_profile` SET `fName`='{$request['fn']}', `lName`='{$request['ln']}' WHERE `ID`='{$request['user']}'");
                                $outArr['value'] = $state;
                                $outArr['error'] = !$state;
                            }

                            if (!is_null($request['province']) && !is_null($request['county'])) {
                                if (is_numeric($request['province']) and is_numeric($request['county'])) {
                                    if ((int)$request['province'] != -1 and (int)$request['county'] != -1) {
                                        $outArr['origin-change']['status'] = $this->DLA->cDoCommand("UPDATE `app_acceptor_profile` SET `province_id`=?, `county_id`=? WHERE `ID`=?",
                                            array('i' => (int)$request['province']),
                                            array('i' => (int)$request['county']),
                                            array('i' => (int)$request['user'])
                                        );

                                        if ($outArr['origin-change']['status']) {
                                            $outArr['origin-change']['province'] = (string)$request['province'];
                                            $outArr['origin-change']['county'] = (string)$request['county'];
//                                            $outArr['origin-change']['city']
                                        }
                                    }
                                }
                            }


                        }
                    }
                    break;
                case 'update-profile-origin':
                    $outArr['origin-change'] = array('status', false, 'province' => -1, 'county' => -1, 'city' => -1);
                    if ($request['user'] != null && strlen($request['user']) > 0 && is_numeric($request['user'])) {
                        if (!is_null($request['province']) && !is_null($request['county'])) {
                            if (is_numeric($request['province']) and is_numeric($request['county'])) {
                                if ((int)$request['province'] != -1 and (int)$request['county'] != -1) {
                                    $outArr['error'] = !($outArr['value'] = $outArr['origin-change']['status'] = $this->DLA->cDoCommand("UPDATE `app_acceptor_profile` SET `province_id`=?, `county_id`=? WHERE `ID`=?",
                                        array('i' => (int)$request['province']),
                                        array('i' => (int)$request['county']),
                                        array('i' => (int)$request['user'])
                                    ));

                                    if ($outArr['origin-change']['status']) {
                                        $outArr['origin-change']['province'] = (string)$request['province'];
                                        $outArr['origin-change']['county'] = (string)$request['county'];
//                                            $outArr['origin-change']['city']
                                    }


                                }
                            }
                        }
                    }
                    break;
                default:
                    break;
            }
        }

        return $outArr;
    }


    /*inject direct query to database for report */
    protected function AppReportClientCard($request)
    {
        require_once("WebServiceSystem.php");
        $this->WebServices = new WebServiceSystem();
        $function = $request['request-mode'];
        $response = null;
        switch ($function) {
            case "nafis-card":
                $param = explode(":", $request['param']);
                $response = null;
                if (count($param) == 3) {
                    if (strlen($param[0]) === 10 AND strlen($param[1]) === 10 AND strlen($param[2]) === 16) {
                        $card = hash('sha256', $param[2]);
                        $report = $this->NafisReporstJson($param[0], $param[1]);
                        if (is_array($report) AND count($report) == 1) {
                            $report = $report[0];
                            if (array_key_exists("error", $report) AND array_key_exists("response", $report)) {
                                if ($report['error'] === "no error" AND is_array($report['response'])) {
                                    $report = $report['response'];
                                    if (count($report) > 0) {
                                        $out = array();
                                        foreach ($report as $r) {
                                            if (array_key_exists('error', $r) AND array_key_exists('result', $r)) {
                                                if ($r['error']['code'] === '0000' AND is_array($r['result']) AND count($r['result']) > 0) {
                                                    $out = array_merge($out, $r['result']);
                                                }
                                            }
                                        }

                                        if (count($out) > 0) {
                                            foreach ($out as $o) {
                                                if ($card == $o['HashPan']) {
                                                    $response[] = array(
                                                        'date' => $o['TransDate'],
                                                        'time' => $o['TransTime'],
                                                        'type' => $o['ServiceName'],
                                                        'code' => $o['MerchantCode'],
                                                        'desc' => $o['ClarifiedStatusDesc'],
                                                        'amount' => $o['TotalAmount']
                                                    );
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                break;
            case 'bus-card':
                $param = explode(":", $request['param']);
                $response = null;

                function QUERY($card, $from, $to)
                {
                    return "
                    SELECT 
                        DISTINCT [Transaction].[ID],
                        [Transaction].[TrxDateID],
                        [Transaction].[TrxTime],
                        [Transaction].[Amount],
                        [Transaction].[BalanceBefore],
                        [Transaction].[BalanceAfter],
                        [Transaction].[TypeNamePersian]
                    FROM 
                        [FCMSDB].[View].[Transaction] [Transaction] Left JOIN 
                        [FCMSDB].[Crd].[Cards] Cards On [Transaction].[PAN]= Cards.[PAN] JOIN
                        [FCMSDB].[Crd].[PhysicalCard] PhysicalCard  ON  
                        PhysicalCard.[CardID] = Cards.[ID]
                    WHERE PhysicalCard.[SerialNumber]='{$card}' AND [Transaction].[TrxDateID] BETWEEN " . $from . " AND " . $to . " ORDER BY [Transaction].[TrxDateID] DESC";
                }

                if (count($param) == 3) {
                    $query = QUERY($param[2], $param[0], $param[1]);
                    $record = $this->DoQueryOffline($query);
                    if ($record != null AND is_array($record) AND count($record) > 0) {
                        foreach ($record as $row) {
                            try {
                                $response[] = array(
                                    'date' => $row->TrxDateID,
                                    'time' => $row->TrxTime,
                                    'Amount' => $row->Amount,
                                    'BalanceBefore' => $row->BalanceBefore,
                                    'BalanceAfter' => $row->BalanceAfter,
                                    'TypeNamePersian' => $row->TypeNamePersian
                                );
                            } catch (Exception $e) {
                                continue;
                            }
                        }
                    }
                }
                break;
            default:
                break;
        }
        return ($response == null ? array() : $response);
    }

    protected function NafisReporstJson($from, $to)
    {
        $data = array(
            'object' => array(
                'FromDate' => $from,
                'ToDate' => $to
            )
        );
        return json_decode($this->post($this->siteURL() . 'ResourcesHolder/core/index.php?request=proxy&action=WebServicesController&data-header=TransReportNafis-json', $data), true);
    }

    protected function DoQueryOffline($Query)
    {
        $response = $this->WebServices->BusApi()->json("InjectQuery", array('query' => $Query));//, $parameter
        $response = json_decode($response, true)[0];
        try {
            if ($response['error'] === "no error") {
                $response = $response['response'];
                if (is_array($response) && !is_object($response) && count($response) > 0 && is_null($response[0])) {
                    if (array_key_exists('error', $response) && array_key_exists('message', $response) && array_key_exists('value', $response)) {
                        if (!$response['error'] && is_array($response) && count($response) > 0) {
                            $response = json_decode($response['value'], false);
                        } else {
                            $response = null;
                        }
                    } else {
                        $response = null;
                    }
                } else {
                    $response = null;
                }
            } else {
                $response = null;
            }
        } catch (Exception $e) {
            $response = null;
        }
        return $response;
    }


    /**
     * @param $request
     */
    protected function AppLoadCity($request)
    {

        $out_array = array();
        $provinces = $this->DLA->cSelect("SELECT * FROM `province_db`");
        if ($provinces) {
            $out_array[] = array(
                'id' => -1,
                'name' => 'استان',
                'county' => array(array('id' => -1, 'name' => 'شهر')));
            foreach ($provinces as $province) {
                $county = $this->DLA->cSelect("SELECT id, name FROM `county_db` WHERE `province_id`=?", array('i' => $province['id']));
                $out_array[] = array(
                    'id' => $province['id'],
                    'name' => $province['name'],
                    'county' => ($county ? $county : array())
                );
            }
        }

        return $out_array;
    }

    /*warning so important*/
    protected function AppCheckForUpdate($request)
    {
        $outArray = array(
            'canRun' => false,
            'message' => '',
            'need-update' => false,
            'link' => array()
        );

        if (array_key_exists('vN', $request) AND array_key_exists('vC', $request) AND array_key_exists('package', $request)) {
            $version_name = $request['vN'];
            $version_code = $request['vC'];
            $package = $request['package'];


            $config = $this->DLA->Select("SELECT * FROM `app_update_status_panel` WHERE `app_active`=TRUE AND `app_package`='{$package}'");
            if ($config AND count($config) == 1 AND is_numeric($version_name) AND is_numeric($version_code)) {
                $config = $config[0];
                if ((float)($config['app_version_code'] > ((float)$request['vC']))) {
                    $outArray['message'] = strlen($config['app_message']) > 0 ? $config['app_message'] : '';

                    if (strlen($config['app_access_link']) > 0) {
                        $data = json_decode($config['app_access_link'], true);
                        if (count($data) > 0) {
                            foreach ($data as $item) {
                                $outArray['link'][] = array(
                                    'address' => $item['link'],
                                    'icon' => $item['icon'],
                                    'text' => $item['site']
                                );
                            }
                        } else {
                            goto ELSEY;
                        }
                    } else {
                        ELSEY:
                        $outArray['link'][] = array(
                            'address' => 'http://gokashan.ir/',
                            'text' => 'کاشان کارت'
                        );
                    }

                    $outArray['need-update'] = true;
                    $outArray['canRun'] = (((float)$config['app_force_update_under']) <= ((float)$request['vC']));
                } else {
                    $outArray['canRun'] = true;
                }
            } else {
                $outArray['canRun'] = true;
            }
        }
        return $outArray;
    }

    /*warning so important*/


    protected function AppBonServiceNafis($request)
    {
        $outArr = array();

        $pan = $request['pan'];

        if (strlen($pan) === 16 AND is_numeric($pan)) {
            $array = array('Pan' => $pan);
            $array = array_merge($array, $this->LoginDataWebServices);
            $data = $this->WebServices->BusApi()->json('CustBonServiceNafis', $array);
            if ($data != null && !is_null($data)) {
                $data = json_decode($data, true);
                if ($data != null && !is_null($data)) {
                    if (count($data) == 1) {
                        $data = $data[0];
                        if (array_key_exists('response', $data)) {
                            $data = $data['response'];
                            if (array_key_exists('error', $data) AND array_key_exists('result', $data)) {
                                if ($data['error']['ResponseCode'] === '0000') {
                                    $data = $data['result'];
                                    if (count($data) > 0) {
                                        for ($i = 0; $i < count($data); $i += 1) {
                                            $obj = $data[$i];
                                            $outArr[] = array(
                                                'title' => $obj['BonTitle'],
                                                'cat' => $obj['CustCategoryName'],
                                                'total' => $obj['CrAmnt'],
                                                'left' => $obj['RemAmnt']
                                            );
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        return $outArr;
    }

    protected function AppAbiServices($request, $server)
    {
        $outArr = array('status' => false);
        if (is_object($server) AND array_key_exists('abi-name', $request) AND array_key_exists('device-name', $request)) {
            $outServer = json_encode($server, JSON_UNESCAPED_UNICODE);
            $abi = $request['abi-name'];
            $device = $request['device-name'];
            $outArr['status'] = $this->DLA->DoCommand("Insert INTO `app_abi_tech` (device_name, device_abi, server) VALUES ('{$device}','{$abi}','{$outServer}')");
        }
        return $outArr;
    }


    //external-function-caller
    protected function ExternalCaller($request)
    {
        $out = [];
        switch ($request['for']) {
            //top tehran function ShopMenu
//            case 'api':
//                $this->DLA->cSelect($request[;'['])
//            default:
//                break;
        }

        return $out;
    }

    protected function AppUserClientCard($request)
    {
        return $this->DLA->cSelect("SELECT `card_number` FROM `app_client_credit_card` WHERE `client_id`=? GROUP BY `card_number` order by `card_number` desc ", array('s' => $request['uid']));
    }

    /*android v2 function */

    /*custom services*/
    protected function LodRecyclingMaterialOption($object)
    {
        $type = $this->DLA->cSelect("SELECT `ID` as `id`, `name` FROM `app_recycling_system` WHERE `key`='recycling-type' ORDER BY `code`");
        $weight = $this->DLA->cSelect("SELECT `ID` as `id`, `name` FROM `app_recycling_system` WHERE `key`='recycling-weight' ORDER BY `code`");
        $data = array(
            'type' => $type,
            'weight' => $weight
        );
        return $data;
    }
    protected function AddRecyclingRequest($object)
    {
        $data = "";
        $data = $object['content'];
        $data = json_decode($this->InputDecoder($data), true);

        $key = array('packet_key', 'name', 'family', 'mobile', 'nc', 'address', 'number_2', 'client_location', 'select_location', 'ClientID', 'delivery_time', 'delivery_date', 'weight_name', 'weight_size', 'type_name', 'type_size');

        $outData = array('error' => '', 'status' => false, 'default' => "خطا در تجزیه بسته ارسالی");

        $validate = $this->CheckArrayKey($data, $key);
        if ($validate[0]) {
            $query = "INSERT INTO `app_recycling_request_system`
            (package_key, client_id, name, family, mobile, nc, address, number_2, client_location, select_location, delivery_time, delivery_date, weight_name, weight_id, type_name, type_id) VALUES 
            ((SELECT `code` FROM `app_recycling_system` WHERE `key` LIKE ? AND `name` LIKE ?),?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";


            $date = $data['delivery_date'];
            $date = explode("/", $date);
            if (count($date) == 3) $date = $date[2] . "/" . $date[1] . "/" . $date[0];

            $outData['status'] = (boolean)$this->DLA->cDoCommand($query,
                array('s' => 'package'),
                array('s' => $data['packet_key']),
                array('i' => $data['ClientID']),
                array('s' => $data['name']),
                array('s' => $data['family']),
                array('s' => $data['mobile']),
                array('s' => $data['nc']),
                array('s' => $data['address']),
                array('s' => $data['number_2']),
                array('s' => $data['client_location']),
                array('s' => $data['select_location']),
                array('s' => $data['delivery_time']),
                array('s' => strlen($date) > 0 ? $date : $data['delivery_date']),
                array('s' => $data['weight_name']),
                array('i' => $data['weight_size']),
                array('s' => $data['type_name']),
                array('i' => $data['type_size']));
            $outData['error'] = $this->DLA->error();

        } else {
            $outData['error'] = $validate[1];
        }
        return $outData;
    }

    protected function CheckArrayKey($array = array(), $keys = array())
    {
        foreach ($keys as $key)
            if (!array_key_exists($key, $array)) return array(false, $key);
        return array(true);
    }

    protected function InputDecoder($input)
    {
        if ($this->Crypter == null) $this->Crypter = new Crypter();
        $input = $this->Crypter->SwipeString($input);
        $input = $this->Crypter->hex2ByteArray($input);
        $input = $this->Crypter->byteArray2String($input);
        return $input;
    }


    protected function AppLoadRecyclingRequest($object)
    {
//        $query = "SELECT select_location,ID,recycling_agent_id, satisfaction_rate as satisfaction_code,(SELECT `name` FROM `app_recycling_system` WHERE `key`=? AND `code`=satisfaction_rate) as 'satisfaction_rate', request_status as r_code, (SELECT `name` FROM `app_recycling_system` WHERE `key`=? AND `code`=request_status) as r_name, type_name, weight_name, address, delivery_date, delivery_time, CONCAT(name ,' ',family) as name FROM `app_recycling_request_system` WHERE (`client_id`=? OR `recycling_agent_id`=?) AND `package_key`=(SELECT `code` FROM `app_recycling_system` WHERE `key` LIKE ? AND `name` LIKE ?)";


        $query = "
        SELECT select_location,
               ID,
               recycling_agent_id,
               client_id,
               satisfaction_rate                                                                       as satisfaction_code,
               (SELECT `name`
                FROM `app_recycling_system`
                WHERE `key` = ?
                  AND `code` = satisfaction_rate)                                                      as 'satisfaction_rate',
               request_status                                                                          as r_code,
               (SELECT `name` FROM `app_recycling_system` WHERE `key` = ? AND `code` = request_status) as r_name,
               type_name,
               weight_name,
               address,
               delivery_date,
               delivery_time,
               CONCAT(name, ' ', family)                                                               as name
            FROM `app_recycling_request_system`
            WHERE (`client_id` = ? OR `recycling_agent_id` = ?) AND 
                  `package_key` = (SELECT `code` 
                                    FROM `app_recycling_system` 
                                    WHERE `key` LIKE ? AND `name` LIKE ?);";


        $select = $this->DLA->cSelect($query,
            array('s' => 'satisfaction_rate'),
            array('s' => 'request_status'),
            array('i' => $object['cid']),
            array('i' => $object['cid']),
            array('s' => 'package'),
            array('s' => $object['packet_key'])
        );
        $outArray = [];
        if ($select) {
            foreach ($select as $row) {

                $f = strpos($row['select_location'], "(");
                $l = strpos($row['select_location'], ")");

                $location = explode(',', substr($row['select_location'], $f + 1, $l - $f - 1));

                $outArray[] = array(
                    'ID' => $row['ID'],
                    'icon' => '',
                    'name' => $row['name'],
                    'type_name' => $row['type_name'],
                    'weight_name' => $row['weight_name'],
                    'address' => $row['address'],
                    'lat' => (double)$location[0],
                    'lng' => (double)$location[1],
                    'delivery_date' => convert($row['delivery_date'], true),
                    'delivery_time' => convert($row['delivery_time'], true),
                    'request_status_name' => $row['r_name'],
                    'r_code' => $row['r_code'],
                    'st_code' => $row['satisfaction_code'],
                    'agent-id' => (int)$row['recycling_agent_id'],
                    'client-id' => (int)$row['client_id'],
                    'satisfaction' => $row['satisfaction_rate']
                );
            }
        }

        return $outArray ? $outArray : array();
    }


    protected function AppRemoveRecyclingItem($object)
    {
        $outArray = array('error' => true, 'status' => false, 'message' => 'خطا در تجزیه بسته');
        //:{"cid":"731","packet_key":"com.android.semnancard.digihelp.net","item-id":"3","request":"app"}}]
        $key = array('packet_key', 'cid', 'item-id');

        $validate = $this->CheckArrayKey($object, $key);
        if ($validate[0]) {
            $query = "DELETE FROM app_recycling_request_system WHERE `ID`=? AND `client_id`=? AND request_status=? AND `package_key`=(SELECT `code` FROM `app_recycling_system` WHERE `key` LIKE ? AND `name` LIKE ?)";
            $outArray['status'] = $this->DLA->cDoCommand($query,
                array('i' => $object['item-id']),
                array('i' => $object['cid']),
                array('i' => 0),
                array('s' => 'package'),
                array('s' => $object['packet_key'])
            );
            $outArray['error'] = !$outArray['status'];

            if ($outArray['error']) {
                $outArray['message'] = "شما نمیتوانید این بسته را حذف کنید.";
            } else {
                if ($outArray['status']) {
                    $outArray['message'] = "انجام شد.";
                }
            }
        }
        return $outArray;
    }

    protected function AppAddSatisfaction($object)
    {

        $outArray = array('error' => true, 'status' => false, 'message' => 'خطا در تجزیه بسته');

        $key = array('packet_key', 'cid', 'item-id', 'level');
        $validate = $this->CheckArrayKey($object, $key);
        if ($validate[0]) {
            $query = "UPDATE app_recycling_request_system SET `satisfaction_rate`=? WHERE `ID`=? AND `client_id`=? AND `satisfaction_rate`=? AND `package_key`=(SELECT `code` FROM `app_recycling_system` WHERE `key` LIKE ? AND `name` LIKE ?)";

            $outArray['status'] = $this->DLA->cDoCommand($query,
                array('i' => $object['level']),
                array('i' => $object['item-id']),
                array('i' => $object['cid']),
                array('i' => -100),
                array('s' => 'package'),
                array('s' => $object['packet_key'])
            );
            $outArray['error'] = !$outArray['status'];

            if ($outArray['error']) {
                $outArray['message'] = "شما نمیتوانید این بسته را ویرایش کنید.";
            } else {
                if ($outArray['status']) {
                    $outArray['message'] = "انجام شد.";
                }
            }
        }
        return $outArray;
    }


    protected function AppCheckIsAgent($object)
    {
        $outArray = array('error' => true, 'status' => false);
        $key = array('client');
        $validate = $this->CheckArrayKey($object, $key);
        if ($validate[0]) {
            $select = $this->DLA->cSelect("SELECT `is_active` FROM `app_agent_recycling_system` WHERE `agent_id`=" . $object['client']);
            if ($select && count($select) == 1 && $select[0]['is_active']) {
                $outArray = array('error' => false, 'status' => true);
            }
        }
        return $outArray;
    }
    /*custom services*/
}