<?php

class OTPTransferCode {

    protected $trans;
    protected $availCodes;
    protected $tnxcodeOTP;

    protected $emailInbox = "OTP.mail.inbox.html";
    protected $tnxcodeForm = "OTP.transfercode.form.html";

    protected $pause = false;

    public function __construct( Transaction $trans ) {
        $this->trans = $trans;
    }


    # Verify OTP

    public function verified() {

        if( !$this->trans->requiresOTP('transfer_code') ) return true;


        $this->availCodes = Uss::$global['options']->get('bank:transfer.codes');
        
        $this->tnxcodeOTP = $this->trans->bundle['tnxcode-otp'] ?? [];

        return !!$this->initOTP();

    }


    # Initiate OTP

    protected function initOTP() {
        
        $index = -1; 
        
        foreach( $this->availCodes as $data ) {

            $index++;

            foreach( $data as $key => $value ) {
                
                $unitCode = $this->tnxcodeOTP[$key] ?? [
                    "code" => $value,
                    "confirmed" => false
                ];
                
                if( !$unitCode['confirmed'] ) {
                    
                    $this->setDefaultTags( $key, !is_null($value), $index );

                    # If the process is not successful, stay on the process

                    if( !$this->processCurrentOTP($key, $unitCode, $value) ) return;

                };

            };

        };

        return true;

    }


    # 

    protected function processCurrentOTP( string $key, array $unitCode, $value ) {
        
        # Send New Transfer Code OTP

        if( is_null($unitCode['code']) ) {

            $this->sendOTP( $key, $unitCode ); 

        } else {

            $codekey = strtoupper($key);

            if( !$this->pause ) {

                if( isset($_POST['tnxcode-otp']) ) {

                    if( $_POST['tnxcode-otp'] === '-R' ) {
                        
                        if( $this->sendOTP( $key, $unitCode ) ) {

                            $this->trans->log('info', "A new {$codekey} code has been send to your email");

                        };

                    } else {
                        
                        $value = (string)($value ?? $unitCode['code']);

                        $unitCode['confirmed'] = ((string)$_POST['tnxcode-otp'] == $value);
                        
                        $this->tnxcodeOTP[$key] = $unitCode;
                        
                        $this->trans->trackBundle( 'tnxcode-otp', $this->tnxcodeOTP );

                        if( !$unitCode['confirmed'] ) {

                            $this->trans->log('error', "The {$codekey} code is incorrect. <br/> Please try again or contact the support team");

                        } else {
                            
                            # Pause the loop processing;

                            return $this->pause = true;

                        };

                    }

                }

            }

        };
        
        $this->trans->setTemplate( $this->tnxcodeForm );

    }


    # Send OTP 

    public function sendOTP( string $key, array $unitCode ) {

        # The general email template

        $globalEmailTemplate = require Udash::VIEW_DIR . "/MAIL/template.php";

        # The generated pin

        $unitCode['code'] = mt_rand(1000, 9999);

        $this->tnxcodeOTP[$key] = $unitCode;

        # The Template Data 

        $emailData = [ 
            "title" => strtoupper($key) . " Code",
            "region" => $this->trans->post['tx_region'],
            "pin" => $unitCode['code']
        ];

        $emailData['code_name'] = $emailData['title'];

        # The Template Content

        $emailContent = file_get_contents( $this->trans->getTemplate( $this->emailInbox ) );

        $emailContent = Core::replace_var($emailContent, $emailData);

        $emailContent = $this->trans->X2Client( $emailContent );

        # The Email Body

        $emailBody = Core::replace_var( $globalEmailTemplate, [
            "content" => $emailContent
        ]);

        # Send Email

        try {

            $PHPMailer = Udash::PHPMailer( true );
            $PHPMailer->Subject = "New {$emailData['title']}";
            $PHPMailer->addAddress( $this->trans->user['email'] );
            $PHPMailer->Body = $emailBody;

            # Allow testable with MailHog
            $this->trans->localTesting( $PHPMailer );

            # Send the email
            $send = $PHPMailer->send();

            if( $send ) {  

                # Track Bundle
                $this->trans->trackBundle( 'tnxcode-otp', $this->tnxcodeOTP );

                return true;

            };

            $this->trans->log('error', "The system was unable to send {$emailData['code_name']}. <br/> Please try again or contact the support team");

        } catch(Exception $e) {

            $this->trans->log('error', "Failed to send {$emailData['code_name']} Email <br/> Please contact the support team");
            
        }

        return false;

    }


    # A value of `NULL` indicates that the code is auto

    protected function setDefaultTags(string $key, $staticValue, int $index) {

        # Key in uppercase
        $codekey = strtoupper($key);

        # Message to User
        if( $staticValue ) {

            $summary = "Please <span class='text-danger'>contact the admin</span> to receive the {$codekey} code";

            $newCodeRequestElement = null;

        } else {

            $summary = "Please <span class='text-danger'>check your email</span> for the {$codekey} code";

            $newCodeRequestElement = "
            <hr/>
            <p>
                Didn't receive the code? 
                <a href='javascript:void(0)' id='resend-otp' data-name='tnxcode-otp'> Request Another</a>
            </p>
            ";

        };

        $index;

        # Counter
        $countResult = $index . " of " . count($this->availCodes);

        if( !$index ) {
            $percentage = 0;
            $width = 100;
            $style = 'bg-secondary-subtle';
        } else {
            # Mark percentage by index
            $percentage = ( $index * 100 ) / count($this->availCodes);
            $percentage = explode(".", $percentage);
            if( !empty($percentage[1]) ) $percentage[1] = substr($percentage[1], 0, 1);
            $percentage = implode(".", $percentage);
            $width = $percentage;
            $style = 'progress-bar-striped --progress-bar-animated bg-primary bg-opacity-75';
        };

        $progressBar = "
            <div class='progress' style='height: 30px;'>
                <div class='progress-bar {$style}' role='progressbar' style='width: {$width}%;' aria-valuenow='{$percentage}' aria-valuemin='0' aria-valuemax='100'>{$percentage}%</div>
            </div>
        ";

        # Increase Text Is Chosen Instead
        $progressText = "<div class='text-end'>
            <span class='text-muted'>Progress Status: </span> {$countResult}
        </div>";

        # Request new email button

        Uss::tag('codekey', $codekey);
        Uss::tag('summary', $summary);

        Uss::tag('newCodeRequestElement', $newCodeRequestElement);

        # Uss::tag('progressInformation', $progressText);
        Uss::tag('progressInformation', $progressBar);

    }

}