<?php

namespace App\Http\Controllers\OnlinePopRecharge;

use App\Classes\Notification;
use App\Classes\SMS\ResellerAccountRechargeSms;
use App\Http\Controllers\Controller;
use App\Http\Controllers\PopController;
use App\Models\Balance;
use App\Models\Pop;
use App\Models\Reseller;
use App\Models\ResellerRechargeReport;
use App\Models\SubResellerRechargeReport;
use App\Models\User;
use App\Models\UserAccounting;
use Brian2694\Toastr\Facades\Toastr;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

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


    public function __construct()
    {
        $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');
        if (url('/') == 'http://radius-circle.test') {
            $this->callbackurl      = 'https://demo.yetfix.net/admin/bkashPopRechargeCallback';
        } else {
            $this->callbackurl      = url('/') . '/admin/bkashPopRechargeCallback';
        }

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



    public function generateToken()
    {
        session()->forget('bkash_token_pop_recharge');

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

        $post_token = json_encode($post_token);
        $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);
        session()->put('bkash_token_pop_recharge', $response['id_token']);

        return $response['id_token'];
    }



    public function createPayment(Request $request)
    {
        $token = getTokenForBkash();
        // dd($token);
        $re['intent'] = 'sale';
        $re['currency'] = 'BDT';
        $re['merchantInvoiceNumber'] = now()->timestamp . $request->pop_id;
        $re['mode'] = "0011";
        $re['payerReference'] = $this->payerReference;
        $re['callbackURL'] = $this->callbackurl . "?merchantInvoiceNumber=" . $re['merchantInvoiceNumber'] . "&pop_id=" . $request->pop_id;
        $re['amount'] = $request->amount;


        // dd($re['callbackURL']);

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

        // dd($request_data_json);

        $header = array(
            'Content-Type:application/json',
            "authorization: $token",
            "x-app-key: $this->app_key"
        );

        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);

        //sett pop id in session
        session()->put('bkash_pop_recharge_pop_id', $request->pop_id);

        return json_decode($resultdata, true);
    }

    public function bkashPopRechargeCallback(Request $request, $status = 'error')
    {

        if ($request->paymentID == null || $request->status == 'cancel' || $request->status == 'failure') {
            Toastr::error('Recharge UnSuccessfull', 'Recharge Faild');
            return redirect()->route('onlinePopRecharge', $request->pop_id);
        }

        // dd($request->all());

        DB::beginTransaction();

        try {
            $recharge_report = SubResellerRechargeReport::where('payment_gateway_transaction_id', $request->paymentID)->count();
            $pop_id = session()->get('bkash_pop_recharge_pop_id');


            if ($request->status == 'success' && $recharge_report == 0 && $pop_id == $request->pop_id) {

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

                if(in_array($result['statusCode'],$this->error)){
                    Toastr::error($result['statusMessage'],'Recharge Faild');
                    return redirect()->route('onlinePopRecharge', $request->pop_id);
                }

                if ($result['statusCode'] == 2062) {
                    $result = $this->queryPayment($request);
                }

                if ($result['transactionStatus'] == 'Completed') {

                    $paid_amount = $result['amount'];
                    $gateway_transaction_id = $result['trxID'];
                    $payment_method = 'Bkash-Online';
                    $user_id = User::onlinePaymentUser($payment_method)->id;

                    // pop online recharge report
                    $pop = Pop::find($request->pop_id);

                    $paid_amount = (new PopController())->getPaidAmountForOnlinePopRecharge($pop,$payment_method,$paid_amount);
                    $remark = 'Bkash Online Recharge by ' . auth()->user()->email . ' Amount : ' . $paid_amount;
                    $pop_recharge_status = Balance::balanceUpdate('pop', $pop->id, $paid_amount, $remark, $paid_amount, $user_id, 'online', $payment_method, $gateway_transaction_id, $gateway_transaction_id);
                    clearCache('pop');

                    if ($pop_recharge_status === 'success') {

                        (new Notification)->notify('Pop Recharge by by ' . auth()->user()->name . ' Amount : ' . $request->amount . ' Remark: ' . $remark);

                    } else {
                        Toastr::error('Recharge UnSuccessfull', 'Recharge UnSuccessfull or already Recharged or duplicate transaction');
                    }


                    //reseller online recharge report
                    $reseller = Reseller::find($pop->reseller_id);

                    if ($reseller->reseller_type == 'other') {
                        $actions = 'Reseller payment received from ' . $reseller->name . ' ' . $reseller->contact;
                        UserAccounting::userAcStore($paid_amount, $actions, null, $payment_method, $payment_method, $user_id);
                    }

                    $status = Balance::balanceUpdate('reseller', $reseller->id, $paid_amount, $remark, $paid_amount, $user_id, 'online', $payment_method, $gateway_transaction_id, $request->transaction_id);
                    clearCache('reseller');

                    $totalRecharge = ResellerRechargeReport::with('reseller', 'user', 'balance')->where('reseller_id', $reseller->id)->sum('amount');

                    if ($status === 'success') {

                        $sms_setting = json_decode(getSmsMessage()->where('tamplate_name', 'reseller_balance_recharge_sms')->first()->tamplate_body, true);

                        if ($sms_setting["sendsms"] == "Yes") {
                            (new ResellerAccountRechargeSms())->sendSms($reseller->id, $request->amount, $totalRecharge);
                        }

                        Toastr::success('Recharge Successfull', 'Recharge Successfull');
                    } else {
                        Toastr::error('Recharge UnSuccessfull', 'Recharge UnSuccessfull or already Recharged or duplicate transaction');
                    }
                }
            }

            DB::commit();



            if ($status == 'error') {
                Toastr::error('Recharge UnSuccessfull', 'Recharge UnSuccessfull or already Recharged or duplicate transaction');
            } else {
                Toastr::success('Recharge Successfull', 'Recharge Successfull');
            }

            return redirect()->route('onlinePopRecharge', $request->pop_id);
        } catch (\Throwable $th) {
            dd($th);
        }
    }


    public function executePayment(Request $request)
    {
        $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);

        $header = array(
            'Content-Type:application/json',
            'Authorization:' . $token,
            "x-app-key:$this->app_key"
        );
        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);

        //   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)
    {
        $paymentID = $request->paymentID;
        $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);

        $header = array(
            'Content-Type:application/json',
            'Authorization:' . $token,
            "x-app-key:$this->app_key"
        );
        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);
        //   Storage::put('querypayment.txt',$resultdata);  //this is for store query payment response in txt file for debug
        return json_decode($resultdata, true);
    }
}
