<?php

namespace App\Http\Controllers\Payment;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\CustomerPackage;
use App\Models\SellerPackage;
use App\Models\CombinedOrder;
use App\Http\Controllers\CustomerPackageController;
use App\Http\Controllers\SellerPackageController;
use App\Http\Controllers\WalletController;
use App\Http\Controllers\CheckoutController;
use App\Models\Order;
use Session;

class BkashController extends Controller
{
    private $base_url;
    public function __construct()
    {
        if (get_setting('bkash_sandbox', 1)) {
            $this->base_url = "https://tokenized.sandbox.bka.sh/v1.2.0-beta/tokenized/";
        } else {
            $this->base_url = "https://tokenized.pay.bka.sh/v1.2.0-beta/tokenized/";
        }
    }

    public function pay()
    {
        $amount = 0;
        if (Session::has('payment_type')) {
            $paymentType = Session::get('payment_type');
            $paymentData = Session::get('payment_data');
            if ($paymentType == 'cart_payment') {
                $combined_order = CombinedOrder::findOrFail(Session::get('combined_order_id'));
                $amount = round($combined_order->grand_total);
            } elseif ($paymentType == 'order_re_payment') {
                $order = Order::findOrFail($paymentData['order_id']);
                $amount = round($order->grand_total);
            } elseif ($paymentType == 'wallet_payment') {
                $amount = round($paymentData['amount']);
            } elseif ($paymentType == 'customer_package_payment') {
                $customer_package = CustomerPackage::findOrFail($paymentData['customer_package_id']);
                $amount = round($customer_package->amount);
            } elseif ($paymentType == 'seller_package_payment') {
                $seller_package = SellerPackage::findOrFail($paymentData['seller_package_id']);
                $amount = round($seller_package->amount);
            }
        }

        Session::forget('bkash_token');
        Session::put('bkash_token', $this->getToken());
        Session::put('amount', $amount);
        return redirect()->route('bkash.create_payment');
    }

    public function create_payment()
    {

        $requestbody = array(
            'mode' => '0011',
            'payerReference' => ' ',
            'callbackURL' => route('bkash.callback'),
            'amount' => Session::get('amount'),
            'currency' => 'BDT',
            'intent' => 'sale',
            'merchantInvoiceNumber' => "Inv" . Date('YmdH') . rand(1000, 10000)
        );
        $requestbodyJson = json_encode($requestbody);

        $header = array(
            'Content-Type:application/json',
            'Authorization:' . Session::get('bkash_token'),
            'X-APP-Key:' . env('BKASH_CHECKOUT_APP_KEY')
        );

        $url = curl_init($this->base_url . 'checkout/create');
        curl_setopt($url, CURLOPT_HTTPHEADER, $header);
        curl_setopt($url, CURLOPT_CUSTOMREQUEST, "POST");
        curl_setopt($url, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($url, CURLOPT_POSTFIELDS, $requestbodyJson);
        curl_setopt($url, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($url, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
        $resultdata = curl_exec($url);
        curl_close($url);

        return redirect(json_decode($resultdata)->bkashURL);
    }

    public function getToken()
    {
        $request_data = array('app_key' => env('BKASH_CHECKOUT_APP_KEY'), 'app_secret' => env('BKASH_CHECKOUT_APP_SECRET'));
        $request_data_json = json_encode($request_data);

        $header = array(
            'Content-Type:application/json',
            'username:' . env('BKASH_CHECKOUT_USER_NAME'),
            'password:' . env('BKASH_CHECKOUT_PASSWORD')
        );

        $url = curl_init($this->base_url . 'checkout/token/grant');
        curl_setopt($url, CURLOPT_HTTPHEADER, $header);
        curl_setopt($url, CURLOPT_CUSTOMREQUEST, "POST");
        curl_setopt($url, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($url, CURLOPT_POSTFIELDS, $request_data_json);
        curl_setopt($url, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($url, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);

        $resultdata = curl_exec($url);
        curl_close($url);

        $token = json_decode($resultdata)->id_token;
        return $token;
    }

    public function callback(Request $request)
    {
        $allRequest = $request->all();
        if (isset($allRequest['status']) && $allRequest['status'] == 'success'){
            $resultdata = $this->execute($allRequest['paymentID']);
            if (!$resultdata){
                $resultdata = $this->query($allRequest['paymentID']);
            }

            Session::forget('payment_details');
            Session::put('payment_details', $resultdata);
            $response = json_decode($resultdata, true);

            if (isset($response['statusCode']) && $response['statusCode'] == "0000" && $response['transactionStatus'] == "Completed") {
                return redirect()->route('bkash.success');
            } else if (isset($response['transactionStatus']) && $response['transactionStatus'] == "Initiated") {
                return redirect()->route('bkash.create_payment');
            }
            return view('frontend.bkash.fail')->with(['errorMessage' => $response['statusMessage']]);
            
        } else if (isset($allRequest['status']) && $allRequest['status'] == 'cancel'){
            return view('frontend.bkash.fail')->with(['errorMessage' => 'Payment Cancelled']);
        } else{
            return view('frontend.bkash.fail')->with(['errorMessage' => 'Payment Failure']);
        }
        
        // $allRequest = $request->all();
        // if (isset($allRequest['status']) && $allRequest['status'] == 'failure') {
        //     return view('frontend.bkash.fail')->with([
        //         'errorMessage' => 'Payment Failure'
        //     ]);
        // } else if (isset($allRequest['status']) && $allRequest['status'] == 'cancel') {
        //     return view('frontend.bkash.fail')->with([
        //         'errorMessage' => 'Payment Cancelled'
        //     ]);
        // } else {

        //     $resultdata = $this->execute($allRequest['paymentID']);
        //     Session::forget('payment_details');
        //     Session::put('payment_details', $resultdata);

        //     $result_data_array = json_decode($resultdata, true);
        //     if (array_key_exists("statusCode", $result_data_array) && $result_data_array['statusCode'] != '0000') {
        //         return view('frontend.bkash.fail')->with([
        //             'errorMessage' => $result_data_array['statusMessage'],
        //         ]);
        //     } else if (array_key_exists("statusMessage", $result_data_array)) {
        //         // if execute api failed to response
        //         sleep(1);
        //         $resultdata = json_decode($this->query($allRequest['paymentID']));

        //         if ($resultdata->transactionStatus == 'Initiated') {
        //             return redirect()->route('bkash.create_payment');
        //         }
        //     }

        //     return redirect()->route('bkash.success');
        // }
    }

    public function execute($paymentID)
    {

        $auth = Session::get('bkash_token');

        $requestbody = array(
            'paymentID' => $paymentID
        );
        $requestbodyJson = json_encode($requestbody);

        $header = array(
            'Content-Type:application/json',
            'Authorization:' . $auth,
            'X-APP-Key:' . env('BKASH_CHECKOUT_APP_KEY')
        );

        $url = curl_init($this->base_url . 'checkout/execute');
        curl_setopt($url, CURLOPT_HTTPHEADER, $header);
        curl_setopt($url, CURLOPT_CUSTOMREQUEST, "POST");
        curl_setopt($url, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($url, CURLOPT_POSTFIELDS, $requestbodyJson);
        curl_setopt($url, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($url, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
        $resultdata = curl_exec($url);
        curl_close($url);

        return $resultdata;
    }

    public function query($paymentID)
    {

        $auth = Session::get('bkash_token');

        $requestbody = array(
            'paymentID' => $paymentID
        );
        $requestbodyJson = json_encode($requestbody);

        $header = array(
            'Content-Type:application/json',
            'Authorization:' . $auth,
            'X-APP-Key:' . env('BKASH_CHECKOUT_APP_KEY')
        );

        $url = curl_init($this->base_url . 'checkout/payment/status');
        curl_setopt($url, CURLOPT_HTTPHEADER, $header);
        curl_setopt($url, CURLOPT_CUSTOMREQUEST, "POST");
        curl_setopt($url, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($url, CURLOPT_POSTFIELDS, $requestbodyJson);
        curl_setopt($url, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($url, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
        $resultdata = curl_exec($url);
        curl_close($url);

        return $resultdata;
    }


    public function success(Request $request)
    {
        $payment_type = Session::get('payment_type');
        $paymentData = Session::get('payment_data');
        
        if ($payment_type == 'cart_payment') {
            return (new CheckoutController)->checkout_done(Session::get('combined_order_id'), Session::get('payment_details'));
        }
        elseif ($payment_type == 'order_re_payment') {
            return (new CheckoutController)->orderRePaymentDone($paymentData, Session::get('payment_details'));
        }
        elseif ($payment_type == 'wallet_payment') {
            return (new WalletController)->wallet_payment_done($paymentData, Session::get('payment_details'));
        }
        elseif ($payment_type == 'customer_package_payment') {
            return (new CustomerPackageController)->purchase_payment_done($paymentData, Session::get('payment_details'));
        }
        elseif ($payment_type == 'seller_package_payment') {
            return (new SellerPackageController)->purchase_payment_done($paymentData, Session::get('payment_details'));
        }
    }
}
