<?php

namespace App\Models;
use Mail;
use Illuminate\Support\Facades\URL;
use GuzzleHttp\Client;

class Nagad
{
    public function requestUrl(){
        return 'http://sandbox.mynagad.com:10080/';
    }
    public function pgPublicKey(){
        $nagadInfo = PaymentGatewaySettings::where("title","Nagad")->where("status",1)->first();
        return $nagadInfo->public_key;
    }
    public function merchantPrivateKey(){
        $nagadInfo = PaymentGatewaySettings::where("title","Nagad")->where("status",1)->first();
        return $nagadInfo->private_key;
    }
    
    public function MerchantID(){
        $nagadInfo = PaymentGatewaySettings::where("title","Nagad")->where("status",1)->first();
        return $nagadInfo->merchant_id;
    }
    public function MerchantNumber(){
        $nagadInfo = PaymentGatewaySettings::where("title","Nagad")->where("status",1)->first();
        return $nagadInfo->number;
    }
    public function generateRandomString($length = 40)
    {
        $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $charactersLength = strlen($characters);
        $randomString = '';
        for ($i = 0; $i < $length; $i++) {
            $randomString .= $characters[rand(0, $charactersLength - 1)];
        }
        return $randomString;
    }
    public function EncryptDataWithPublicKey($data)
    {
        $pgPublicKey = $this->pgPublicKey();
        $public_key = "-----BEGIN PUBLIC KEY-----\n" . $pgPublicKey . "\n-----END PUBLIC KEY-----";
        // echo $public_key; 
        // exit();
        $key_resource = openssl_get_publickey($public_key);
        openssl_public_encrypt($data, $cryptText, $key_resource);
        return base64_encode($cryptText);   
    }
    public function SignatureGenerate($data)
    {
        $merchantPrivateKey = $this->merchantPrivateKey();
        $private_key = "-----BEGIN RSA PRIVATE KEY-----\n" . $merchantPrivateKey . "\n-----END RSA PRIVATE KEY-----";
        // echo $private_key; 
        // exit();
        openssl_sign($data, $signature, $private_key, OPENSSL_ALGO_SHA256);
        return base64_encode($signature);
    }
    public function getResponseData($payment_ref_id){
        $url = "http://sandbox.mynagad.com:10080/remote-payment-gateway-1.0/api/dfs/verify/payment/".$payment_ref_id;
        $json = $this->HttpGet($url);
        
        return $json;
    }
    public function HttpGet($url)
    {
        $ch = curl_init();
        $timeout = 10;
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
        curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/0 (Windows; U; Windows NT 0; zh-CN; rv:3)");
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        $file_contents = curl_exec($ch);
        echo curl_error($ch);
        curl_close($ch);
        return $file_contents;
    }
    public function HttpPostMethod($PostURL, $PostData)
    {
        //print_r($PostData);
        $url = curl_init($PostURL);
        $postToken = json_encode($PostData);
        $header = array(
            'Content-Type:application/json',
            'X-KM-Api-Version:v-0.2.0',
            'X-KM-IP-V4:' . $this->get_client_ip(),
            'X-KM-Client-Type:PC_WEB'
        );
        
        /*
        $client = new Client();
        
        $requestAPI = $client->post( $PostURL, [
            'headers' => $header,
            'body' => json_encode($PostData)
        ]);
        
        print_r($PostURL);die;
        */
        curl_setopt($url, CURLOPT_HTTPHEADER, $header);
        curl_setopt($url, CURLOPT_CUSTOMREQUEST, "POST");
        curl_setopt($url, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($url, CURLOPT_POSTFIELDS, $postToken);
        curl_setopt($url, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($url, CURLOPT_SSL_VERIFYPEER, false); 
        $resultData = curl_exec($url);
        
        echo "<pre>";
        $report=curl_error($url);
        print_r($report);die;
        
        $ResultArray = json_decode($resultData, true);
        curl_close($url);
        return $ResultArray;

    }
    public function get_client_ip()
    {
        $ipaddress = '';
        if (isset($_SERVER['HTTP_CLIENT_IP']))
            $ipaddress = $_SERVER['HTTP_CLIENT_IP'];
        else if (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
            $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
        else if (isset($_SERVER['HTTP_X_FORWARDED']))
            $ipaddress = $_SERVER['HTTP_X_FORWARDED'];
        else if (isset($_SERVER['HTTP_FORWARDED_FOR']))
            $ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
        else if (isset($_SERVER['HTTP_FORWARDED']))
            $ipaddress = $_SERVER['HTTP_FORWARDED'];
        else if (isset($_SERVER['REMOTE_ADDR']))
            $ipaddress = $_SERVER['REMOTE_ADDR'];
        else
            $ipaddress = 'UNKNOWN';
        return $ipaddress;
    }
    public function DecryptDataWithPrivateKey($cryptText)
    {
        $merchantPrivateKey = $this->merchantPrivateKey();
        $private_key = "-----BEGIN RSA PRIVATE KEY-----\n" . $merchantPrivateKey . "\n-----END RSA PRIVATE KEY-----";
        openssl_private_decrypt(base64_decode($cryptText), $plain_text, $private_key);
        return $plain_text;
    }
    public function urlGenerateForOrder($amount,$callbackUrl){
        date_default_timezone_set('Asia/Dhaka');

        $MerchantID = $this->MerchantID();
        $DateTime = Date('YmdHis');
        $amount = $amount;
        $OrderId = "Ngd".uniqid();;
        //$OrderId = $id_app_user.'x'.$amount.'x'.$no.'xn';
        //print_r(count($OrderId));die;
        $random = $this->generateRandomString();    
        
        $PostURL = $this->requestUrl()."remote-payment-gateway-1.0/api/dfs/check-out/initialize/" . $MerchantID . "/" . $OrderId;
        
        $merchantCallbackURL = $callbackUrl.'/'.$OrderId;
        
        $SensitiveData = array(
            'merchantId' => $MerchantID,
            'datetime' => $DateTime,
            'orderId' => $OrderId,
            'challenge' => $random
        );
        //echo $OrderId;die;
        $PostData = array(
            'accountNumber' => $this->MerchantNumber(), //Replace with Merchant Number
            'dateTime' => $DateTime,
            'sensitiveData' => $this->EncryptDataWithPublicKey(json_encode($SensitiveData)),
            'signature' => $this->SignatureGenerate(json_encode($SensitiveData))
        );
        
        $Result_Data = $this->HttpPostMethod($PostURL, $PostData);
        print_r($Result_Data);die;
        $res['status'] = 0;
        if (isset($Result_Data['sensitiveData']) && isset($Result_Data['signature'])) {
            if ($Result_Data['sensitiveData'] != "" && $Result_Data['signature'] != "") {
        
                $PlainResponse = json_decode($this->DecryptDataWithPrivateKey($Result_Data['sensitiveData']), true);
                //print_r($PlainResponse);die;
                if (isset($PlainResponse['paymentReferenceId']) && isset($PlainResponse['challenge'])) {
        
                    $paymentReferenceId = $PlainResponse['paymentReferenceId'];
                    $randomServer = $PlainResponse['challenge'];
        
                    $SensitiveDataOrder = array(
                        'merchantId' => $MerchantID,
                        'orderId' => $OrderId,
                        'currencyCode' => '050',
                        'amount' => $amount,
                        'challenge' => $randomServer
                    );
        
                    $merchantAdditionalInfo = '{"Service Name": "Infolink Limited"}';
        
                    $PostDataOrder = array(
                        'sensitiveData' => $this->EncryptDataWithPublicKey(json_encode($SensitiveDataOrder)),
                        'signature' => $this->SignatureGenerate(json_encode($SensitiveDataOrder)),
                        'merchantCallbackURL' => $merchantCallbackURL,
                        'additionalMerchantInfo' => json_decode($merchantAdditionalInfo)
                    );
        
                    
                    $OrderSubmitUrl = $this->requestUrl()."remote-payment-gateway-1.0/api/dfs/check-out/complete/" . $paymentReferenceId;
                    $Result_Data_Order = $this->HttpPostMethod($OrderSubmitUrl, $PostDataOrder);
        
                     //echo json_encode($Result_Data_Order);die;
                    
                        if ($Result_Data_Order['status'] == "Success") {
                            $res['status'] = 1;
                            $res['url'] = $Result_Data_Order['callBackUrl'];
                            $res['callback_url'] = $merchantCallbackURL;
                            $res['transaction_id'] = $OrderId;
                            $res['payment_reference_id'] = $paymentReferenceId;
                        }
                        else{
                            $res['status'] = 2;
                        }
                } else {
                    $res['status'] = 3;
                }
            }
        }
        return json_encode($res);
    }
}