<?php

class UserList extends OpenAPIAbstraction{
    
    /**
     * 
     * @var ParamHolder
     */
    private $holder;
    
    public function __construct(){
        parent::__construct();
    }
   
    public function showResults(){
        $this -> holder = $this -> getHolder();
        
        $this -> list();
    }
    
    private function list(){
        $where = $this -> getWhere();
        
        $total	= intval($this -> getColumnData(
            $this -> getRowData($this -> accessSelect('COUNT_ACCOUNTS_REVISED', $where)), 
            COLUMN_COUNTER));
       
                
        $list = $this -> accessSelect('LIST_ACCOUNTS_REVISED_BI', $where);
        $totalPage = $this -> getTotalPageCommon(VAR_DEFAULT_PAGE_COUNT, $total);
                
        $result = [
            "row_count" => $this -> holder -> page == -1 ? count($list) : $total,
            "page_total" => $this -> holder -> page == -1 ? 1 : $totalPage,
            "current_page" => $this -> holder -> page,
            "result" => []
        ];
        
        foreach($list as $user){
            $result["result"][] = [
                "user_account" => $this -> getColumnData($user, COLUMN_USER_ACCOUNT),
                "email_address" => $this -> getColumnData($user, COLUMN_MAIL),
                "first_name" => $this -> getColumnData($user, COLUMN_FIRST_NAME),
                "last_name" => $this -> getColumnData($user, COLUMN_LAST_NAME),
                "account_type" => $this -> getColumnData($user, COLUMN_ACCOUNT_TYPE) ? "Corporate" : "Individual",
                "account_cat" => $this -> getColumnData($user, COLUMN_TEST_ACCOUNT_FLG) == 0 ? "Live" : "Test",
                "create_time" => $this -> getColumnData($user, COLUMN_CREATE_TIME),
                "suspension_time" => $this -> getColumnData($user, COLUMN_SUSPENSION_TIME),
                "balances" => $this -> generateBalances($user[COLUMN_USER_ACCOUNT])
            ];
        }
        
        // データの取得
        echo json_encode($result);
    }
    
    private function generateBalances($userAccount){
        $balances = $this -> accessSelect('SELECT_USER_BALANCES', [$userAccount]);
        
        // enhancements
        foreach($balances as &$balance){
            unset($balance["user_account"]);
            $balance["balance"] = $this -> intToCurrency($balance["balance"], $balance["currency"]);
            $balance["withdraw_amount"] = $this -> intToCurrency($balance["withdraw_amount"], $balance["currency"]);
            $balance["deposit_amount"]  = $this -> intToCurrency($balance["deposit_amount"], $balance["currency"]);
        }
         
        return $balances;
    }
    
    private function getWhere() {
        // 変数宣言部
        $where		= NO_STRING;
        $having		= NO_STRING;
        $rtn		= array();
        $statuses	= array();
        
        // 所属WL
        if($this -> holder -> wlId != NO_STRING) {
            $where .= ' AND data.wl_id = (\')' . $this -> holder -> wlId . '(\')';
        }
        
        // メールアドレス
        if($this -> holder -> emailAddress != NO_STRING) {
            $where .= ' AND data.mail LIKE (\')%' . $this -> holder -> emailAddress . '%(\')';
        }
        
        // 氏名
        if($this -> holder -> name != NO_STRING) {
            $where .= ' AND (data.last_name LIKE (\')%' . $this -> holder -> name . '%(\') OR data.first_name LIKE (\')%' . $this -> holder -> name . '%(\'))';
        }
        
        // 口座番号
        if($this -> holder -> userAccount != NO_STRING) {
            $where .= ' AND data.user_account = (\')' . $this -> holder -> userAccount . '(\')';
        }
        
        // 国
        if($this -> holder -> country != NO_STRING) {
            $where .= ' AND data.country = (\')' . $this -> holder -> country . '(\')';
        }
        
        // 都道府県
        if($this -> holder -> state != NO_STRING) {
            $where .= ' AND data.state LIKE (\')%' . $this -> holder -> state . '%(\')';
        }
        
        // 住所
        if($this -> holder -> address != NO_STRING) {
            $where .= ' AND (data.state = (\')' 
                . $this -> holder -> address . '(\') OR city = (\')' 
                . $this -> holder -> address . '(\') OR zip_code = (\')' 
                . $this -> holder -> address . '(\') OR address = (\')' 
                . $this -> holder -> address . '(\'))';
        }
        
        // エージェントコード
        if($this -> holder -> agentCode != NO_STRING) {
            $where .= ' AND data.parent_agent_code = (\')' . $this -> holder -> agentCode . '(\')';
        }
        
        // KYCフラグ
        if($this -> holder -> kycFlg != NO_STRING) {
            if($this -> holder -> kycFlg != NO_COUNT){
                $where .= ' AND data.kyc_validate_status = (\')' . $this -> holder -> kycFlg . '(\')';
            }
        }
        
        // CRM ID
        if($this -> holder -> crmId != NO_STRING) {
            $where .= ' AND data.crm_id = (\')' . $this -> holder -> crmId . '(\')';
        }
          
        // 口座種別
        if($this -> holder -> accountType != NO_STRING) {
            $where .= ' AND data.account_type = (\')' . $this -> holder -> accountType . '(\')';
        }
        
        // 口座種別
        if($this -> holder -> testAccountFlag != NO_STRING) {
            $where .= ' AND data.test_account_flg = (\')' . $this -> holder -> testAccountFlag . '(\')';
        }
        
        // 通貨
        if($this -> holder -> currency != NO_STRING) {
            $where .= ' AND (data.from_currency = (\')' 
                . $this -> holder -> currency . '(\') OR data.to_currency = (\')' 
                . $this -> holder -> currency . '(\') OR data.from_currency = (\')0(\') OR data.to_currency = (\')0(\'))';
        }
        
        // 金額（最低値）
        if($this -> holder -> minAmount != NO_STRING) {
            $having .= ' AND (data.deposit_amount + data.withdraw_amount) >= (\')' . $this -> holder -> minAmount . '(\')';
        }
        
        // 金額（最高値）
        if($this -> holder -> maxAmount != NO_STRING) {
            $having .= ' AND (data.deposit_amount + data.withdraw_amount) <= (\')' . $this -> holder -> maxAmount . '(\')';
        }
        
        // 検索のフラグがある場合
        if($this -> holder ->dateOfAccountOpening != NO_STRING) {
            
            // 開始日（口座開設日）
            if($this -> holder -> dateOfAccountOpeningFrom != NO_STRING) {
                $having .= ' AND data.create_time >= (\')' 
                    . str_replace(DELIMIT_SLASH, DELIMIT_HYPHEN, $this -> holder -> dateOfAccountOpeningFrom) . '(\')';
            }
            
            // 終了日（口座開設日）
            if($this -> holder -> dateOfAccountOpeningTo != NO_STRING) {
                $having .= ' AND data.create_time < DATE_ADD((\')' 
                    . str_replace(DELIMIT_SLASH, DELIMIT_HYPHEN, $this -> holder -> dateOfAccountOpeningTo) . '(\'), INTERVAL 1 DAY)';
            }
        }
        
        // 検索のフラグがある場合
        if($this -> holder -> dateOfLastLogin != NO_STRING) {
            
            // 開始日（最終ログイン日）
            if($this -> holder -> dateOfLastLoginFrom != '2014/01/01'
                && $this -> holder -> dateOfLastLoginFrom != NO_STRING) {
                $having .= ' AND data.last_login_time >= (\')' . 
                str_replace(DELIMIT_SLASH, DELIMIT_HYPHEN, $this -> holder -> dateOfLastLoginFrom) . '(\')';
            }
                
            // 終了日（最終ログイン日）
            if($this -> holder -> dateOfLastLoginTo != NO_STRING) {
                $having .= ' AND data.last_login_time < DATE_ADD((\')' . 
                str_replace(DELIMIT_SLASH, DELIMIT_HYPHEN, $this -> holder -> dateOfLastLoginTo) . '(\'), INTERVAL 1 DAY)';
            }
        }
        
        // 検索のフラグがある場合
        if($this -> holder -> dateOfAccountClosing != NO_STRING) {
            
            // 開始日（口座閉鎖日）
            if($this -> holder -> dateOfAccountClosingFrom != '2014/01/01'
                && $this -> holder -> dateOfAccountClosingFrom != NO_STRING) {
               $having .= ' AND data.close_time >= (\')' . 
               str_replace(DELIMIT_SLASH, DELIMIT_HYPHEN, $this -> holder -> dateOfAccountClosingFrom) . '(\')';
           }
                
           // 終了日（口座閉鎖日）
           if($this -> holder -> dateOfAccountClosingTo != NO_STRING) {
               $having .= ' AND data.close_time < DATE_ADD((\')' . 
               str_replace(DELIMIT_SLASH, DELIMIT_HYPHEN, $this -> holder -> dateOfAccountClosingTo) . '(\'), INTERVAL 1 DAY)';
           }
        }
        
        // 検索のフラグがある場合
        if($this -> holder -> dateOfAccountSuspension != NO_STRING) {
            
            // 開始日（口座閉鎖日）
            if($this -> holder -> dateOfAccountSuspensionFrom != '2014/01/01' 
                && $this -> holder -> dateOfAccountSuspensionFrom != NO_STRING) {
               $having .= ' AND data.suspension_time >= (\')' . 
               str_replace(DELIMIT_SLASH, DELIMIT_HYPHEN, $this -> holder -> dateOfAccountSuspensionFrom) . '(\')';
            }
                
            // 終了日（口座閉鎖日）
            if($this -> holder -> dateOfAccountSuspensionTo != NO_STRING) {
                $having .= ' AND data.suspension_time < DATE_ADD((\')' . 
                str_replace(DELIMIT_SLASH, DELIMIT_HYPHEN, $this -> holder -> dateOfAccountSuspensionTo) . '(\'), INTERVAL 1 DAY)';
            }
        }
        
        if(!empty($this -> statuses())) {
            $where .= ' AND (';
            
            foreach($this -> statuses() as $row) {
                $statuses[] = ' data.status = (\')' . $row . '(\')';
            }
            
            $where .= implode(DELIMIT_OR, $statuses) . ')';
        }
        
        if(empty($this -> holder -> page))
            $this -> holder -> page = 1;
        
        // ページ数
        $start	= ($this -> holder -> page - VAL_INT_1) * VAR_DEFAULT_PAGE_COUNT;
        $page = ' LIMIT ' . $start . DELIMIT_COMMA . VAL_INT_50;
        
        switch($this -> holder -> orderByAlgorithm){
            case 1:
                $this -> holder -> orderByAlgorithm = "ASC";
                break;
            case 2:
                $this -> holder -> orderByAlgorithm = "DESC";
                break;
        }
        
        $rtn[] = $where;
        $rtn[] = $having;
        $rtn[] = "create_time {$this -> holder -> orderByAlgorithm}";
        $rtn[] = $this -> holder -> page != -1 ? $page : NO_STRING;
                
        return $rtn;
    }
    
    private function statuses() : Array {
        $statuses = [];
        
        if($this -> holder -> statusDisable)
            $statuses[] = 0;
        
        if($this -> holder -> statusTempoRegist)
            $statuses[] = 1;
        
        if($this -> holder -> statusStandard)
            $statuses[] = 2;
        
        if($this -> holder -> statusExecutive)
            $statuses[] = 3;
        
        if($this -> holder -> statusSuspended)
            $statuses[] = 4;
        
        if($this -> holder -> statusClosed)
            $statuses[] = 5;
        
        if($this -> holder -> statusSusStandardDormant)
            $statuses[] = 6;
        
        if($this -> holder -> statusSusExecutiveDormant)
            $statuses[] = 7;
        
        return $statuses;
    }
}