<?php

namespace App\Http\Controllers\Api;

use App\Classes\AuthUser;
use App\Classes\BillgenerateUpdate;
use Carbon\Carbon;
use App\Models\Client;
use App\Models\Billpayment;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Hash;
use App\Http\Controllers\PaymentController;
use App\Http\Controllers\PaymentDeleteController;
use App\Jobs\BillGenerateUpdateJob;
use App\Models\PayBillLog;
use App\Models\ResellerClientBillPayment;
use App\Services\ExpirationService;
use App\Services\ResellerClientOlineRechargeService;
use Exception;
use Illuminate\Support\Facades\Log;

class BillPaymentController extends Controller
{
    //

    public function checkAuth($request)
    {
        if ($request->app_key == config('app.nagad_app') && $request->secret == config('app.nagad_secret')) {
            return true;
        } elseif ($request->app_key == config('app.bkash_app') && $request->secret == config('app.bkash_secret')) {
            return true;
        } elseif ($request->app_key == config('payment.UPAY_PAYBILL_APP_KEY') && $request->secret == config('payment.UPAY_PAYBILL_SECRET')) {
            return true;
        } elseif ($request->app_key == config('app.rocket_app_key') && $request->secret == config('app.rocket_app_secret')) {
            return true;
        } else {
            return false;
        }
    }

    public function checkBill(Request $request)
    {
        $response = null;

        $payBillLog = new PayBillLog();
        $payBillLog->payment_method = $request->app_key;
        $payBillLog->request = json_encode($request->all());
        $payBillLog->client_id = $request->customer_id;


        Log::error($request->customer_id. " id found");

        if ($this->checkAuth($request)) {



                $client = Client::with('pop', 'clientsinfo', 'customerAccount', 'packages')->where('id', (int)$request->customer_id)->withTrashed()->first();


                if (checkSettings('prepaid-bill-by-client-username') == 'enable'){
                    $client = Client::with('pop', 'clientsinfo', 'customerAccount', 'packages')->where('userid', $request->customer_id)->withTrashed()->first();
                }

                if (checkSettings('prepaid-bill-by-client-code') == 'enable'){
                    $customerId = (string)$request->customer_id;

                    $client = Client::with('pop', 'clientsinfo', 'customerAccount', 'packages')->where('customer_code', $customerId)->withTrashed()->first();
                }



                if ($client && $client->pop->bill_generate == 'yes') {

                    $token = Hash::make(Str::random(60) . now()->timestamp . $client->id);

                    $client->payment_token = $token;
                    $client->app_key_type = $request->app_key;
                    $client->save();

                    if (getDueAmount($client) > 0) {

                        $response = [
                            'name' => preg_replace('/[^a-zA-Z0-9\s]/', '', (string)$client->clientsinfo->clients_name),
                            'contact' => $client->clientsinfo->contact_no,
                            'bill_amount' => getDueAmount($client),
                            'ErrorCode' => 200,
                            'ErrorMessage' => 'Success'
                        ];
                    } else {
                        $response = [
                            'name' => preg_replace('/[^a-zA-Z0-9\s]/', '', (string)$client->clientsinfo->clients_name),
                            'contact' => $client->clientsinfo->contact_no,
                            'bill_amount' => number_format(0, 2),
                            'ErrorCode' => 436,
                            'ErrorMessage' => 'Bill Already Paid',
                        ];
                    }
                } else {

                    if($client && globalPermission('ResellerClientOnlineRecharge')){

                        $getDueAmount = getResellerClientPaymentAmount($client);

                        $response = [
                            'name' => preg_replace('/[^a-zA-Z0-9\s]/', '', (string)$client->clientsinfo->clients_name),
                            'contact' => $client->clientsinfo->contact_no,
                            'bill_amount' => $getDueAmount,
                            'ErrorCode' => 200,
                            'ErrorMessage' => 'Success'
                        ];
                    }else{

                        $response = [
                            'ErrorCode' => 404,
                            'ErrorMessage' => 'Customer Id invalid',
                        ];
                    }
                }

        } else {
            $response = [
                'ErrorCode' => 401,
                'ErrorMessage' => 'Unauthorized'
            ];
        }

        $payBillLog->response = json_encode($response);
        $payBillLog->request_url = "check_bill";
        $payBillLog->save();

        return response()->json($response, $response['ErrorCode']);
    }

    public function payment(Request $request)
    {
        Log::error("Paybill start ");
        $response = null;
        $error_message = null;

        $payBillLog = new PayBillLog();
        $payBillLog->payment_method = $request->app_key;
        $payBillLog->request = json_encode($request->all());
        $payBillLog->client_id = $request->customer_id;
        $payBillLog->trxn_id = $request->trx_id;
        $payBillLog->request_url = "payment";

        if ($this->checkAuth($request)) {
            $client = Client::with('pop', 'clientsinfo', 'customerAccount')
                ->where('id', $request->customer_id)->withTrashed()
                ->first();

            if (checkSettings('prepaid-bill-by-client-username') == 'enable'){
                $client = Client::with('pop', 'clientsinfo', 'customerAccount', 'packages')->where('userid', $request->customer_id)->withTrashed()->first();
            }

            if (checkSettings('prepaid-bill-by-client-code') == 'enable'){
                $customerId = (string)$request->customer_id;
                $client = Client::with('pop', 'clientsinfo', 'customerAccount', 'packages')->where('customer_code', $customerId)->withTrashed()->first();
            }

            if ($client && $client->pop->bill_generate == 'yes') {

                $bill = getDueAmount($client);

                if ($bill <= 0) {
                    $response = [
                        'ErrorCode' => 436,
                        'ErrorMessage' => 'Bill Already Paid',
                    ];
                    $error_message = 'Bill Already Paid';
                } else {

                    if ($bill == $request->amount) {
                        Log::error("Paybill start ". $client->id);
                        $result = (new PaymentController)->billPayPayment($request->trx_id, $client->id, $request->amount, $request->mobile_no, $request->datetime, $request->app_key, 'billpay');

                        if ($result['status'] == 'success') {

                            if($client->deleted_at != null){
                                $client->restore();
                            }

                            $response = [
                                'result' => $result['status'],
                                'paymentAmount' => number_format($request->amount,2),
                                'ErrorCode' => 200,
                                'ErrorMessage' => 'Success'
                            ];
                        } else {
                            $response = [
                                'ErrorCode' => 409,
                                'ErrorMessage' => $result['status']
                            ];

                            $error_message = $result['message'];
                        }
                    } else {

                        $response = [
                            'result' => 'Amount mismatch',
                            'paymentAmount' => $request->amount,
                            'ErrorCode' => 435,
                            'ErrorMessage' => 'amount mismatch'
                        ];

                        $error_message = 'Amount mismatch';
                    }
                }

            } else {
                if($client && globalPermission('ResellerClientOnlineRecharge')){

                    $bill = getResellerClientPaymentAmount($client);


                    if ($bill <= 0) {
                        $response = [
                            'ErrorCode' => 436,
                            'ErrorMessage' => 'Bill Already Paid',
                        ];
                        $error_message = 'Bill Already Paid';
                    } else {

                        if ($bill == $request->amount) {

                            $user = (new AuthUser)->check('user@' . $request->app_key . '.com', $request->app_key);
                            $result = (new ResellerClientOlineRechargeService)->resellerClientPayBillPaymentProcess($client->id,$request->amount,$request->trx_id,$user->id,"Bkash-Pay-Bill");
                            // dd($result);
                            if ($result['status'] == 'success') {
                                $response = [
                                    'result' => $result['status'],
                                    'paymentAmount' => number_format($request->amount,2),
                                    'ErrorCode' => 200,
                                    'ErrorMessage' => 'Success'
                                ];
                            } else {
                                $response = [
                                    'ErrorCode' => 409,
                                    'ErrorMessage' => $result['status']
                                ];

                                $error_message = $result['message'];
                            }
                        } else {

                            $response = [
                                'result' => 'Amount mismatch',
                                'paymentAmount' => $request->amount,
                                'ErrorCode' => 435,
                                'ErrorMessage' => 'amount mismatch'
                            ];

                            $error_message = 'Amount mismatch';
                        }
                    }

                }else{

                    $response = [
                        'ErrorCode' => 404,
                        'ErrorMessage' => 'Customer Id not found'
                    ];
                    $error_message = 'Customer Id not found';
                }
            }
        } else {
            $response = [
                'ErrorCode' => 400,
                'ErrorMessage' => 'Bad Request'
            ];

            $error_message = 'Bad Request';
        }
        $payBillLog->response = json_encode($response);
        $payBillLog->error_message = $error_message;
        $payBillLog->save();

        if(globalPermission('RadiusExpiration')){
            try{
                (new ExpirationService())->handleExpiration($client->userid,$client->expire_date,$client->payment_dadeline,$client->pop->experity_check);
            }catch(\Exception $exce){

            }
        }


        return response()->json($response, $response['ErrorCode']);
    }


    public function search(Request $request)
    {
        $response = null;
        $error_message = null;

        $payBillLog = new PayBillLog();
        $payBillLog->payment_method = $request->app_key;
        $payBillLog->request = json_encode($request->all());
        $payBillLog->client_id = $request->customer_id;
        $payBillLog->trxn_id = $request->trx_id;
        $payBillLog->request_url = "search";

        if ($this->checkAuth($request)) {

            $payment = Billpayment::with('clients', 'clientsinfo')
                ->where('money_receipt_number', $request->app_key . '_' . $request->trx_id)
                ->where('trx_id', $request->trx_id)
                ->first();


            if ($payment) {

                $customer_id = strval($payment->clients->id);

                if (checkSettings('prepaid-bill-by-client-username') == 'enable'){
                    $customer_id = strval($payment->clients->userid);

                }

                if (checkSettings('prepaid-bill-by-client-code') == 'enable'){
                    $customer_id = strval($payment->clients->customer_code);
                }


                $data = [
                    'name' =>  preg_replace('/[^a-zA-Z0-9\s]/', '', (string)$payment->clientsinfo->clients_name),
                    'customer_id' => $customer_id,
                    'paid_amount' => $payment->paid_amount,
                    'trxId' => $payment->trx_id,
                    'datetime' => $payment->paymentCreateTime,
                    'ErrorCode' => 200,
                    'ErrorMessage' => 'Success'
                ];

                $response = $data;

            } else {
                if (globalPermission('ResellerClientOnlineRecharge')) {
                    $resellerClientOnlineRecharge = ResellerClientBillPayment::with('client.clientsinfo')
                        ->where('trx_id', $request->trx_id)
                        ->first();

                    if ($resellerClientOnlineRecharge) {

                        $customer_id_info = $resellerClientOnlineRecharge->client->id;

                        $response = [
                            'name' => preg_replace('/[^a-zA-Z0-9\s]/', '', (string)($resellerClientOnlineRecharge->client->clientsinfo->clients_name ?? "")),
                            'customer_id' => $customer_id_info,
                            'paid_amount' => $resellerClientOnlineRecharge->amount,
                            'trxId' => $resellerClientOnlineRecharge->trx_id,
                            'datetime' => Carbon::parse($resellerClientOnlineRecharge->created_at)->format('Y-m-d H:i:s'),
                            'ErrorCode' => 200,
                            'ErrorMessage' => 'Success',
                        ];
                    } else {
                        // Response for when no record is found
                        $response = [
                            'ErrorCode' => 404,
                            'ErrorMessage' => 'Not Found',
                        ];
                        $error_message = 'Not Found';
                    }
                } else {
                    // Response when the user lacks necessary permissions
                    $response = [
                        'ErrorCode' => 404,
                        'ErrorMessage' => 'Not Found',
                    ];
                    $error_message = 'Not Found';
                }
            }
        } else {
            $response = [
                'ErrorCode' => 401,
                'ErrorMessage' => 'Unauthorized'
            ];

            $error_message = 'Unauthorized';
            // return response()->json([
            //     'ErrorCode' => 401,
            //     'ErrorMessage' => 'Unauthorized'
            // ], 401);
        }

        $payBillLog->response = json_encode($response);
        $payBillLog->error_message = $error_message;
        $payBillLog->save();

        return response()->json($response, $response['ErrorCode']);
    }

    public function delete(Request $request)
    {

        if ($this->checkAuth($request)) {

            $payment = Billpayment::where('money_receipt_number', $request->app_key . '_' . $request->trx_id)->where('trx_id', '=', $request->trx_id)->first();

            if ($payment) {
                DB::beginTransaction();
                try {
                    $payment = Billpayment::with('user', 'income')->find($payment->id);

                    $amount = floatval($payment->paid_amount) + floatval($payment->discount_amount);

                    $paid_amount = floatval($payment->paid_amount);

                    $clientIdForThisBillDelete = PaymentDeleteController::deletePayment($payment, $amount, $paid_amount);

                    DB::commit();

                    BillGenerateUpdateJob::dispatch($payment->client_id);

                    return response()->json([
                        'ErrorCode' => 200,
                        'ErrorMessage' => 'Success'
                    ], 200);
                } catch (\Exception $e) {
                    DB::rollback();
                    return response()->json([
                        'ErrorCode' => 500,
                        'ErrorMessage' => $e->getMessage()
                    ], 500);
                }
            } else {
                // dd("vc");
                return response()->json([
                    'ErrorCode' => 404,
                    'ErrorMessage' => 'Not Found'
                ], 404);
            }
        } else {
            return response()->json([
                'ErrorCode' => 401,
                'ErrorMessage' => 'Unauthorized'
            ], 401);
        }
    }
}
