<?php

class Transaction extends AbstractHelper
{
    protected $dir;
    protected $user;
    protected $post;
    protected $usermeta;

    protected $template = "transaction-form.php";
    protected $noncekey = 'transfer';

    protected $bankinfo;
    protected $transfer = [];

    public function __construct()
    {

        parent::__construct(); # Configurations are available in Parent Classes

        if($_SERVER['REQUEST_METHOD'] == 'POST') {
            $this->initTransfer();
        }

    }

    # Process The Transaction;

    private function initTransfer()
    {

        # Inform JavaScript
        Uss::console('transaction', true);

        $this->prepareTransaction(); # ( AbstractTransfer )

        $this->getBeneficiary(); # ( AbstractTransfer )

        # No Error
        if(!$this->hasError()) {

            # Successful Transfer
            if($location = $this->processTransfer()) {

                # Save Beneficiary
                $this->saveBeneficiary(); # ( AbstractTransfer )

               $this->relocate($location);

            };

        };

    }


    # Check for Errors

    private function hasError()
    {

        if($this->transferError()) {
            return true;
        } elseif(!(new OTPEmail($this))->verified()) {
            return true;
        } # ( AbstractOTP )

        elseif(!(new OTPTransferCode($this))->verified()) {
            return true;
        } # ( AbstractOTP )

        elseif($this->loading()) {
            return true;
        } # ( AbstractTransfer )

        return false;

    }


    # Check for Transaction Errors

    private function transferError()
    {

        # Check if user account is active

        $active = $this->usermeta->get('bank:account', $this->user['id']);

        if(empty($active) || empty($active['can-transfer'])) {

            $message = "{$this->post['tx_region']} transfer is not activated on this account <br/> Please contact support";

            return $this->log('error', $message);

        } else {

            # Check if Account Number is Valid

            if(strlen($this->post['bank_account']) > 20 || !is_numeric($this->post['bank_account'])) {

                $message = "The account number does not follow any financial institution standard!";

                return $this->log('error', $message);

            } else {

                # Check if user balance is sufficient

                if($this->user['balance'] < $this->transfer['total']) {

                    $total = number_format($this->transfer['total'], 2);

                    $message = "
                        <h5 class='fw-normal'>Insufficient Fund</h5> 
                        <p>You need a minimum of <span class='text-primary'>{$this->user['currency']['symbol']}{$total}</span> to initiate this transaction</p>
                    ";

                    return $this->log('error', $message);

                };

            }

        };

    }


    # Process The User Transaction

    private function processTransfer()
    {

        # Configure Sender Info

        $transaction = array();

        $transaction['default'] = $this->post;

        $transaction['debit'] = [
            'account_number' => $this->user['bank_number']
        ];

        $transaction['credit'] = [
            'account_number' => $this->post['bank_account']
        ];

        $transfer = Bank::transfer($transaction);

        # Send Transaction Data

        return $this->response($transfer);

    }


    # This adds transaction to database;

    private function response($tx_ref)
    {

        try {

            if(!$tx_ref) {

                # If the user was not debited, transaction will still be recorded as failed

                throw new Exception("Your account could not be debited");

            } else {

                return Core::url(ROOT_DIR . "/" . UDASH_ROUTE . "/transfer/history");

            };

        } catch(Exception $e) {

            # Get Deletion Query
            $SQL = SQuery::delete(DB_TABLE_PREFIX . "_transfers", "tx_ref = '{$tx_ref}'");

            # Delete The Transaction;
            $result = Uss::$global['mysqli']->query($SQL);

            # Report Error Message
            $this->log('error', "The transaction was not successful");

            # Create a log Message
            $error = [
                "Date: " . date('Y-M-d h:i A'),
                "Error: Failed transaction ({$this->user['id']}:{$this->user['email']})",
                "Message: \"{$e->getMessage()}\"",
                "File: {$e->getFile()}",
                "Line: {$e->getLine()}",
                "\n\n"
            ];

            # save error;
            error_log(implode("; ", $error), 3, $this->dir . "/transfer.error_log");

            return false;

        };

        return $tx_ref;

    }

    private function relocate(string $location) {
         
        header("location: {$location}");

        Uss::exit();
        
    }
};
