<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Api\BillPaymentController;
use App\Models\Billpayment;
use App\Models\Client;
use App\Models\Pop;
use App\Models\Reseller;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Validator;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Crypt;

class VFCPBillPayController extends Controller
{
    public function grantToken(Request $request)
    {

        $validator = Validator::make($request->all(), [
            'app_key' => 'required',
            'app_secret' => 'required',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'statusCode' => 422,
                'message' => 'Validation errors',
                'data' => $validator->errors(),
            ], 422);
        }

        $newRequest = new Request();
        $newRequest->merge([
            "app_key"           => $request->app_key,
            "secret"            => $request->app_secret,
        ]);

        $check_auth = (new BillPaymentController())->checkAuth($newRequest);
        if(!$check_auth){
            return response()->json([
                'statusCode' => 401,
                'message' => 'Invalid app_key or app_secret',
            ]);
        }

       $madekey = [
                'time' => now(),
                'key'  => createUUID(),
                'app_key' => $request->app_key,
                'app_secret' => $request->app_secret,
            ];

       $endCripted = Crypt::encrypt(json_encode($madekey),env('VFCPKEY'));

       return response()->json([
            "statusCode" => 0,
            "id_token"=> $endCripted,
            "expires_in" => 3600,
       ],200);
    }

    public function getTotalBillCountByBillingCycle(Request $request)
    {

        // Retrieve the 'Authorization' header
    $authorizationHeader = $request->header('Authorization');


    if (!$authorizationHeader || !str_starts_with($authorizationHeader, 'Bearer ')) {
        return response()->json([
            'statusCode' => 422,
            'message' => 'Validation errors',
            'data' => "Bearer token not found or invalid",
        ], 422);
    }

    // Extract the token (remove 'Bearer ' prefix)
    $encryptedToken = substr($authorizationHeader, 7);

    if (empty($encryptedToken)) {
        return response()->json([
            'statusCode' => 422,
            'message' => 'Validation errors',
            'data' => "Token is empty",
        ], 422);
    }


        try {
            $decrypted = Crypt::decrypt($encryptedToken,env('VFCPKEY'));
        } catch (\Exception $e) {
            return response()->json([
                'statusCode' => 401,
                'message' => 'Invalid token. Access denied.',
            ], 401);
        }

        $validator = Validator::make($request->all(), [
            'billingCycle' => 'required',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'statusCode' => 422,
                'message' => 'Validation errors',
                'data' => $validator->errors(),
            ], 422);
        }



        $decodeData = json_decode($decrypted);


        $startTime = Carbon::parse($decodeData->time);
        $endTime = Carbon::now();

        $diffInSeconds = $startTime->diffInSeconds($endTime);
        if ($diffInSeconds > 3600) {
            return response()->json([
                'statusCode' => 401,
                'message' => 'Token has expired.',
            ], 401);
        }


        $resellers = Reseller::where('reseller_type', 'own')->pluck('id');
        $allOwnManagerPop = Pop::whereIn('reseller_id', $resellers)->pluck('id');
        $totalClient = Client::with('customerAccount')->whereHas('customerAccount',function (Builder $query){
            return $query->where('dueAmount', '>', 0);
        })
        ->whereIn('pop_id', $allOwnManagerPop)->count();

        return response()->json([
            "statusCode" => 0,
            "message"=> "Successful",
            "count" => $totalClient,
       ],200);
    }

    public function getBillDocumentByBillingCycle(Request $request){
        $authorizationHeader = $request->header('Authorization');


        if (!$authorizationHeader || !str_starts_with($authorizationHeader, 'Bearer ')) {
            return response()->json([
                'statusCode' => 422,
                'message' => 'Validation errors',
                'data' => "Bearer token not found ",
            ], 422);
        }

        // Extract the token (remove 'Bearer ' prefix)
        $encryptedToken = substr($authorizationHeader, 7);

        if (empty($encryptedToken)) {
            return response()->json([
                'statusCode' => 422,
                'message' => 'Validation errors',
                'data' => "Token is empty",
            ], 422);
        }

        try {
            $decrypted = Crypt::decrypt($encryptedToken,env('VFCPKEY'));
        } catch (\Exception $e) {
            return response()->json([
                'statusCode' => 401,
                'message' => 'Invalid token. Access denied.',
            ], 401);
        }

        $decodeData = json_decode($decrypted);


        $startTime = Carbon::parse($decodeData->time);
        $endTime = Carbon::now();

        $diffInSeconds = $startTime->diffInSeconds($endTime);
        if ($diffInSeconds > 3600) {
            return response()->json([
                'statusCode' => 401,
                'message' => 'Token has expired.',
            ], 401);
        }

        $validator = Validator::make($request->all(), [
            'billingCycle' => 'required',
            'pageSize' => 'required|numeric',
            'pageNo' => 'required|numeric',
        ]);

        if ($request->pageNo <= 0) {
            return response()->json([
                'statusCode' => 400,
                'message' => 'Invalid page number',
            ], 400);
        }

        if ($validator->fails()) {
            return response()->json([
                'statusCode' => 422,
                'message' => 'Validation errors',
                'data' => $validator->errors(),
            ], 422);
        }

        $resellers = Reseller::where('reseller_type', 'own')->pluck('id');
        $allOwnManagerPop = Pop::whereIn('reseller_id', $resellers)->pluck('id');
        $offset = $request->pageSize * ($request->pageNo - 1);

        $clients = Client::with('clientsinfo','customerAccount')
                ->whereHas('customerAccount',function (Builder $query){
                    return $query->where('dueAmount', '>', 0);
                })
                ->whereIn('pop_id', $allOwnManagerPop)
                ->offset($offset)
                ->limit($request->pageSize)
                ->orderBy('id', 'asc')
                ->get()
                ->map(function ($client, $index) use ($offset) {

                    $clientId = $client->id;
                    if (checkSettings('prepaid-bill-by-client-username') == 'enable'){
                        $clientId = $client->userid;
                    }

                    if (checkSettings('prepaid-bill-by-client-code') == 'enable'){
                        $clientId = $client->customer_code ;
                    }
                    return [
                        "sequenceNo" => $offset + $index + 1, // Sequence number can be set based on the loop index
                        "uniqueID" => $clientId,
                        "customerName" => $client->clientsinfo->clients_name, // Assuming 'name' field exists; replace as necessary
                        "email" =>  $client->clientsinfo->email,
                        "phoneNo" =>  $client->clientsinfo->contact_no,  // Assuming 'phone' field exists; replace as necessary
                        "Total Fee" => isset($client->customerAccount) ? ($client->customerAccount->dueAmount >= 0 ? $client->customerAccount->dueAmount : 0 ) : 0, // Replace with actual data if needed

                    ];
                });

                return response()->json([
                    "statusCode" => 0,
                    "message"=> "Successful",
                    "content" => $clients,
               ],200);



    }

    public function pushPaymentTransaction(Request $request)
    {
        $authorizationHeader = $request->header('Authorization');


        if (!$authorizationHeader || !str_starts_with($authorizationHeader, 'Bearer ')) {
            return response()->json([
                'statusCode' => 422,
                'message' => 'Validation errors',
                'data' => "Bearer token not found ",
            ], 422);
        }

        // Extract the token (remove 'Bearer ' prefix)
        $encryptedToken = substr($authorizationHeader, 7);

        if (empty($encryptedToken)) {
            return response()->json([
                'statusCode' => 422,
                'message' => 'Validation errors',
                'data' => "Token is empty",
            ], 422);
        }

        try {
            $decrypted = Crypt::decrypt($encryptedToken,env('VFCPKEY'));
        } catch (\Exception $e) {
            return response()->json([
                'statusCode' => 401,
                'message' => 'Invalid token. Access denied.',
            ], 401);
        }

        $decodeData = json_decode($decrypted);


        $startTime = Carbon::parse($decodeData->time);
        $endTime = Carbon::now();

        $diffInSeconds = $startTime->diffInSeconds($endTime);
        if ($diffInSeconds > 3600) {
            return response()->json([
                'statusCode' => 401,
                'message' => 'Token has expired.',
            ], 401);
        }

        $validator = Validator::make($request->all(), [
            'UniqueId' => 'required',
            'TransactionID' => 'required',
            'TransactionDate' => 'required',
            'Amount' => 'required|numeric',
            'PaymentChannel' => 'required',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'statusCode' => 422,
                'message' => 'Validation errors',
                'data' => $validator->errors(),
            ], 422);
        }

        $check_previous_payment = Billpayment::where('trx_id',$request->TransactionID)->get()->count();
        if($check_previous_payment > 0){
            return response()->json([
                'statusCode' => 7007,
                'message' => 'Duplicate entry',
            ]);
        }

        $dateTime = Carbon::parse($request->TransactionDate)->format("Y-m-d H:i:s");

        $getClient = Client::find($request->UniqueId);
        
        if (checkSettings('prepaid-bill-by-client-username') == 'enable'){
            $getClient = Client::where('userid',$request->UniqueId)->first();
        }

        if (checkSettings('prepaid-bill-by-client-code') == 'enable'){
            $getClient = Client::where('customer_code',$request->UniqueId)->first();

        }

        if(!$getClient){
            return response()->json([
                'statusCode' => 404,
                'message' => 'Client not found',
            ], 404);
        }


        $result = (new PaymentController)->billPayPayment($request->TransactionID, $getClient->id, $request->Amount, "VFCP Not Provide any number", $dateTime, $decodeData->app_key, 'billpay');

        if ($result['status'] == 'success') {
            $response = [
                "statusCode" => 0,
                "message" => "Successful",
            ];
        } else {
            $response = [
                'statusCode' => 409,
                'message' => $result['status']
            ];
        }

        return response()->json($response);
    }
}
