<?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\PgwResponseLog;
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 Brian2694\Toastr\Toastr as ToastrToastr;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Http;

class NagadPoprechargeController extends Controller
{
    private $nagad_merchant_id;
    private $nagad_merchant_number;
    private $nagad_public_key;
    private $nagad_private_key;
    private $timezone;
    private $nagad_pop_recharge_callbackurl;
    private $baseUrl;


    public function __construct()
    {
        $this->baseUrl                          = config('app.nagad_base_url');
        $this->nagad_merchant_id                = config('app.nagad_merchant_id');
        $this->nagad_merchant_number            = config('app.nagad_merchant_number');
        $this->nagad_public_key                 = config('app.nagad_public_key');
        $this->nagad_private_key                = config('app.nagad_private_key');
        $this->timezone                         = config('app.timezone');
        $this->nagad_pop_recharge_callbackurl   = config('app.nagad_pop_recharge_callbackurl');

        // if (url('/') == 'http://radius-circle.test') {
        //     $this->nagad_pop_recharge_callbackurl      = 'https://demo.yetfix.net/admin/nagad-pop-recharge-callback';
        // } else {
        //     $this->nagad_pop_recharge_callbackurl      = url('/') . '/admin/nagad-pop-recharge-callback';
        // }


    }
    function getRandomString($length = 45)
    {
        $characters       = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $charactersLength = strlen($characters);
        $randomString     = '';
        for ($i = 0; $i < $length; $i++) {
            $randomString .= $characters[rand(0, $charactersLength - 1)];
        }
        return $randomString;
    }

    function getSensitiveData(string $invoice)
    {
        return [
            'merchantId' => $this->nagad_merchant_id,
            'datetime'   => Carbon::now($this->timezone)->format("YmdHis"),
            'orderId'    => $invoice,
            'challenge'  => $this->getRandomString()
        ];
    }

    function headers()
    {
        return [
            "Content-Type"     => "application/json",
            "X-KM-IP-V4"       => request()->ip(),
            "X-KM-Api-Version" => "v-0.2.0",
            "X-KM-Client-Type" => "PC_WEB"
        ];
    }

    function encryptWithPublicKey(string $data)
    {
        $publicKey   = "-----BEGIN PUBLIC KEY-----\n" . $this->nagad_public_key . "\n-----END PUBLIC KEY-----";
        $keyResource = openssl_get_publickey($publicKey);
        $status      = openssl_public_encrypt($data, $cryptoText, $keyResource);
        if ($status) {
            return base64_encode($cryptoText);
        }
    }

    function signatureGenerate(string $data)
    {
        $private_key = "-----BEGIN RSA PRIVATE KEY-----\n" . $this->nagad_private_key . "\n-----END RSA PRIVATE KEY-----";
        $status      = openssl_sign($data, $signature, $private_key, OPENSSL_ALGO_SHA256);
        if ($status) {
            return base64_encode($signature);
        }

    }

    function decryptDataPrivateKey(string $data)
    {
        $private_key = "-----BEGIN RSA PRIVATE KEY-----\n" . $this->nagad_private_key . "\n-----END RSA PRIVATE KEY-----";
        openssl_private_decrypt(base64_decode($data), $plain_text, $private_key);
        return $plain_text;
    }

    public function createPayment(Request $request)
    {

        $amount = $request->amount;
        $OrderId = now()->timestamp . $request->pop_id;

        $baseUrl       = $this->baseUrl . "check-out/initialize/" . $this->nagad_merchant_id . "/{$OrderId}";
        $sensitiveData = $this->getSensitiveData($OrderId);
        $body          = [
            "accountNumber" => $this->nagad_merchant_number,
            "dateTime"      => Carbon::now()->timezone($this->timezone)->format('YmdHis'),
            "sensitiveData" => $this->encryptWithPublicKey(json_encode($sensitiveData)),
            'signature'     => $this->signatureGenerate(json_encode($sensitiveData)),
        ];

        $response = Http::withHeaders($this->headers())->post($baseUrl, $body);
        $initialize = json_decode($response->body());

        if(!isset($initialize->sensitiveData) && !isset($initialize->signature)){
            $data = [
                'message' => $initialize->message,
                'status' => 'error'
            ];
            return $data;
        }

        if ($initialize->sensitiveData && $initialize->signature) {
            $decryptData        = json_decode($this->decryptDataPrivateKey($initialize->sensitiveData));
            $url                = $this->baseUrl . "/check-out/complete/" . $decryptData->paymentReferenceId;
            $sensitiveOrderData = [
                'merchantId'   => $this->nagad_merchant_id,
                'orderId'      => $OrderId,
                'currencyCode' => '050',
                'amount'       => $amount,
                'challenge'    => $decryptData->challenge
            ];

            $response = Http::withHeaders($this->headers())
                ->post($url, [
                    'sensitiveData'       => $this->encryptWithPublicKey(json_encode($sensitiveOrderData)),
                    'signature'           => $this->signatureGenerate(json_encode($sensitiveOrderData)),
                    'merchantCallbackURL' => config("app.nagad_callbackurl")."/admin/nagad-pop-recharge-callback"."?pop_id=".$request->pop_id."&",
                ]);

                try{
                    $result = json_decode($response->body());
                    $url = $result->callBackUrl;
                    $split_url = explode('check-out/', $url);

                    $pgw_responser_log = new PgwResponseLog();
                    $pgw_responser_log->response = $response->body();
                    $pgw_responser_log->payment_for = 'Pop';
                    $pgw_responser_log->payment_method = 'Nagad';
                    $pgw_responser_log->source = 'Payment_initiate';
                    $pgw_responser_log->user_id = $request->pop_id;
                    $pgw_responser_log->payment_ref_id = $split_url[1];
                    $pgw_responser_log->added_by = auth()->user()->id;
                    $pgw_responser_log->save();
                }catch(\Exception $e){

                }

            session()->put('nagad_pop_recharge_pop_id', $request->pop_id);
            $result = json_decode($response->body());

            if (isset($result->reason)) {
                $data = [
                    'message' => $result->reason,
                    'status' => 'error'
                ];
                return $data;
            }
            $data = [
                        'message' => $result->callBackUrl,
                        'status' => 'success'
                    ];
            return $data;
        }

    }

    public function nagadPopRechargeCallback(Request $request)
    {
        // dd($request->all());

        $pgw_responser_log = new PgwResponseLog();
        $pgw_responser_log->response = json_encode($request->all());
        $pgw_responser_log->payment_ref_id = $request->payment_ref_id;
        $pgw_responser_log->payment_for = 'Pop';
        $pgw_responser_log->payment_method = 'Nagad';
        $pgw_responser_log->source = 'Call_back_url';
        $pgw_responser_log->user_id = $request->pop_id;
        $pgw_responser_log->added_by = auth()->user()->id;
        $pgw_responser_log->save();


        $url      = config('app.nagad_base_url') . "verify/payment/{$request->payment_ref_id}";
        $response = Http::withHeaders($this->headers())->get($url);


        $response_payment = json_decode($response->body(), true);

        if($response_payment['status'] == "Success"){
            DB::beginTransaction();
            try {

                $paid_amount = $response_payment['amount'];
                $gateway_transaction_id = $response_payment['issuerPaymentRefNo'];
                // new code
                $pop_online_recharge = SubResellerRechargeReport::where('payment_gateway_transaction_id', $gateway_transaction_id)->count();
                $pop_id = session()->get('nagad_pop_recharge_pop_id');

                if($pop_online_recharge == 0 && $pop_id == $request->pop_id){

                    $user_id = User::onlinePaymentUser('Nagad-Online')->id;

                    $pop = Pop::find($request->pop_id);

                    $paid_amount = (new PopController)->getPaidAmountForOnlinePopRecharge($pop,'Nagad-Online',$paid_amount);

                    $charge_remark = $this->getChargeRemark($pop, 'Nagad-Online');

                    $remark = 'Nagad-Online Recharge by ' . auth()->user()->email . ' Amount : ' . $paid_amount . " ".$charge_remark;

                    $pop_recharge_status = Balance::balanceUpdate('pop', $pop->id, $paid_amount, $remark, $paid_amount, $user_id, 'online', 'Nagad', $gateway_transaction_id, $request->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('Something is wrong' . $pop_recharge_status, 'error');
                        return redirect()->back();
                    }


                    $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, 'Nagad', 'Nagad', $user_id);
                    }

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

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

                    $pgw_responser_log->status = 'Success';
                    $pgw_responser_log->save();

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

                        $sms_setting = json_decode(getSmsMessage()->where('tamplate_name', 'reseller_balance_recharge_sms')->first()->tamplate_body, true);
                        if ($sms_setting["sendsms"] == "Yes") {
                            try{
                                (new ResellerAccountRechargeSms())->sendSms($reseller->id, $request->amount, $totalRecharge);
                            }catch(\Exception $e){
                            }
                        }

                        Toastr::success('Nagad Recharge Successful', 'Recharge Successful');
                        return redirect()->route('onlinePopRecharge', $request->pop_id);
                    } else {
                        Toastr::error('Nagad Recharge UnSuccessful', 'Recharge Failed');
                        return redirect()->route('onlinePopRecharge', $request->pop_id);
                    }


                }else {
                    $pgw_responser_log->status = 'Failed';
                    $pgw_responser_log->error_massage = "pop id not matching";
                    $pgw_responser_log->save();
                    Toastr::error('Nagad Recharge UnSuccessful', 'Recharge Failed');
                    return redirect()->route('onlinePopRecharge', $request->pop_id);
                }

                // end new code
            } catch (\Throwable $th) {
                $pgw_responser_log->status = 'Failed';
                $pgw_responser_log->error_massage = $th->getMessage();
                $pgw_responser_log->save();
                dd($th);
            }
        }else{
            $pgw_responser_log->status = 'Failed';
            $pgw_responser_log->error_massage = $response_payment['message'];
            $pgw_responser_log->save();

            Toastr::error('Nagad Recharge UnSuccessful', 'Recharge Failed');
            return redirect()->route('onlinePopRecharge', $request->pop_id);
        }
        $pgw_responser_log->status = 'Failed';
        $pgw_responser_log->error_massage = $response_payment['status'];
        $pgw_responser_log->save();

        Toastr::error('Nagad Recharge UnSuccessful', 'Recharge Failed');
        return redirect()->route('onlinePopRecharge', $request->pop_id);
    }


    public function getChargeRemark($pop, $payment_method)
    {
        $charges = json_decode($pop->payment_charges,true);
        $remark = '';
        if($charges == null){
            $remark = 'Online Charges: ' . 0 . '%';
        }elseif(isset($charges['bkash_charges']) && $charges['bkash_charges'] > 0 && $payment_method == 'Bkash-Online'){
            $remark = 'Online Charges: ' . $charges['bkash_charges'] . '%';
        }elseif(isset($charges['upay_charges']) && $charges['upay_charges'] > 0 && $payment_method == 'Upay-Online'){
            $remark = 'Online Charges: ' . $charges['upay_charges'] . '%';
        }elseif(isset($charges['rocket_charges']) && $charges['rocket_charges'] > 0 && $payment_method == 'Rocket-Online'){
            $remark = 'Online Charges: ' . $charges['rocket_charges'] . '%';
        }elseif(isset($charges['nagad_charges']) && $charges['nagad_charges'] > 0 && $payment_method == 'Nagad-Online'){
            $remark = 'Online Charges: ' . $charges['nagad_charges'] . '%';
        }

       return $remark;
    }

    public function onlinePopRechargeRedirect($id)
    {

        // return redirect()->route('onlinePopRecharge', $id);

        // echo "<script>alert('Recharge Successful');</script>";
        //redirect
        echo "<script>window.location.href = '".route('onlinePopRecharge', $id)."';</script>";
        // echo "<scritp>window.location.href = "'.route('onlinePopRecharge', $id).'";</script>';

        // return redirect()->to(route('onlinePopRecharge', $id));
    }
}
