<?php

class OverallTransactions extends OpenAPIAbstraction{
    
    /**
     * 
     * @var ParamHolder
     */
    private $holder;
    
    public function showResults(){
        $this -> holder = $this -> getHolder();        
        $this -> list();
    }
    
    private function list(){
       $transactionTotal = $this -> getRowData(
           $this -> accessSelect('COUNT_TRANSACTION', $this -> getWhere()),
           NO_COUNT);
       
       $pagerProps = new PagerProperties();
       $pagerProps -> totalPage = $this -> getTotalPageCommon(VAR_DEFAULT_PAGE_COUNT, $transactionTotal['counter']);
       $pagerProps -> focusedPage = empty($this -> holder -> page) ? 1 : $this -> holder -> page;
       
       $this -> getTotalPageCommon(VAR_DEFAULT_PAGE_COUNT, $transactionTotal['counter'])."\n";
       
       $transactions = $this -> accessSelect('LIST_TRANSACTION', $this -> getWhere($pagerProps));
       
       $result = [
           "row_count" => $transactionTotal["counter"],
           "page_total" => $pagerProps -> totalPage,
           "current_page" => $pagerProps -> focusedPage,
           "result" => $transactions,
       ];
                  
       echo json_encode($result);
    }
    
    /**
     *
     *
     * @param PagerProperties $pagerProps
     * @return int
     */
    private function getFocusedPage(PagerProperties &$pagerProps) : int {
        if($pagerProps -> focusedPage > $pagerProps -> totalPage)
            $pagerProps -> focusedPage = $pagerProps -> totalPage;
            
        return $pagerProps -> focusedPage;
    }
    
    /**
     * 
     * 
     * @param ParamHolder $holder
     * @return string[]
     */
    private function getWhere(PagerProperties &$pagerProps = null) : Array {
        $rtn = [];
        
        if($this -> holder -> transactionNum != NO_STRING) {
            $rtn[] = ' trans.transaction_number = (\')' . $this -> holder -> transactionNum . '(\') ';
        }
        
        // 出金口座名義（検索項目）
        if($this -> holder -> withdrawalAccountName != NO_STRING) {
            $rtn[] = ' (withdraw_users.last_name LIKE (\')%' . trim($this -> holder -> withdrawalAccountName) . 
            '%(\') OR withdraw_users.first_name LIKE (\')%' . trim($this -> holder -> withdrawalAccountName) . '%(\')) ';
        }
        
        // 出金口座番号（検索項目）
        if($this -> holder -> withdrawalAccountNum != NO_STRING) {
            $rtn[] = ' trans.withdraw_account_number = (\')' . $this -> holder -> withdrawalAccountNum . '(\') ';
        }
        
        // 入金口座名義（検索項目）
        if($this -> holder -> depositAccountName != NO_STRING) {
            $rtn[] = ' (deposit_users.last_name LIKE (\')%' . trim($this -> holder -> depositAccountName) . 
            '%(\') OR deposit_users.first_name LIKE (\')%' . trim($this -> holder -> depositAccountName) . '%(\')) ';
        }
        
        // 入金口座番号（検索項目）
        if($this -> holder -> depositAccountNum != NO_STRING) {
            $rtn[] = ' trans.deposit_account_number = (\')' . $this -> holder -> depositAccountNum . '(\') ';
        }
        
        // 取引タイプ（検索項目）
        if($this -> holder -> transactionType != NO_STRING) {
            
            switch($this -> holder -> transactionType) {
                case VAL_INT_1:
                    $rtn[] = ' trans.transaction_type = (\')1(\')';                 // 入金
                    break;
                case VAL_INT_2:
                    $rtn[] = ' trans.transaction_type IN ((\')2(\'), (\')7(\'))';   // 出金
                    break;
                case VAL_INT_3:
                    $rtn[] = ' trans.transaction_type = (\')4(\')';                 // 通貨両替
                    break;
                case VAL_INT_4:
                    $rtn[] = ' trans.transaction_type = (\')3(\') ';                // 口座振替
                    break;
                case VAL_INT_5:
                    $rtn[] = ' trans.transaction_type = (\')5(\')';                 // 引き落し
                    break;
                case VAL_INT_6:
                    $rtn[] = ' (trans.transaction_type = (\')11(\') OR trans.type = (\')1(\'))';    // 引き落し
                    break;
                default:
                    break;
            }
        }
        
        // 通貨
        if($this -> holder -> currency  != NO_STRING) {
            $rtn[] = ' (trans.withdraw_currency = (\')' . $this -> holder -> currency . 
            '(\') OR trans.deposit_currency = (\')' . $this -> holder -> currency . '(\'))';
        }
        
        // 送金額（最少）（検索項目）
        if($this -> holder -> minAmount != NO_STRING) {
            if($this -> holder -> currency == NO_STRING) {  
                $rtn[] = ' (trans.deposit_amount + trans.withdraw_amount) >= (\')' .
                $this -> holder -> minAmount . '(\')';
            } else {                                
                $rtn[] = ' (trans.deposit_amount + trans.withdraw_amount) >= (\')' .
                $this -> currencyToInt($this -> holder -> minAmount, $this -> holder -> currency) . '(\')';
            }
        }
        
        // 送金額（最大）（検索項目）
        if($this -> holder -> maxAmount != NO_STRING) {
            if($this -> holder -> currency == NO_STRING) {  
                $rtn[] = ' (trans.deposit_amount + trans.withdraw_amount) <= (\')' . 
                $this -> holder -> maxAmount . '(\')';
            } else {                                
                $rtn[] = ' (trans.deposit_amount + trans.withdraw_amount) <= (\')' . 
                $this -> currencyToInt($this -> holder -> maxAmount, $this -> holder -> currency) . '(\')';
            }
        }
        
        $statuses = $this -> transactionStatus();
                       
        if(count($statuses) != 0) { 
            foreach($statuses as $val) 
                $clause[] = 'trans.process_status = (\')'.$val.'(\') ';
            
            if($this -> isLoopData($clause)) {
               $where = '('.implode(DELIMIT_OR, $clause).')';
               $rtn[] = $where;
            }            
        }
  
        if($this -> holder -> searchByDate) {
            if($this -> holder -> dateFrom != NO_STRING) 
                $rtn[] = ' trans.transaction_time >= (\')' . $this -> holder -> dateFrom . '(\')';
            
            if($this -> holder -> dateTo != NO_STRING) 
                $rtn[] = ' trans.transaction_time < DATE_ADD((\')' . $this -> holder -> dateTo . '(\'), INTERVAL 1 DAY)';
        }
        
        if($this -> holder -> testAccountFlag != NO_STRING) {
            $rtn[] .= '(withdraw_users.test_account_flg = (\')' 
                . $this -> holder -> testAccountFlag . '(\') OR deposit_users.test_account_flg = (\')' 
                . $this -> holder -> testAccountFlag . '(\'))'  ;
        }
                 
        $page = NO_STRING;
        
        if($pagerProps){
            $start  = ($this -> getFocusedPage($pagerProps) - 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;
        }
        
        $delimitedArrayByAnd =
            (count($rtn) > NO_COUNT)
            ? DELIMIT_AND . implode(DELIMIT_AND, $rtn)
            : NO_STRING;
        
        return array($delimitedArrayByAnd, "transaction_time {$this -> holder -> orderByAlgorithm}", $page);
    }

    /**
     *
     *
     * @param ParamHolder $holder
     * @return array
     */
    private function transactionStatus() : Array {
        $status = [];
        
        if($this -> holder -> statusUser)
            $status[] = 0;
            
        if($this -> holder -> statusAdmin)
            $status[] = 1;
                
        if($this -> holder -> statusAPI)
            $status[] = 2;
                    
        if($this -> holder -> statusBatch)
            $status[] = 3;
                        
        if($this -> holder -> statusBank)
            $status[] = 4;
                            
        if($this -> holder -> statusCard)
            $status[] = 5;
                                
        if($this -> holder -> statusCredit)
            $status[] = 6;
            
        return $status;
    }
    
}