<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use App\Models\GateConfiguration;
use App\Models\Settings;
use App\Models\Transaction;
use App\Models\FastagEntry;
use App\Models\FastagErrorList;
use DB;
use App\Traits\FastagEngineCallAPI;

class FastagFailureTxn extends Command
{
    use FastagEngineCallAPI;

    public $Gate;
    public $Settings;
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'FastagFailureTxn';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Fastag Failure And Declined Txn Status Check';

    /**
     * Execute the console command.
     *
     * @return mixed
     */

    public function handle()
    {
        DB::beginTransaction();
        $logPath = storage_path() . '/logs/fastag_fail_chk/';
        if (!file_exists($logPath)) {
            mkdir($logPath, 0755, true);
        }
        $logFile = $logPath . 'fastag_' . date('Y-m-d') . '.log';

        // Custom log function
        $log = function($message, $context = array(), $level = 'info') use ($logFile) {
            $logMessage = '[' . date('Y-m-d H:i:s') . '] ' . strtoupper($level) . ': ' . $message;
            if (!empty($context)) {
                $logMessage .= ' ' . json_encode($context);
            }
            $logMessage .= PHP_EOL;
            file_put_contents($logFile, $logMessage, FILE_APPEND);
        };

        try {
            $log('######################### Fastag Failure And Declined Txn Start##############################');
            $fastagEntries =  DB::select("SELECT *  from sps_transactions LEFT join sps_cps on sps_cps.transaction_id = sps_transactions.id  where sps_transactions.fastag_pay IN ('FAILURE','DECLINED') AND sps_transactions.fastag_messageId is not null AND sps_transactions.deleted_at is null LIMIT 250");
            //print_r($fastagEntries);
            $log('Found transactions', ['count' => count($fastagEntries)]);

            if (empty($fastagEntries)) {
                $log('No FASTag transactions found for failure or declined', array(), 'warning');
                throw new \Exception("FASTag Fail Txn API -- Data not found");
            }
            $vehicleDetails = [];
            $this->Gate = new GateConfiguration();
            $this->Settings = new Settings();
            $log('Initialized GateConfiguration and Settings');
            $holeTime = 0; //1 min
        
            $now = strtotime(date('Y-m-d H:i:s'));
            if (!empty($fastagEntries)) {
                $log('Processing transactions', ['count' => count($fastagEntries)]);

                foreach ($fastagEntries as $entry) {
                        $entry = (array)$entry;
                        $log('Processing transaction', ['id' => $entry['id']], 'debug');

                        $fastagReqpayRequestCount = $entry['fastag_reqpay_req_count'];
                        $fastagPayStatus = $entry['fastag_pay'];
                        $log('Transaction details', [
                            'req_pay_count' => $fastagReqpayRequestCount,
                            'pay_status' => $fastagPayStatus
                        ], 'debug');
                        
                        if($fastagReqpayRequestCount == 0 && ($fastagPayStatus == "pending" || empty($fastagPayStatus))){
                            $log('Skipping transaction', [
                                'id' => $entry['id'],
                                'reason' => $fastagPayStatus === null ? 'status is empty' : 'pending and not yet sent to bank',
                                'fastag_status' => $fastagPayStatus,
                                'req_pay_count' => $fastagReqpayRequestCount
                            ], 'debug');
                            continue;
                        }

                        
                        $fastagReqcheckRequestCount = $entry['fastag_reqcheck_req_count'];
                        // $fastagReqcheckRequestDate = $entry['fastag_reqcheck_req_datetime'];
                        // $delayMinutes = $fastagReqcheckRequestCount * 2;
                        // $callTime =strtotime("+" . $delayMinutes . " minutes", strtotime($fastagReqcheckRequestDate));
                        $log('Fastag request check count with failure', ['id' => $entry['id'],'fastag_request_count',$fastagReqcheckRequestCount], 'debug');

                        $log('Calling fastagReqCheckApi for failure', ['id' => $entry['id']]);
                        $this->fastagReqCheckApi($entry, $entry['fastag_reqcheck_req_count']);

                        // Update check count and timestamp
                        $data0 = [
                            "fastag_reqcheck_req_count" => $entry['fastag_reqcheck_req_count'] + 1,
                            "fastag_reqcheck_req_datetime" => date("Y-m-d H:i:s")
                        ];
                        $log('Updating transaction check count', [
                            'id' => $entry['id'],
                            'new_count' => $data0["fastag_reqcheck_req_count"],
                            'new_datetime' => $data0["fastag_reqcheck_req_datetime"]
                        ]);
                        
                        $updateTransactionForReqCheckCount = Transaction::where('id', $entry['id'])->update($data0);
                        $log('Transaction check count updated', [
                            'id' => $entry['id'],
                            'rows_affected' => $updateTransactionForReqCheckCount
                        ]);
                    //}
                }
                DB::commit();
                $log('Request Check Transaction for failure committed successfully');
            } else {
                throw new \Exception("FASTag Fail Chk Details API -- Data not found");
            }

        } catch (\Exception $exception) {
            DB::rollback();
		    $log('Exception occurred', [
                'message' => $exception->getMessage(),
                'file' => $exception->getFile(),
                'line' => $exception->getLine()
            ], 'error');
            $this->createLog(false, $logPath, "FASTag Fail Chk", json_encode($fastagEntries), $exception->getMessage());
        }
        $log('######################### Fastag Failure And Declined Transaction End ##############################');
    }


    public function fastagReqCheckApi($entry,$fastagReqcheckRequestCount){
        $logPath = storage_path() . '/logs/fastag_fail_chk/';
        if (!file_exists($logPath)) {
            mkdir($logPath, 0755, true);
        }
        $logFile = $logPath . 'fastag_' . date('Y-m-d') . '.log';

        // Custom log function
        $log = function($message, $context = array(), $level = 'info') use ($logFile) {
            $logMessage = '[' . date('Y-m-d H:i:s') . '] ' . strtoupper($level) . ': ' . $message;
            if (!empty($context)) {
                $logMessage .= ' ' . json_encode($context);
            }
            $logMessage .= PHP_EOL;
            file_put_contents($logFile, $logMessage, FILE_APPEND);
        };

        $log('######################### Fastag ReqCheck API Start ##############################');
        $log('Processing transaction', ['transaction_id' => $entry['id']], 'debug');

        //DB::beginTransaction();
        $vehicleDetails = [];
        $this->Gate = new GateConfiguration();
        $this->Settings = new Settings();
        $holeTime = 0; //1 min


        try {
            $log('Calling fastagReqChkTxn API');
            $jsonResponse = $this->fastagReqChkTxn($entry);
            if($jsonResponse != false){
                //$log('Received API response', ['response' => $jsonResponse], 'debug');
                // Decode the JSON response
                preg_match('/\{.*\}/s', $jsonResponse, $matches);
                $response = json_decode($matches[0], true);
                $responseData = $response;
                $log('Decoded JSON response', ['response_data' => $responseData], 'debug');

                if (!$responseData) {
                    $log('Invalid JSON response received', [], 'error');
                    return false; // Invalid JSON
                }

                $txnStatus = null;
                $errCode = null;
                $statusSource = '';

                // 1. Try to get from TxnStatusReqList -> Status -> TxnList -> txnStatus and errCode
                if (isset($responseData['Txn']['Resp']['TxnStatusReqList']['Status']['TxnList']['@attributes']['txnStatus']) &&
                    isset($responseData['Txn']['Resp']['TxnStatusReqList']['Status']['TxnList']['@attributes']['errCode'])) {

                    $txnStatus = $responseData['Txn']['Resp']['TxnStatusReqList']['Status']['TxnList']['@attributes']['txnStatus'];
                    $errCode = $responseData['Txn']['Resp']['TxnStatusReqList']['Status']['TxnList']['@attributes']['errCode'];
                    $statusSource = 'TxnList';
                }
                // 2. Fallback: Try to get from TxnStatusReqList -> Status -> result and errCode
                elseif (isset($responseData['Txn']['Resp']['TxnStatusReqList']['Status']['@attributes']['result']) &&
                        isset($responseData['Txn']['Resp']['TxnStatusReqList']['Status']['@attributes']['errCode'])) {

                    $txnStatus = $responseData['Txn']['Resp']['TxnStatusReqList']['Status']['@attributes']['result'];
                    $errCode = $responseData['Txn']['Resp']['TxnStatusReqList']['Status']['@attributes']['errCode'];
                    $statusSource = 'Status';
                }
                // 3. Fallback: Try to get from Resp -> result and errCode
                elseif (isset($responseData['Txn']['Resp']['@attributes']['result']) &&
                        isset($responseData['Txn']['Resp']['@attributes']['respCode'])) {

                    $txnStatus = $responseData['Txn']['Resp']['@attributes']['result'];
                    $errCode = $responseData['Txn']['Resp']['@attributes']['respCode'];
                    $statusSource = 'Resp';
                }
                // Not found
                else {
                    $log('Could not extract status and error code from response', ['response' => $responseData], 'error');
                    return false;
                }

                $log('Extracted transaction status', [
                    'status' => $txnStatus,
                    'error_code' => $errCode,
                    'source' => $statusSource
                ]);

                $reqChkTxn = [
                    'status' => $txnStatus,
                    'errCode' => $errCode
                ];
                if($reqChkTxn){
                    $fasTagPay = $reqChkTxn['status'];
                    $responseCode = $reqChkTxn['errCode'];
                    $datareqChkTxn = [];
                    $transactionId = $entry['id'];

                    $log('Processing transaction status', [
                        'status' => $fasTagPay,
                        'error_code' => $responseCode
                    ]);
                    if($fasTagPay == "SUCCESS"){
                        $datareqChkTxn["fastag_pay"] = "ACCEPTED";
                        $log('Transaction accepted', ['transaction_id' => $transactionId]);
                    }elseif($fasTagPay == "FAILURE"){
                        $datareqChkTxn["fastag_pay"] = "FAILURE";
                        $log('Transaction failed', ['transaction_id' => $transactionId]);
                    }elseif($fasTagPay == "DECLINED"){
                        $datareqChkTxn["fastag_pay"] = "DECLINED";
                        $log('Transaction declined', ['transaction_id' => $transactionId]);
                    }elseif($fasTagPay == "IN-PROCESS"){
                        $datareqChkTxn["fastag_pay"] = "inprocess";
                        $log('Transaction still in process', ['transaction_id' => $transactionId]);
                    }else{
                        $log('Transaction not successful', [
                            'transaction_id' => $transactionId,
                            'status' => $fasTagPay,
                            'error_code' => $responseCode
                        ]);
                    }

                    $errorMsg = FastagErrorList::where('error_code', $responseCode)->get()->first();
                    $log('Fetched error message from database', [
                        'error_code' => $responseCode,
                        'error_message' => $errorMsg ? $errorMsg->description : 'Not found'
                    ]);

                    if (!empty($errorMsg)) {
                        $datareqChkTxn["fastag_comment"] = $responseCode."|".$errorMsg->description;
                    }

                    $log('Updating transaction record', [
                        'transaction_id' => $transactionId,
                        'update_data' => $datareqChkTxn
                    ]);

                    // $data["fastag_messageId"] = $response;
                    // $data["fastag_pay"] = "inprocess";
                    // $data["fastag_comment"] = "ReqPay Api intiated, Waiting for response";
                    $updateTransaction = Transaction::where('id', $transactionId)
                    ->update($datareqChkTxn);
                    $log('Transaction updated successfully', [
                        'transaction_id' => $transactionId,
                        'rows_affected' => $updateTransaction
                    ]);
                }
            }else{
                $log('Empty or false response received from fastagReqChkTxn', [], 'error');
            }
            $log('######################### Fastag ReqCheck API End ##############################');
        } catch (\Exception $exception) {
            $log('Exception occurred', [
                'message' => $exception->getMessage(),
                'file' => $exception->getFile(),
                'line' => $exception->getLine(),
                'trace' => $exception->getTraceAsString()
            ], 'error');
            throw new \Exception("FASTag Req Check Details API: " . $exception->getMessage());
        }
    }


    public function testFastagReqCheckApi($entry,$fastagReqcheckRequestCount){

        //DB::beginTransaction();
        $vehicleDetails = [];
        $this->Gate = new GateConfiguration();
        $this->Settings = new Settings();
        $holeTime = 0; //1 min

        try {
            //DB::commit();


            $response = true;

            if($response != false){


                    $result = "pending"; //change here for test txn status

                    $txnStatus = "";

                    if($result == "SUCCESS"){
                        $txnStatus = "ACCEPTED";
                    }elseif($result == "FAILURE"){
                        $txnStatus = "DECLINED";
                    }


                    $errCode = "00"; //00 for success
                    $fastagTxnId = "1234567890"; //dummy txnID
                    $ReqChkTxnId = "1111111111"; //dymmu fastagTxnId
                    print_r("###".$fastagTxnId."###");


                    $data["fastag_pay"] = $txnStatus;
                    $responseCode = $errCode;
                    $transactionId = $entry['id'];

                    $errorMsg = FastagErrorList::where('error_code', $responseCode)->get()->first();

                    //if (!empty($errorMsg)) {
                    $data["fastag_comment"] = "ResChkTxn|".$responseCode."|".$errorMsg->description."|".$ReqChkTxnId;
                    //}

                    print_r($data["fastag_comment"]);

                    // $data["fastag_messageId"] = $response;
                    // $data["fastag_pay"] = "inprocess";
                    // $data["fastag_comment"] = "ReqPay Api intiated, Waiting for response";

                   // $updateTransaction = Transaction::where('id', $transactionId)->update($data);
                    

                    // $this->createLog(true, $logPath, "FASTag Request Pay", $entry, json_encode($response));

            }

            //DB::commit();

        } catch (\Exception $exception) {
            print_r($exception->getMessage());
            //DB::rollback();
            throw new \Exception("FASTag Req Tag Details API ");
        }
    }



}
