<?php

namespace Sipago\WooCommerce\SipagoCheckout\Controllers;
use Sipago\WooCommerce\SipagoCheckout\Helpers\LogHandler;
use Sipago\WooCommerce\SipagoCheckout\ClientSipago\SipagoOrderRest;
use Sipago\WooCommerce\SipagoCheckout\ClientSipago\SipagoLogRemoteRest;

use DateTime;
use DateTimeZone;
use Sipago\WooCommerce\SipagoCheckout\Helpers\SessionMessageHelper;
use Sipago\WooCommerce\SipagoCheckout\Models\Transaction;
use WC_Order;

class WebhookSipagoController
{
    /**
     * @var array
     */
    protected $pluginConfig;



    public $clientId;


    /**
     * ResponseController constructor.
     *
     * @param array $pluginConfig
     */
    public function __construct(array $pluginConfig)
    {
        $this->pluginConfig = $pluginConfig;

        $this->clientId = $this->pluginConfig['CLIENT_ID'];
    }



    

        /**
     * @throws \GuzzleHttp\Exception\GuzzleException
     * @throws \Sipago\WooCommerce\SipagoCheckout\Exceptions\TokenNotFoundOnDatabaseException
     */
    public function responsePrueba($response,$getData,$postData)
    {

        
        $response->set_status(200);
        return $response;
 
    }

    /**
     * @throws \GuzzleHttp\Exception\GuzzleException
     * @throws \Sipago\WooCommerce\SipagoCheckout\Exceptions\TokenNotFoundOnDatabaseException
     */
    public function response($response,$getData,$postData)
    {
        $response->set_status(200);
        $this->log = new LogHandler();
     
        $this->log = new LogHandler();

        $order_id=intval($getData['order_id']);
        $ref_id=$getData['ref'];

        $this->log->logInfo('Webhook order_id -> '.$order_id);
        $this->log->logInfo('Webhook -> ref_id'.$ref_id);

        $sipagopayTransaction = Transaction::getByOrderIdSipago($order_id,$ref_id);


        $sipagoOrderRest=new SipagoOrderRest();
        //$sipagoLogRemoteRest=new SipagoLogRemoteRest($this->clientId );

        $result=$sipagoOrderRest->getOrder($sipagopayTransaction->session_id);

        $jsonRaw = [
            'ref_id' => $ref_id,
            'dataRes' => $result
            
            ];

        //$sipagoLogRemoteRest->putLogs($order_id,"wbk",$jsonRaw);
        $wooCommerceOrder = $this->getWooCommerceOrderById($sipagopayTransaction->order_id);

        if ($wooCommerceOrder->is_paid()) {
            $this->log->logInfo('Webhook is_paid  order_id -> '.$order_id.' ref_id ->'.$ref_id);
            return $response;
        }

        if (!$wooCommerceOrder->needs_payment()) {
            $this->log->logInfo('Webhook needs_payment  order_id -> '.$order_id.' ref_id ->'.$ref_id);
            return $response;
        }


     
        if ( $this->validateTransactionDetails($result, $sipagopayTransaction)) {
            $this->completeWooCommerceOrder($wooCommerceOrder, $result, $sipagopayTransaction);
            $this->log->logInfo('Webhook validateTransactionDetails  order_id -> '.$order_id.' ref_id ->'.$ref_id);
            return $response;
        }

        $this->setWooCommerceOrderAsFailed($wooCommerceOrder, $sipagopayTransaction, $result);
        $this->log->logInfo('Webhook setWooCommerceOrderAsFailed  order_id -> '.$order_id.' ref_id ->'.$ref_id);
        return $response;
    }


    /**
     * @param $orderId
     *
     * @return WC_Order
     */
    protected function getWooCommerceOrderById($orderId)
    {
        $wooCommerceOrder = new WC_Order($orderId);

        return $wooCommerceOrder;
    }

    /**
     * @param WC_Order $wooCommerceOrder
     * @param array    $result
     * @param $sipagopayTransaction
     */
    protected function completeWooCommerceOrder(WC_Order $wooCommerceOrder, $result, $sipagopayTransaction)
    {
        $this->log = new LogHandler();
        $phpObject = json_decode($result['raw'], true); 
        $data = $this->getTransactionDetails($phpObject);
        list($orderNumber,$authorizationCode,$referenceNumber, $amount, $transactionResponse,$date_accepted) = $data;
     
        update_post_meta($wooCommerceOrder->get_id(), 'buyOrder', $result['orderNumber']);
        update_post_meta($wooCommerceOrder->get_id(), 'voucherNumber', $result['voucherNumber']);
        update_post_meta($wooCommerceOrder->get_id(), 'paymentCodeResult', $result['statusSipago']);
        update_post_meta($wooCommerceOrder->get_id(), 'amount', (floatval($result['amount'])/100) ) ;
        update_post_meta($wooCommerceOrder->get_id(), 'transaction_id', $result['uuid']);
        update_post_meta($wooCommerceOrder->get_id(), 'rest_response', json_encode($result['raw']));

        $message = 'Pago exitoso con Sipago';
        
     

        $this->addOrderDetailsOnNotes(
            (floatval($result['amount'])/100) ,
            $result['orderNumber'],
            $message,
            $result['statusSipago'],
            $result['voucherNumber'],
            $result['uuid'],
            $authorizationCode,
            $wooCommerceOrder
        );

        Transaction::update(
            $sipagopayTransaction->id,
            [
                'status'             => Transaction::STATUS_APPROVED,
                'sipago_status'   => $result['statusSipago'],
                'sipago_response' => $result['raw']
            ]
        );

        $wooCommerceOrder->payment_complete();
        $wooCommerceOrder->update_status("completed");
        /*
        $final_status = $this->pluginConfig['STATUS_AFTER_PAYMENT'];
        
        if ($final_status) {
            $wooCommerceOrder->update_status($final_status);
        }*/
    }

    /**
     * @param WC_Order $wooCommerceOrder
     * @param array    $result
     * @param $sipagopayTransaction
     */
    protected function setWooCommerceOrderAsFailed(WC_Order $wooCommerceOrder, $sipagopayTransaction, $result = null)
    {
        $this->log = new LogHandler();
        $_SESSION['woocommerce_order_failed'] = true;
        $wooCommerceOrder->update_status('failed');
        if ($result !== null) {
            $message = 'Pago rechazado';

            $this->addOrderDetailsOnNotes(
            (floatval($result['amount'])/100) ,
            $result['orderNumber'],
            $message,
            $result['statusSipago'],
            $result['voucherNumber'],
            $result['uuid'],
                //$date,
                "",
                $wooCommerceOrder
            );
    
        }


        Transaction::update(
            $sipagopayTransaction->id,
            [
                'status'             => Transaction::STATUS_FAILED,
                'sipago_response' => $result['raw']
            ]
        );
    }

    /**
     * @param array $result
     *
     * @return bool
     */
    protected function transactionIsApproved($result)
    {
        if (!isset($result->responseCode)) {
            return false;
        }

        return (int) $result->responseCode === 0;
    }

    /**
     * @param array $result
     * @param $sipagopayTransaction
     *
     * @return bool
     */
    protected function validateTransactionDetails($result, $sipagopayTransaction)
    {
	    $this->log = new LogHandler();

        
        if ($result['error']) {
            return false;
        }

        return $result['statusSipago'] == 'SUCCESS' && $result['orderNumber']== $sipagopayTransaction->buy_order;
        ## && (floatval($result['amount']))/100 == floatval($sipagopayTransaction->amount);
    }

    /**
     * @param array $result
     *
     * @throws \Exception
     *
     * @return array
     */
 



     public function getTransactionDetails($responseData)
     {
 
  


         $responseDataPayment=null;
         foreach ($responseData['data']['attributes']['payments'] as $x) {
             if ($x['status'] === "APPROVED") {
                 $responseDataPayment=$x;
                 break;
             }
           }
 
 
 
         $responseCode = $responseData['data']['attributes']['status'];
 
 
         $orderNumber = $responseData['data']['attributes']['orderNumber'];
     
         $authorizationCode = "";
         $referenceNumber = "";
 
         if($responseDataPayment!=null){
             $authorizationCode = $responseDataPayment['authorization_code'];
             $referenceNumber = $responseDataPayment['reference_number'];
         }
 
 
         $amountPre = $responseData['data']['attributes']['price']['amount'];
         $amount=(floatval($amountPre)/100);
 
         if ($responseDataPayment!=null && $responseDataPayment["status"] === "APPROVED") {
             $transactionResponse = 'Transacción Aprobada';
         } else {
             $transactionResponse = 'Transacción Rechazada';
         }
         
 
         $date_accepted = new DateTime();
         $date_accepted->setTimeZone(new DateTimeZone(wc_timezone_string()));
 
         return [$orderNumber,$authorizationCode,$referenceNumber, $amount, $transactionResponse,$date_accepted];
     }
     

    protected function setOrderAsCancelledByUser(WC_Order $order_info, $sipagopayTransaction)
    {
        // Transaction aborted by user
        $order_info->add_order_note(__('Sipago: Pago abortado por el usuario en el formulario de pago', 'sipago_wc_plugin'));
        $order_info->update_status('cancelled');
        Transaction::update(
            $sipagopayTransaction->id,
            ['status' => Transaction::STATUS_ABORTED_BY_USER]
        );
    }



    /**
     * @param $amount
     * @param array $result
     * @param $sharesAmount
     * @param string $message
     * @param $transactionResponse
     * @param $authorizationCode
     * @param $cardNumber
     * @param $sharesNumber
     * @param $paymentType
     * @param $paymentCodeResult
     * @param $sipagopayTransaction
     * @param $date
     * @param WC_Order $wooCommerceOrder
     */
    protected function addOrderDetailsOnNotes(
        $amount,
        $buyOrder,
        string $message,
        $transactionResponse,
        $voucherNumber,
        $uuid,
        $authorizationCode,
        WC_Order $wooCommerceOrder
    ) {
        $amountFormatted = number_format($amount, 0, ',', '.');
        $transactionDetails = "
            <div class='sipago_response_note'>
                <p><h3>{$message}</h3></p>
                <strong>Estado: </strong>{$transactionResponse} <br />
                <strong>Orden de compra: </strong>{$buyOrder} <br />
                <strong>Número voucher: </strong>{$voucherNumber} <br />
                <strong>Monto: </strong>$ {$amountFormatted} <br />
                <strong>ID interno: </strong>{$uuid} <br />
                <strong>authorizationCode: </strong>{$authorizationCode} <br />

            </div>
        ";
        $wooCommerceOrder->add_order_note($transactionDetails);
    }

    /**
     * @param $paymentTypeCode
     *
     * @return string|void
     */
 
    /**
     * @param string $msg
     */
    protected function throwError(string $msg)
    {
        $error_message = __($msg);
        wc_add_notice($error_message, 'error');
    }
}
