<?php

namespace App\Http\Controllers;

use App\Models\Client;
use App\Models\BkashPayment;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Jobs\ClientSyncJobForSingle;
use Brian2694\Toastr\Facades\Toastr;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Storage;
use App\Http\Controllers\PaymentController;
use App\Http\Controllers\Customer\CustomerFrontController;
use App\Models\BkashPaymentResellerReport;
use App\Models\PaymentGetwayCredential;
use App\Models\Pop;
use App\Models\Reseller;
use Illuminate\Support\Facades\Log;

class BkashController extends Controller
{
    private $base_url;
    private $app_key;
    private $app_secret;
    private $username;
    private $password;
    private $error;
    private $payerReference;
    private $callbackurl;


    public function __construct()
    {
        // bKash Merchant API Information

        // You can import it from your Database
        // $bkash_app_key = '7epj60ddf7id0chhcm3vkejtab'; // bKash Merchant API APP KEY
        // $bkash_app_secret = '18mvi27h9l38dtdv110rq5g603blk0fhh5hg46gfb27cp2rbs66f'; // bKash Merchant API APP SECRET
        // $bkash_username = 'sandboxTokenizedUser01'; // bKash Merchant API USERNAME
        // $bkash_password = 'sandboxTokenizedUser12345'; // bKash Merchant API PASSWORD
        // $base_url = 'https://tokenized.sandbox.bka.sh/v1.2.0-beta'; // For Live Production URL: https://checkout.pay.bka.sh/v1.2.0-beta

        $this->app_key          = config('app.bkash_app_key');
        $this->app_secret       = config('app.bkash_app_secret');
        $this->username         = config('app.bkash_username');
        $this->password         = config('app.bkash_password');
        $this->base_url         = config('app.bksh_base_url');
        $this->payerReference   = config('app.bkash_payerReference');
        $this->callbackurl      = config('app.bkash_callbackurl');


        // 'bkash_app_key'          => env('BKASH_APP_KEY'),
        // 'bkash_app_secret'       => env('BKASH_SECRET_KEY'),
        // 'bkash_username'         => env('BKASH_USERNAME'),
        // 'bkash_password'         => env('BKASH_PASSWORD'),
        // 'bksh_base_url'          => env('BKASH_URL'),
        // 'bkash_payerReference'   => env('BKASH_PAYER_REFERENCE'),
        // 'bkash_callbackurl'      => env('BKASH_CALLBACK_URL'),


        for ($i = 2001; $i <= 2069; $i++) {
            $this->error[] = $i;
        }
    }




    public function generateToken($pop = null, $getwayInfo = null)
    {
        session()->forget('bkash_token');

        // dd($pop, $getwayInfo);

        if ($pop == null) {
            $post_token = array(
                'app_key' => $this->app_key,
                'app_secret' => $this->app_secret
            );

            $url = curl_init("$this->base_url/tokenized/checkout/token/grant");
        }else {

            if($pop->bill_generate == 'no'){
                $post_token = array(
                    'app_key' => $getwayInfo->appkey_publickey,
                    'app_secret' => $getwayInfo->secretkey_privatekey
                );

                $url = curl_init("$getwayInfo->base_url/tokenized/checkout/token/grant");
            }else{
                $post_token = array(
                    'app_key' => $this->app_key,
                    'app_secret' => $this->app_secret
                );

                $url = curl_init("$this->base_url/tokenized/checkout/token/grant");
            }

        }



        // dd($url, $post_token);

        // $url = curl_init("$this->base_url/tokenized/checkout/token/grant");

        // dd($url);
        $post_token = json_encode($post_token);

        if($pop == null){
            $header = array(
                "Accept: application/json",
                'Content-Type:application/json',
                "password:$this->password",
                "username:$this->username"
            );
        }else{

            if($pop->bill_generate == 'no'){
                $header = array(
                    "Accept: application/json",
                    'Content-Type:application/json',
                    "password:$getwayInfo->password_merchantnumber",
                    "username:$getwayInfo->username_merchantid"
                );
            }else{
                $header = array(
                    "Accept: application/json",
                    'Content-Type:application/json',
                    "password:$this->password",
                    "username:$this->username"
                );
            }

        }




        curl_setopt($url, CURLOPT_HTTPHEADER, $header);
        curl_setopt($url, CURLOPT_CUSTOMREQUEST, "POST");
        curl_setopt($url, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($url, CURLOPT_ENCODING, "");
        curl_setopt($url, CURLOPT_MAXREDIRS, 10);
        curl_setopt($url, CURLOPT_TIMEOUT, 30);
        curl_setopt($url, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
        curl_setopt($url, CURLOPT_POSTFIELDS, $post_token);
        curl_setopt($url, CURLOPT_FOLLOWLOCATION, 1);
        $resultdata = curl_exec($url);
        curl_close($url);

        $response = json_decode($resultdata, true);

        // dd($response);

        // Storage::put('tokenresponse.txt',$resultdata);  //this is for store token in txt file for debug

        session()->put('bkash_token', $response['id_token']);

        return $response['id_token'];
    }



    public function createPayment(Request $request)
    {
        $client = Client::find($request->customerid);
        $pop = Pop::find($client->pop_id);
        $reseller = Reseller::find($pop->reseller_id);

        if($pop->bill_generate == 'no'){
            $getwayInfo = PaymentGetwayCredential::where('reseller_id', $reseller->id)->where('getway_name', 'bkash')->first();
        }

        if($pop->bill_generate == 'no'){
            $token = $this->generateToken($pop, $getwayInfo);
        }else{
            $token = getTokenForBkash();
        }

        // dd($getwayInfo);
        $merchantInvoiceNumber = rand();

        $bkashPaymentResellerReport = new BkashPaymentResellerReport();
        $bkashPaymentResellerReport->merchantInvoiceNumber = $merchantInvoiceNumber;
        $bkashPaymentResellerReport->client_id = $request->customerid;
        $bkashPaymentResellerReport->reseller_id = $reseller->id;
        $bkashPaymentResellerReport->pop_id = $pop->id;
        $bkashPaymentResellerReport->amount = $request->amount;
        $bkashPaymentResellerReport->transactionStatus = 'Pending';
        $bkashPaymentResellerReport->save();

        Log::error("Bkash Invoice {$merchantInvoiceNumber}");



        $re['intent'] = 'sale';
        $re['currency'] = 'BDT';
        $re['merchantInvoiceNumber'] = $merchantInvoiceNumber;
        $re['mode'] = "0011";
        $re['payerReference'] = $this->payerReference;
        // $re['payerReference'] = '019';
        if($pop->bill_generate == 'no'){
            $re['callbackURL'] = $getwayInfo->callback_url . "?customerid=" . $request->customerid;
        }else{
            $re['callbackURL'] = $this->callbackurl . "?customerid=" . $request->customerid;
        }
        $re['amount'] = $request->amount;

        if($pop->bill_generate == 'no'){
            $url = curl_init("$getwayInfo->base_url/tokenized/checkout/create");
        }else{
            $url = curl_init("$this->base_url/tokenized/checkout/create");
        }

        Log::error(("Bkash Callback URL: {$re['callbackURL']}"));
        Log::error("Payment reference: {$re['payerReference']}");

        // dd($url);

        // $url = curl_init("$this->base_url/tokenized/checkout/create");
        $request_data_json = json_encode($re);

        Log::error($request_data_json);
        if($pop->bill_generate == 'no'){
            $appKey = "x-app-key: $getwayInfo->appkey_publickey";
        }else{
            $appKey = "x-app-key: $this->app_key";
        }

        $header = array(
            'Content-Type:application/json',
            "authorization: $token",
            $appKey,
        );

        // dd($header);

        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);
        // dd($resultdata);
        curl_close($url);

        Log::error("Bkash Create Payment Response: {$resultdata}");

        // Storage::put('createpayment.txt',$resultdata); //this is for store payment request in txt file for debug


        return json_decode($resultdata, true);
    }

    public function checkout(request $request)
    {


        if ($request->paymentID == null) {
            return false;
        }

        if ($request->status == 'cancel') {
            return redirect()->route('bkashCanceled');
        }

        if ($request->status == 'failure') {
            return redirect()->route('bkashFailure');
        }


        Log::error("Bkash payment checkout successful redirect");
        $bkashPayment = BkashPayment::where('paymentID', $request->paymentID)->first();

        if ($bkashPayment == null) {
            $bkashPayment = BkashPayment::create([
                'paymentID' => $request->paymentID,
                'client_id' => $request->customerid,
                'transactionStatus' => 'Pending'
            ]);
        }

        $customer_info =  CustomerFrontController::getClientInfo($request);


        if ($customer_info['clientlist'] != null && $customer_info['clientlist']->id == $request->customerid) {

            if ($bkashPayment->transactionStatus == 'Pending' or $bkashPayment->transactionStatus == 'Initiated') {

                $result = $this->executePayment($request);


                if (in_array($result['statusCode'], $this->error)) {

                    session(['bkashErrorMessage' => $result['statusMessage']]);

                    return redirect()->route('bkashError');
                }

                // $this->queryPayment($request);

                // dd($result);
                if (isset($result) && $result['statusCode'] == '0000') {

                    $bkashPayment = BkashPayment::where('paymentID', $request->paymentID)->first();
                    $bkashPayment->statusCode = $result['statusCode'];
                    $bkashPayment->statusCode = $result['statusCode'];
                    $bkashPayment->payerReference = $result['payerReference'];
                    $bkashPayment->customerMsisdn = $result['customerMsisdn'];
                    $bkashPayment->trxID = $result['trxID'];
                    $bkashPayment->amount = $result['amount'];
                    $bkashPayment->transactionStatus = $result['transactionStatus'];
                    $bkashPayment->paymentExecuteTime = $result['paymentExecuteTime'];
                    $bkashPayment->currency = $result['currency'];
                    $bkashPayment->intent = $result['intent'];
                    $bkashPayment->statusMessage = $result['statusMessage'];
                    $bkashPayment->merchantInvoiceNumber = $result['merchantInvoiceNumber'];
                    $bkashPayment->save();
                } else {
                    $result = $this->queryPayment($request);
                    $bkashPayment = BkashPayment::where('paymentID', $request->paymentID)->first();
                    $bkashPayment->transactionStatus = $result['transactionStatus'];
                    $bkashPayment->statusMessage = $result['statusMessage'];
                    $bkashPayment->save();
                }



                if ($bkashPayment->transactionStatus == 'Completed') {
                    Log::error("Bkash payment checkout successful");
                    if ($customer_info['clientlist']->pop->bill_generate == 'no') {
                        $status =   (new PaymentController)->bkashPaymentProcessReseller($request->paymentID, 'bkashPaymentFromResellerClient');
                    }else{
                        $status =   (new PaymentController)->bkashPaymentProcess($request->paymentID, 'bkashPaymentFromClient');
                    }
                }
            } elseif ($bkashPayment->transactionStatus == 'Completed') {
                if ($customer_info['clientlist']->pop->bill_generate == 'no') {
                    $status =   (new PaymentController)->bkashPaymentProcessReseller($request->paymentID, 'bkashPaymentFromResellerClient');
                }else{
                    $status =   (new PaymentController)->bkashPaymentProcess($request->paymentID, 'bkashPaymentFromClient');
                }
            }

            try{
                if (checkAPI()) {
                    ClientSyncJobForSingle::dispatch($customer_info['clientlist']->id);
                }
            }catch(\Exception $e){

            }


            if ($customer_info['login_check'] == "true") {
                Toastr::success('Payment has been Completed Successfully', 'Success');
                return redirect()->route('customerDashboard');
            } else {
                return redirect()->route('client-open-payment', $customer_info['clientlist']->slug);
            }
        }
    }


    public function executePayment(Request $request)
    {

        // dd($request->all());
        $client = Client::find($request->customerid);
        $pop = Pop::find($client->pop_id);
        $reseller = Reseller::find($pop->reseller_id);

        if($pop->bill_generate == 'no'){
            $getwayInfo = PaymentGetwayCredential::where('reseller_id', $reseller->id)->where('getway_name', 'bkash')->first();
        }

        $paymentID = $request->paymentID;
        $token = getTokenForBkash();



        $request_body = array(
            'paymentID' => $paymentID
        );
        $url = curl_init("$this->base_url/tokenized/checkout/execute");

        $request_body_json = json_encode($request_body);

        if($pop->bill_generate == 'no'){
            $appKey = "x-app-key: $getwayInfo->appkey_publickey";
        }else{
            $appKey = "x-app-key: $this->app_key";
        }

        Log::error("Payment paymentID: {$paymentID}");


        $header = array(
            'Content-Type:application/json',
            'Authorization:' . $token,
            $appKey,
        );
        curl_setopt($url, CURLOPT_HTTPHEADER, $header);
        curl_setopt($url, CURLOPT_CUSTOMREQUEST, "POST");
        curl_setopt($url, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($url, CURLOPT_POSTFIELDS, $request_body_json);
        curl_setopt($url, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($url, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
        $resultdata = curl_exec($url);

        curl_close($url);

        Log::error("Bkash payment execute response: {$resultdata}");

        // Storage::put('executepayment.txt',$resultdata); //this is for store execute payment response in txt file for debug


        return json_decode($resultdata, true);
    }






    public function queryPayment(Request $request)
    {
        $client = Client::find($request->customerid);
        $pop = Pop::find($client->pop_id);
        $reseller = Reseller::find($pop->reseller_id);

        if($pop->bill_generate == 'no'){
            $getwayInfo = PaymentGetwayCredential::where('reseller_id', $reseller->id)->where('getway_name', 'bkash')->first();
        }

        $paymentID = $request->paymentID;
        if($pop->bill_generate == 'no'){
            $token = $this->generateToken($pop, $getwayInfo);
        }else{
            $token = $this->generateToken();
        }

        $request_body = array(
            'paymentID' => $paymentID
        );

        $url = curl_init("$this->base_url/tokenized/checkout/payment/status");

        $request_body_json = json_encode($request_body);

        if($pop->bill_generate == 'no'){
            $appKey = "x-app-key: $getwayInfo->appkey_publickey";
        }else{
            $appKey = "x-app-key: $this->app_key";
        }

        Log::error("Bkash paymentID for status/ : {$paymentID}");


        $header = array(
            'Content-Type:application/json',
            'Authorization:' . $token,
            $appKey,
        );
        curl_setopt($url, CURLOPT_HTTPHEADER, $header);
        curl_setopt($url, CURLOPT_CUSTOMREQUEST, "POST");
        curl_setopt($url, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($url, CURLOPT_POSTFIELDS, $request_body_json);
        curl_setopt($url, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($url, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
        $resultdata = curl_exec($url);

        Log::error("Bkash payment staus: {$resultdata}");

        curl_close($url);
        //   Storage::put('querypayment.txt',$resultdata);  //this is for store query payment response in txt file for debug
        return json_decode($resultdata, true);
    }


    public function searchTranxection($transectin)
    {
        $token = getTokenForBkash();

        $request_body = array(
            'trxID' => $transectin
        );
        $url = curl_init("$this->base_url/tokenized/checkout/general/searchTransaction");

        $request_body_json = json_encode($request_body);

        $appKey = "x-app-key: $this->app_key";

        Log::error("Bkash Search Transaction Request: trxID {$transectin}");

        $header = array(
            'Content-Type:application/json',
            'Authorization:' . $token,
            $appKey,
        );
        curl_setopt($url, CURLOPT_HTTPHEADER, $header);
        curl_setopt($url, CURLOPT_CUSTOMREQUEST, "POST");
        curl_setopt($url, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($url, CURLOPT_POSTFIELDS, $request_body_json);
        curl_setopt($url, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($url, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
        $resultdata = curl_exec($url);

        Log::error("Bkash Search Transaction Response: {$resultdata}");

        curl_close($url);

        // Storage::put('searchtransaction.txt',$resultdata); //this is for store execute payment response in txt file for debug
    }

    public function bkashSuccess(Request $request)
    {
        // IF PAYMENT SUCCESS THEN YOU CAN APPLY YOUR CONDITION HERE
        if ('Noman' == 'success') {


            // THEN YOU CAN REDIRECT TO YOUR ROUTE

            Session::flash('successMsg', 'Payment has been Completed Successfully');

            return response()->json(['status' => true]);
        }

        Session::flash('error', 'Noman Error Message');

        return response()->json(['status' => false]);
    }
}
