<?php

/**
 * 
 * @author antonio
 *
 */
trait ProcessingHistory{
    
    /**
     * 
     * with pagination algo
     * 
     * 
     */
    public function getTransactions(ParamHolder $holder){
        $sys = $holder -> getSource();
        
        if($sys instanceof System){
            $transactionTotal = $sys -> getRowData(
                $sys -> accessSelect('COUNT_TRANSACTION', $this -> getWhereHistory($holder)), 
                NO_COUNT);
            
            $pagerProps = new PagerProperties();
            $pagerProps -> totalPage = $sys -> getTotalPageCommon(VAR_DEFAULT_PAGE_COUNT, $transactionTotal['counter']);
            $pagerProps -> focusedPage = empty($holder -> page) ? 1 : $holder -> page;
            
            $sys -> getTotalPageCommon(VAR_DEFAULT_PAGE_COUNT, $transactionTotal['counter'])."\n";
            
            $transactions = $sys -> accessSelect('LIST_TRANSACTION', $this -> getWhereHistory($holder, $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 getWhereHistory(ParamHolder $holder, PagerProperties &$pagerProps = null) : Array {
        $sys = $holder -> getSource();
        
        $rtn = [];
        
        if($holder -> transactionNum != NO_STRING) {
            $rtn[] = ' trans.transaction_number = (\')' . $holder -> transactionNum . '(\') ';
        }
        
        // 出金口座名義（検索項目）
        if($holder -> withdrawalAccountName != NO_STRING) {
            $rtn[] = ' (withdraw_users.last_name LIKE (\')%' . trim($holder -> withdrawalAccountName) . 
            '%(\') OR withdraw_users.first_name LIKE (\')%' . trim($holder -> withdrawalAccountName) . '%(\')) ';
        }
        
        // 出金口座番号（検索項目）
        if($holder -> withdrawalAccountNum != NO_STRING) {
            $rtn[] = ' trans.withdraw_account_number = (\')' . $holder -> withdrawalAccountNum . '(\') ';
        }
        
        // 入金口座名義（検索項目）
        if($holder -> depositAccountName != NO_STRING) {
            $rtn[] = ' (deposit_users.last_name LIKE (\')%' . trim($holder -> depositAccountName) . 
            '%(\') OR deposit_users.first_name LIKE (\')%' . trim($holder -> depositAccountName) . '%(\')) ';
        }
        
        // 入金口座番号（検索項目）
        if($holder -> depositAccountNum != NO_STRING) {
            $rtn[] = ' trans.deposit_account_number = (\')' . $holder -> depositAccountNum . '(\') ';
        }
        
        // 取引タイプ（検索項目）
        if($holder -> transactionType != NO_STRING) {
            
            switch($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($holder -> currency  != NO_STRING) {
            $rtn[] = ' (trans.withdraw_currency = (\')' . $holder -> currency . 
            '(\') OR trans.deposit_currency = (\')' . $holder -> currency . '(\'))';
        }
        
        // 送金額（最少）（検索項目）
        if($holder -> minAmount != NO_STRING) {
            if($holder -> currency == NO_STRING) {	
                $rtn[] = ' (trans.deposit_amount + trans.withdraw_amount) >= (\')' .
                $holder -> minAmount . '(\')';
            } else {								
                $rtn[] = ' (trans.deposit_amount + trans.withdraw_amount) >= (\')' .
                $sys -> currencyToInt($holder -> minAmount, $holder -> currency) . '(\')';
            }
        }
        
        // 送金額（最大）（検索項目）
        if($holder -> maxAmount != NO_STRING) {
            if($holder -> currency == NO_STRING) {	
                $rtn[] = ' (trans.deposit_amount + trans.withdraw_amount) <= (\')' . 
                $holder -> maxAmount . '(\')';
            } else {								
                $rtn[] = ' (trans.deposit_amount + trans.withdraw_amount) <= (\')' . 
                $sys -> currencyToInt($holder -> maxAmount, $holder -> currency) . '(\')';
            }
        }
        
        $statuses = $this -> transactionStatus($holder);
                       
        if(count($statuses) != 0) {	
            foreach($statuses as $val) 
                $clause[] = 'trans.process_status = (\')'.$val.'(\') ';
            
            if($sys -> isLoopData($clause)) {
               $where = '('.implode(DELIMIT_OR, $clause).')';
               $rtn[] = $where;
            }            
        }
  
        if($holder -> searchByDate) {
            if($holder -> dateFrom != NO_STRING) 
                $rtn[] = ' trans.transaction_time >= (\')' . $holder -> dateFrom . '(\')';
            
            if($holder -> dateTo != NO_STRING) 
                $rtn[] = ' trans.transaction_time < DATE_ADD((\')' . $holder -> dateTo . '(\'), INTERVAL 1 DAY)';
        }
        
        if($holder -> testAccountFlag != NO_STRING) {
            $rtn[] .= '(withdraw_users.test_account_flg = (\')' 
                . $holder -> testAccountFlag . '(\') OR deposit_users.test_account_flg = (\')' 
                . $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($holder -> orderByAlgorithm){
            case 1:
                $holder -> orderByAlgorithm = "ASC";
                break;
            case 2:
                $holder -> orderByAlgorithm = "DESC";
                break;
        }
        
        $delimitedArrayByAnd =
            (count($rtn) > NO_COUNT)
            ? DELIMIT_AND . implode(DELIMIT_AND, $rtn)
            : NO_STRING;
            
        return array($delimitedArrayByAnd, "transaction_time {$holder -> orderByAlgorithm}", $page);
    }
    
    /**
     * 
     * 
     * @param ParamHolder $holder
     * @return array
     */
    private function transactionStatus(ParamHolder $holder) : Array {
        $status = [];
        
        if($holder -> statusUser)
            $status[] = 0;
        
        if($holder -> statusAdmin)
            $status[] = 1;
        
        if($holder -> statusAPI)
            $status[] = 2;
        
        if($holder -> statusBatch)
            $status[] = 3;
            
        if($holder -> statusBank)
            $status[] = 4;
        
        if($holder -> statusCard)
            $status[] = 5;
        
        if($holder -> statusCredit)
            $status[] = 6;
        
        return $status;
    }
}