<?php

namespace Icetech\Payment\Gateway;

/**
 * Mobilpay Payment Gateway.
 *
 * (c) Draga Sergiu 12/2018
 * (c) Icetech 2018
 *
 */
class Mobilpay extends PaymentGateway
{

    protected $status = [
        'confirmed_pending' => self::STATUS_PENDING, // transaction is pending review. After this is done, a new IPN request will be sent with either confirmation or cancellation
        'paid_pending' => self::STATUS_PENDING, // transaction is pending review. After this is done, a new IPN request will be sent with either confirmation or cancellation
        'paid' => self::STATUS_PREAUTHORIZED, // transaction is pending authorization. After this is done, a new IPN request will be sent with either confirmation or cancellation
        'confirmed' => self::STATUS_PAID, // transaction is finalized, the money have been captured from the customer's account
        'canceled' => self::STATUS_CANCELED, // transaction is canceled
        'credit' => self::STATUS_REFUNDED, // transaction has been refunded
    ];
    protected $errors = [
        0 => 'approved',
        16 => 'card has a risk (i.e. stolen card)',
        17 => 'card number is incorrect',
        18 => 'closed card',
        19 => 'card is expired',
        20 => 'insufficient funds',
        21 => 'cVV2 code incorrect',
        22 => 'issuer is unavailable',
        32 => 'amount is incorrect',
        33 => 'currency is incorrect',
        34 => 'transaction not permitted to cardholder',
        35 => 'transaction declined',
        36 => 'transaction rejected by antifraud filters',
        37 => 'transaction declined (breaking the law)',
        38 => 'transaction declined',
        48 => 'invalid request',
        49 => 'duplicate PREAUTH',
        50 => 'duplicate AUTH',
        51 => 'you can only CANCEL a preauth order',
        52 => 'you can only CONFIRM a preauth order',
        53 => 'you can only CREDIT a confirmed order',
        54 => 'credit amount is higher than auth amount',
        55 => ' capture amount is higher than preauth amount',
        56 => 'duplicate request',
        99 => 'generic error',
    ];

    public function __construct()
    {
        parent::__construct();

        // include mobilepay libs.
        require_once 'vendor/Mobilpay/Payment/Request/Abstract.php';
        require_once 'vendor/Mobilpay/Payment/Request/Card.php';
        require_once 'vendor/Mobilpay/Payment/Request/Notify.php';
        require_once 'vendor/Mobilpay/Payment/Invoice.php';
        require_once 'vendor/Mobilpay/Payment/Address.php';
        require_once 'vendor/Mobilpay/Payment/Request.php';
    }

    public function getContactKeyMappings()
    {
        return [
            'firstName' => 'firstname',
            'lastName' => 'lastname',
            'address' => 'address',
            'email' => 'email',
            'mobilePhone' => 'phone',
            'country' => ['country', 'name'],
            'county' => ['county', 'name'],
            'city' => 'city',
            'zipCode' => 'postalcode',
        ];
    }

    public function getOrderIdParamName()
    {
        return 'orderId';
    }

    public function generatePurchaseParams()
    {
        $objPmReqCard = new \Mobilpay_Payment_Request_Card();
        #merchant account signature - generated by mobilpay.ro for every merchant account
        #semnatura contului de comerciant - mergi pe www.mobilpay.ro Admin -> Conturi de comerciant -> Modifica -> Setari securitate
        $objPmReqCard->signature = $this->merchant_id;
        #you should assign here the transaction ID registered by your application for this commercial operation
        #order_id should be unique for a merchant account
        $objPmReqCard->orderId = $this->order_id;
        #below is where mobilPay will send the payment result. This URL will always be called first; mandatory
        $objPmReqCard->confirmUrl = $this->confirm_url;
        #below is where mobilPay redirects the client once the payment process is finished. Not to be mistaken for a "successURL" nor "cancelURL"; mandatory
        $objPmReqCard->returnUrl = $this->return_url;

        #detalii cu privire la plata: moneda, suma, descrierea
        #payment details: currency, amount, description
        $objPmReqCard->invoice = new \Mobilpay_Payment_Invoice();
        #payment currency in ISO Code format; permitted values are RON, EUR, USD, MDL; please note that unless you have mobilPay permission to 
        #process a currency different from RON, a currency exchange will occur from your currency to RON, using the official BNR exchange rate from that moment
        #and the customer will be presented with the payment amount in a dual currency in the payment page, i.e N.NN RON (e.ee EUR)
        $objPmReqCard->invoice->currency = $this->currency;
        $objPmReqCard->invoice->amount = $this->amount;
        #available installments number; if this parameter is present, only its value(s) will be available
        //$objPmReqCard->invoice->installments= '2,3';
        #selected installments number; its value should be within the available installments defined above
        //$objPmReqCard->invoice->selectedInstallments= '3';
        //platile ulterioare vor contine in request si informatiile despre token. Prima plata nu va contine linia de mai jos.
        // $objPmReqCard->invoice->tokenId = $this->order_id; //'token_id';
        $objPmReqCard->invoice->details = 'Plata cu card-ul prin mobilPay';

        #detalii cu privire la adresa posesorului cardului
        #details on the cardholder address (optional)
        $billingAddress = new \Mobilpay_Payment_Address();

        $billingAddress->type = 'person'; // @qfix

        foreach ($this->details as $key => $value) {
            $billingAddress->$key = $value;
        }

        // @hard coded! sori
        if (empty($this->details['country'])) {
            $billingAddress->country = 'Romania';
        }

        $objPmReqCard->invoice->setBillingAddress($billingAddress);

        $objPmReqCard->encrypt($this->public_key_path);


        return [
            'env_key' => $objPmReqCard->getEnvKey(),
            'data' => $objPmReqCard->getEncData(),
        ];
    }

    public function response()
    {
        $env_key = request('env_key');
        $data = request('data');
        $objPmReq = \Mobilpay_Payment_Request_Abstract::factoryFromEncrypted($env_key, $data, $this->private_key_path);


        // 1. set orderId
        $this->setOrderId($objPmReq->orderId);

        // 2. set responseData.
        $this->setResponseData([
            'error_code' => $objPmReq->objPmNotify->errorCode,
            'error_message' => $objPmReq->objPmNotify->errorMessage,
            'action' => $objPmReq->objPmNotify->action,
            'raw' => $objPmReq,
        ]);

        return $this;
    }

    public function callbackOutput()
    {
        $output = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";

        if ($this->response->hasError()) {
            $output .= "<crc error_type=\"{$this->response->getErrorType()}\" error_code=\"{$this->response->getErrorCode()}\">{$this->response->getMessage()}</crc>";
        } else {
            $output .= "<crc>{$this->response->getMessage()}</crc>";
        }

        return response($output)
            ->header('Content-Type', 'application/xml');
    }

}
