<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Customer\CustomerFrontController;
use App\Jobs\ClientSyncJobForSingle;
use App\Models\PgwResponseLog;
use App\Models\Setting;
use Brian2694\Toastr\Facades\Toastr;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Http;


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' => config("app.nagad_merchant_id"),
        'datetime'   => Carbon::now(config("app.timezone"))->format("YmdHis"),
        'orderId'    => $invoice,
        'challenge'  => 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" . config('app.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" . config("app.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" . config('app.nagad_private_key') . "\n-----END RSA PRIVATE KEY-----";
    openssl_private_decrypt(base64_decode($data), $plain_text, $private_key);
    return $plain_text;
}



class NagadCheckOutCustomerPaymentController extends Controller
{
    public function nagadPaymenToken(Request $request)
    {
        $host = parse_url(url('/'), PHP_URL_HOST);
        $first_three_char = substr($host, 0, 3);


        $amount = $request->amount;
        $OrderId = $first_three_char . strtotime("now") . rand(1000, 10000);

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

        $response = Http::withHeaders(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(decryptDataPrivateKey($initialize->sensitiveData));
            $url                = config('app.nagad_base_url') . "/check-out/complete/" . $decryptData->paymentReferenceId;
            $sensitiveOrderData = [
                'merchantId'   => config("app.nagad_merchant_id"),
                'orderId'      => $OrderId,
                'currencyCode' => '050',
                'amount'       => $amount,
                'challenge'    => $decryptData->challenge
            ];

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

            $result = json_decode($response->body());

            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 = 'Client';
                $pgw_responser_log->payment_method = 'Nagad';
                $pgw_responser_log->source = 'Payment_initiate';
                $pgw_responser_log->user_id = $request->customer_id;
                $pgw_responser_log->payment_ref_id = $split_url[1];
                $pgw_responser_log->added_by = null;
                $pgw_responser_log->save();
            } catch (\Exception $e) {
            }

            session(['nagad_recharge_amount' => $amount]);

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


            $data = [
                'message' => $result->callBackUrl,
                'status' => 'success'
            ];
            return $data;
        }
    }


    public function nagadPaymenCallback(Request $request)
    {

        $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 = 'Client';
        $pgw_responser_log->payment_method = 'Nagad';
        $pgw_responser_log->source = 'Call_back_url';
        $pgw_responser_log->user_id = $request->customer_id;
        $pgw_responser_log->added_by = null;
        $pgw_responser_log->save();

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


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

        $pgw_responser_log->verify_response = $response->body();
        $pgw_responser_log->save();



        if ($response_payment['status'] == "Success" && $response_payment['amount'] == session('nagad_recharge_amount') && $response_payment['merchantId'] == config("app.nagad_merchant_id")) {

            try {
                (new PaymentController)->NagadClientCheckOutPaymentProcess(
                    $response_payment['amount'],
                    $request->customer_id,
                    $response_payment['issuerPaymentRefNo'],
                    $response_payment['clientMobileNo'],
                    $response_payment['paymentRefId'],
                    $response_payment['issuerPaymentDateTime'],
                );


            } catch (\Exception $e) {
                DB::rollback();
                Toastr::error('Nagad Payment is not Successful');
                return redirect()->route('customerDashboard');
            }

            $request->merge(['customerid' => $request->customer_id]);
            $customer_info =  CustomerFrontController::getClientInfo($request);

            if (checkAPI()) {
                ClientSyncJobForSingle::dispatch($request->customer_id);
            }

            // Toastr::success('Nagad Payment is Successful');
            // return redirect()->route('customerDashboard');

            if ($customer_info['login_check'] == "true") {
                Toastr::success('Nagad Payment is Successful', 'Success');
                return redirect()->route('customerDashboard');
            } else {
                Toastr::success('Nagad Payment is Successful');
                return redirect()->route('client-open-payment', $customer_info['clientlist']->slug);
            }
        } else {
            Toastr::error('Nagad Payment is not Successful');
            return redirect()->route('customerDashboard');
        }
        Toastr::error('Nagad Payment is not Successful');
        return redirect()->route('customerDashboard');

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

    }

    public function checkResponse($payment_ref_id)
    {
         $url      = config('app.nagad_base_url') . "verify/payment/{$payment_ref_id}";
        $response = Http::withHeaders(headers())->get($url);
        dd($response->body());
    }
}
