<?php

namespace Extension\KonnektiveUtilPack;
use Application\Controller\CrmsController;

use Application\Config;
use Application\Request;
use Application\Response;
use Application\CrmResponse;
use Application\CrmPayload;
use Application\Lang;
use Application\Session;
use Application\Extension;
use Application\Model\Configuration;


class PaypalCommerceCheckout extends Common
{
    public $stepToAttempt;

    private $paypalCommerce, $enableLegacyFLow, $configuration, $currentConfigId;
    const PAYPAL_ERROR = 'Payment Cancelled';

    public function __construct()
    {
        $this->stepToAttempt     = (int) Session::get('steps.current.id');
        $this->paypalCommerce = Config::extensionsConfig('KonnektiveUtilPack.paypal_commerce');
        $this->enableLegacyFLow = Config::extensionsConfig('KonnektiveUtilPack.enable_legacy_flow');
        $this->currentConfigId = (int) Session::get('steps.current.configId');
        $this->configuration   = new Configuration($this->currentConfigId);
    }

    public function updateCrmPayload()
    {

        if (Request::attributes()->get('action') === 'prospect' || empty($this->paypalCommerce)) {
            return;
        }

        $offerUrl = Request::getOfferUrl();

        $postData   = Request::form()->all();
        $attributes = Request::attributes()->all();

        if ($this->stepToAttempt > 1) {
            $postData['creditCardType'] = Session::get('customer.cardType');
        }

        if ((!empty($postData['creditCardType']) && $postData['creditCardType'] != 'paypal') || empty($postData['creditCardType'])) {
            return;
        }

        if ($this->stepToAttempt == 1) {
            $payload['paySource']       = 'PAYPAL';
            $payload['forceGatewayId']  = Config::extensionsConfig('KonnektiveUtilPack.paypal_merchant_id');
            $payload['redirectsTo']     = $offerUrl . 'extensions/KonnektiveUtilPack/PaypalCommercePostResponse.php';
            $payload['errorRedirectsTo'] = $offerUrl . AJAX_PATH . 'extensions/konnektiveutilpack/paypal-response-error';
        }


        if ($this->stepToAttempt > 1 && !empty($this->paypalCommerce['two_click_upsell'])) {
            $payload['paySource']       = 'PAYPAL';
            $payload['redirectsTo']      = $offerUrl . 'extensions/KonnektiveUtilPack/PaypalCommercePostResponse.php';
            $payload['errorRedirectsTo'] = $offerUrl . AJAX_PATH . 'extensions/konnektiveutilpack/paypal-response-error';
        }

        if ($this->enableLegacyFLow) {
            $payload['paypalBillerId']  = Config::extensionsConfig('KonnektiveUtilPack.paypal_merchant_id');
            $payload['salesUrl']  = \Bootstrap::isNginxServer() ? Request::getOfferUrl() . 'extensions/KonnektiveUtilPack/PaypalCommerceLegacyResponse.php' : Request::getOfferUrl() . AJAX_PATH . 'extensions/konnektiveutilpack/kon-legacy-paypal-success';
            unset($payload['redirectsTo'], $payload['errorRedirectsTo'], $payload['forceGatewayId']);
        }

        CrmPayload::set(
            'sessionId',
            Session::get(
                'extensions.konnektiveUtilPack.importClick.sessionId'
            )
        );

        CrmPayload::remove('cardType');
        CrmPayload::remove('cardNumber');
        CrmPayload::remove('cardExpiryMonth');
        CrmPayload::remove('cardExpiryMonth');
        CrmPayload::remove('cardExpiryYear');
        CrmPayload::remove('cvv');

        CrmPayload::update($payload);
    }

    public function captureCrmResponse()
    {

        if (Request::attributes()->get('action') === 'prospect' || empty($this->paypalCommerce)) {
            return;
        }

        $response = CrmResponse::all();
        
        Session::set('extensions.konnektiveUtilPack.paypalData.form.crmPayload', CrmPayload::all());

        if ($this->enableLegacyFLow && !empty(CrmResponse::get('redirect'))) {
            Response::send(array(
                'success'         => true,
                'skipQueryParams' => true,
                'redirect'        => CrmResponse::get('redirect'),
            ));
        }
        if (!$response['success'] && !empty($response['isMerchantRedirection']) && !$this->enableLegacyFLow) {
            Response::send(array(
                'success'         => true,
                'skipQueryParams' => true,
                'redirect'        => CrmResponse::get('redirect'),
            ));
        }
    }

    public function paypalCommerceResponse()
    {
        $response     = Request::query()->all();
        $instancePath = Request::getInstancePath();

        if (!empty($response['orderData'])) {
            $orderData = json_decode($response['orderData'], true);
            if ($orderData['orderStatus'] == 'COMPLETE') {
                Session::set(
                    sprintf('steps.%d.orderId', $this->stepToAttempt),
                    $orderData['orderId']
                );
                Session::set(
                    sprintf('steps.%d.customerId', $this->stepToAttempt),
                    $orderData['customerId']
                );
                Session::set('queryParams.order_id', $orderData['orderId']);
                Session::set('queryParams.customer_id', $orderData['customerId']);
                $queryParams = Session::get('queryParams');
                $url         = rtrim($instancePath, '/') . '/' . Session::get('steps.next.link');

                CrmResponse::replace(
                    array('success' => true, 'orderId' => $orderData['orderId'], 'customerId' => $orderData['customerId'])
                );

                $this->setNecessarySessionData();
                $extension = Extension::getInstance();
                $extension->performEventActions('afterAnyCrmRequest');

                header(sprintf('Location: %s?%s', $url, http_build_query($queryParams)));
                exit;
            }
        }

        $errorMessage = Lang::get('exceptions.generic_error');

        foreach ($response as $key => $value) {
            if (preg_match("/errorMsg=?.*/i", $value, $match)) {
                $errorMessageParts = explode('=', $match[0]);
                if (!empty($errorMessageParts[1])) {
                    $errorMessage = $errorMessageParts[1];
                    break;
                }
            }
        }

        $queryParams          = Session::get('queryParams');
        $queryParams['error'] = $errorMessage;
        $url                  = rtrim($instancePath, '/') . '/' . Session::get('steps.current.link');
        header(sprintf('Location: %s?%s', $url, http_build_query($queryParams)));
        exit;
    }

    public function paypalCommerceResponseError()
    {
        $response     = Request::query()->all();
        $instancePath = Request::getInstancePath();

        if (!empty($response['errorMsg'])) {
            $errorMessage = $response['errorMsg'];
        } else {
            $errorMessage = Lang::get('exceptions.generic_error');
        }

        $queryParams          = Session::get('queryParams');
        $queryParams['error'] = $errorMessage;
        $url                  = rtrim($instancePath, '/') . '/' . Session::get('steps.current.link');
        header(sprintf('Location: %s?%s', $url, http_build_query($queryParams)));
        exit;
    }

    private function setNecessarySessionData()
    {
        $crmPayloadData = Session::get('extensions.konnektiveUtilPack.paypalData.form.crmPayload');
        CrmPayload::replace($crmPayloadData);
        Session::set('steps.' . $this->stepToAttempt . '.gatewayId', CrmResponse::get('gatewayId'));
        Session::set(sprintf('steps.%d.products', $this->stepToAttempt), CrmPayload::get('products', array()));
    }

    public function paypalLegacyCommerceResponseSuccess()
    {
        $payerID = Request::get('PayerID');
        $token   = Request::get('token');
        $paypalAccept   = Request::get('paypalAccept');
        $baToken   = Request::get('ba_token');
        $offerPath  = Request::getInstancePath();
        // pressed back button in paypal login page
        if (empty($paypalAccept)) {
            $queryParams = Session::get('queryParams');
            if (!empty($queryParams)) {
                $redirectionLink = sprintf(
                    '%s/%s?%s',
                    rtrim($offerPath, '/'),
                    Session::get('steps.current.link'),
                    http_build_query(array_replace(
                        Session::get('queryParams'),
                        array(
                            'error' => self::PAYPAL_ERROR,
                        )
                    ))
                );
            } else {
                $redirectionLink = sprintf(
                    '%s/%s?%s',
                    rtrim($offerPath, '/'),
                    Session::get('steps.current.link'),
                    http_build_query(array_replace(
                        array(
                            'error' => self::PAYPAL_ERROR,
                        )
                    ))
                );
            }
        } else {
            // processed paypal login and transaction done            
            $payload = Session::get('extensions.konnektiveUtilPack.paypalData.form.crmPayload');
            CrmPayload::update($payload);
            CrmPayload::set('payerId', $payerID);
            CrmPayload::set('token', $token);
            CrmPayload::set('baToken', $baToken);
            // Confirm paypal call            
            CrmPayload::set('meta.crmMethod', 'confirmPaypal');
            $crmClass = sprintf(
                '\Application\Model\%s',
                ucfirst(CrmPayload::get('meta.crmType'))
            );
            $crmInstance = new $crmClass(CrmPayload::get('meta.crmId'));
            $crmMethod   = CrmPayload::get('meta.crmMethod');
            call_user_func(array($crmInstance, $crmMethod));
            // Order created by confirmPaypal | proceed to next page
            if (!empty(CrmResponse::get('orderId'))) {
                Session::set(
                    sprintf('steps.%d.orderId', $this->stepToAttempt),
                    CrmResponse::get('orderId')
                );
                Session::set(
                    sprintf('steps.%d.customerId', $this->stepToAttempt),
                    CrmResponse::get('customerId')
                );
                Session::set('queryParams.order_id', CrmResponse::get('orderId'));
                Session::set('queryParams.customer_id', CrmResponse::get('customerId'));
                $this->setNecessarySessionData();
                $extension = Extension::getInstance();
                $extension->performEventActions('afterAnyCrmRequest');
            }
            $redirectionLink = sprintf('%s/%s?%s', rtrim($offerPath, '/'), Session::get('steps.current.goto'), http_build_query(
                array_replace(
                    Session::get('queryParams')
                )
            ));
            // error while processing paypal
            if (empty(CrmResponse::get('success'))) {
                $crmResponse = CrmResponse::all();
                $params = array_replace(
                    Session::get('queryParams'),
                    array(
                        'error' => $crmResponse['errors']['crmError']
                    )
                );

                $redirectionLink = sprintf(
                    '%s/%s?%s',
                    rtrim($offerPath, '/'),
                    Session::get('steps.current.link'),
                    http_build_query($params)
                );


                $redirectionLink = sprintf(
                    '%s/%s?%s',
                    rtrim($offerPath, '/'),
                    Session::get('steps.current.link'),
                    http_build_query($params)
                );
            }
        }
        header('Location: ' . $redirectionLink);
        exit;
    }

}
