<?php

namespace App\Http\Controllers\Fastag;

//ini_set('display_errors', 1);
//ini_set('display_startup_errors', 1);
//error_reporting(E_ALL);

use App\Http\Controllers\APIBaseController as APIBaseController;
use App\Http\Requests\FASTag\FASTagRequest;
use App\Models\FastagErrorList;
use App\Models\GatePaymentsMapping;
use App\Models\ImageUpload;
use App\Models\Tariff;
use App\Models\TransactionAdditionalCharge;
use App\Models\TaxBreakup;
use App\Models\Area;
use App\Models\GateConfiguration;
use App\Models\Location;
use App\Models\Settings;
use App\Models\ShiftManagement;
use App\Models\StickerMembership;
use App\Models\TransactionDiscount;
use App\Models\User;
use App\Models\Transaction;
use App\Models\FastagEntry;
use App\Models\VehicleTypes;
use App\Models\Voucher;
use App\Models\PaymentModes;

use Carbon\Carbon;
use DB;
use Exception;
use Illuminate\Http\Request;
use Validator;

use Illuminate\Support\Facades\URL;
use DateTime;
use App\Traits\GenerateBarcode;
use App\Traits\CalculateTariff;
use App\Traits\FastagEngineCallAPI;
use Log;

class FastagController extends APIBaseController
{
    use GenerateBarcode, CalculateTariff, FastagEngineCallAPI;

    public $User;
    public $Gate;
    public $GatePayment;
    public $ShiftManagment;
    public $StickerMembership;
    public $FastagEntry;
    public $PaymentMode;
    public $VehicleType;
    public $logPath;
    public $settings;
    public $Tariff;

    public function __construct()
    {
        $this->User = new User();
        $this->Gate = new GateConfiguration();
        $this->GatePayment = new GatePaymentsMapping();
        $this->ShiftManagment = new ShiftManagement();
        $this->StickerMembership = new StickerMembership();
        $this->FastagEntry = new FastagEntry();
        $this->PaymentMode = new PaymentModes();
        $this->VehicleType = new VehicleTypes();
        $this->Tariff = new Tariff();
        $this->settings = Settings::all()->first();
        $this->logPath = storage_path() . '/logs/fastag/';
    }

    public function AddTest(Request $request)
    {
        //Get input request parameters
        $data = array();
        try {
            $input = $request->all();
            return $this->sendFastageResponse($input, 'Successfully');
        } catch (\Exception $e) {
            return $this->sendFastageError('Exception Error.', $e->getMessage(), 422);
        }
    }


    public function storeEntryVehImages($input, $txnid)
    {
        $logMsg = '';
        $successTransactionIdAtEntry = $txnid;

        $entryEnfImage = "enf";  //enf for face image
        $entryEnvImage = "env";  //env for vehicle image
        $entryEncImage = "enc";  //enc for Vehicle Croped Image
        $imageTimestampName = date("YmdHis");
        /*---- transaction id convert to md5 encryption ----*/
        $md5OfTransactionId = md5($successTransactionIdAtEntry);
        //echo "transaction_id:$md5OfTransactionId\n";
        $created_at = date("Y-m-d H:i:s");

        $contentEnf = base64_decode($input['VehicleImage']);  //face image
        $contentEnv = base64_decode($input['DriverImage']); //vehicle image
        $contentEnc = base64_decode($input['vehicleCropedImage']);  //croped image
        $entryFirstImage = 1;
        $entrySecondImage = 1;
        $entryThirdImage = 1;

        if ($entryFirstImage == "NULL" || $entryFirstImage == "-1") {
            $logMsg .= "Image is not captured getting null string for first image \n";

        } else {
            $fullImageNameEnf = $entryEnfImage . "_" . $imageTimestampName . "_" . $successTransactionIdAtEntry;
            $logMsg .= "full image path enf:$fullImageNameEnf\n";
            //$dir = "../storage/images/transactions";
            $dir = storage_path() . '/images/transactions';
            if (!file_exists($dir)) {
                $oldmask = umask(0);  // helpful when used in linux server
                /*---- using mkdir to create a directory if not exists and giving permission ----*/
                mkdir($dir, 0777);
                $fileEnfEntry = storage_path() . "/images/transactions/$fullImageNameEnf.jpg";
                file_put_contents($fileEnfEntry, $contentEnf);
                $logMsg .= "full image path enf1:$fileEnfEntry\n";
            } else {
                $fileEnfEntry = storage_path() . "/images/transactions/$fullImageNameEnf.jpg";
                file_put_contents($fileEnfEntry, $contentEnf);
                $logMsg .= "full image path enf2:$fileEnfEntry\n";
            }
            $finalImageName = $fullImageNameEnf . ".jpg";
            $logMsg .= "final image path enf:$finalImageName\n";

            $image1 = new ImageUpload();
            $image1->module = 'Entry';
            $image1->module_id = $successTransactionIdAtEntry;
            $image1->file_name = $finalImageName;
            $image1->save();

            if ($image1) {
                $logMsg .= $finalImageName . " inserted successfully\n";
            } else {
                $logMsg .= $finalImageName . " Not inserted successfully\n";
            }
        }




        /*---- image "Null" means unmanned entry and image "-1" means manned entry ----*/
        if ($entrySecondImage == "NULL" || $entrySecondImage == "-1") {
            $logMsg .= "Image is not captured getting null string for second image \n";
        } else {
            $logMsg .= "inside image env\n";
            /*---- creating image name using type of image, timestamp and transaction id ----*/
            $fullImageNameEnvEntry = $entryEnvImage . "_" . $imageTimestampName . "_" . $successTransactionIdAtEntry;
            $dir = storage_path() . "/images/transactions";
            $logMsg .= "full image path env:$fullImageNameEnvEntry\n";
            if (!file_exists($dir)) {

                $oldmask = umask(0);  // helpful when used in linux server

                /*---- using mkdir to create a directory if not exists and giving permission ----*/
                mkdir($dir, 0777);

                /*---- path for creating directory ----*/
                $fileEnvEntry = storage_path() . "/images/transactions/$fullImageNameEnvEntry.jpg";
                file_put_contents($fileEnvEntry, $contentEnv);
                $logMsg .= "full image path env1:$fileEnvEntry\n";
            } else {

                /*---- path for creating directory ----*/
                $fileEnvEntry = storage_path() . "/images/transactions/$fullImageNameEnvEntry.jpg";
                file_put_contents($fileEnvEntry, $contentEnv);
                $logMsg .= "full image path env2:$fileEnvEntry\n";
            }

            $finalImageNameEnv = $fullImageNameEnvEntry . ".jpg";
            $logMsg .= "final image path env:$finalImageNameEnv\n";

            $image2 = new ImageUpload();
            $image2->module = 'Entry';
            $image2->module_id = $successTransactionIdAtEntry;
            $image2->file_name = $finalImageNameEnv;
            $image2->save();

            if ($image2) {
                $logMsg .= $finalImageNameEnv . " inserted successfully\n";
            } else {
                $logMsg .= $finalImageNameEnv . " Not inserted successfully\n";
            }
        }


        /*---- image "Null" means unmanned entry and image "-1" means manned entry ----*/
        if ($entryThirdImage == "NULL" || $entryThirdImage == "-1" || $entryThirdImage == "#") {
            $logMsg .= "Image is not captured getting null string for croped image \n";
        } else {
            $logMsg .= "inside image enc\n";
            /*---- creating image name using type of image, timestamp and transaction id ----*/
            $fullImageNameEncEntry = $entryEncImage . "_" . $imageTimestampName . "_" . $successTransactionIdAtEntry;
            $dir = storage_path() . "/images/transactions";
            $logMsg .= "full image path enc:$fullImageNameEncEntry\n";
            if (!file_exists($dir)) {

                $oldmask = umask(0);  // helpful when used in linux server

                /*---- using mkdir to create a directory if not exists and giving permission ----*/
                mkdir($dir, 0777);

                /*---- path for creating directory ----*/
                $fileEncEntry = storage_path() . "/images/transactions/$fullImageNameEncEntry.bmp";
                file_put_contents($fileEncEntry, $contentEnc);
                $logMsg .= "full image path enc1:$fileEncEntry\n";
            } else {

                /*---- path for creating directory ----*/
                $fileEncEntry = storage_path() . "/images/transactions/$fullImageNameEncEntry.bmp";
                file_put_contents($fileEncEntry, $contentEnc);
                $logMsg .= "full image path enc2:$fileEncEntry\n";
            }

            $finalImageNameEnc = $fullImageNameEncEntry . ".bmp";
            $logMsg .= "final image path enc:$finalImageNameEnc\n";

            $queryEntryEncImages = new ImageUpload();
            $queryEntryEncImages->module = 'Entry';
            $queryEntryEncImages->module_id = $successTransactionIdAtEntry;
            $queryEntryEncImages->file_name = $finalImageNameEnc;
            $queryEntryEncImages->save();

            if ($queryEntryEncImages) {
                $logMsg .= $finalImageNameEnc . " inserted successfully\n";
            } else {
                $logMsg .= $finalImageNameEnc . " Not inserted successfully\n";
            }
        }
        $this->createLog(true, $this->logPath, "FASTag Entry Image", $input, $logMsg);
    }


    public function storeExitVehImages($input, $txnid){


        $logMsg = '';
        $spsTransactionIdExit = $txnid;

        $exitEnfImage = "exf"; //face image
        $exitEnvImage = "exv"; //vehicle image
        $exitEncImage = "exc"; //croped image
        $imageTimestampNameExit = date("YmdHis");
        /*---- transaction id md5 encryption ----*/
        $md5OfTransactionId = md5($spsTransactionIdExit);
        //echo "transaction_id:$md5OfTransactionId\n";
        $created_at = date("Y-m-d H:i:s");
        //if($image != NULL)
        /*---- decoding base64 encoded string into binary string ----*/
        $contentEnvExit = base64_decode($input['VehicleImage']); //vehicle image
        $contentEnfExit = base64_decode($input['DriverImage']); //face image
        $contentEncExit = base64_decode($input['vehicleCropedImage']); //croped image

        $envImageExit = 1;
        $enfImageExit = 1;
        $encImageExit = 1;
        /*---- check for image present or not(vehicle image) ----*/
        if ($envImageExit == "-1" || $envImageExit == "NULL") {
            echo "Image is not captured getting null string for first image \n";
            $finalImageNameExit = "-1";
        } else {
            /*---- creating image name using type of image, timestamp and transaction id ----*/
            $fullImageNameEnv =
                $exitEnvImage .
                "_" .
                $imageTimestampNameExit .
                "_" .
                $spsTransactionIdExit;
            $dir = "../storage/images/transactions";
            /*---- checking if directory is already exists or not ----*/
            if (!file_exists($dir)) {
                $oldmask = umask(0); // helpful when used in linux server

                /*---- using mkdir to create a directory if not exists and giving permission ----*/
                mkdir($dir, 0777);
                $fileEnvExit = storage_path() . "/images/transactions/$fullImageNameEnv.jpg";
                file_put_contents(
                    $fileEnvExit,
                    $contentEnvExit
                );
            } else {
                /*---- if directory name already exists then write image directly to that directory ----*/
                $fileEnvExit = storage_path() . "/images/transactions/$fullImageNameEnv.jpg";
                file_put_contents(
                    $fileEnvExit,
                    $contentEnvExit
                );
            }

            $finalImageNameExit = $fullImageNameEnv . ".jpg";
            //echo "final image of env:$finalImageName\n\n\n\n";

            /*---- Inserting image detail into sps_images table ----*/

            // $queryExitEnvImages = "insert into sps_images(module,module_id,file_name,created_at)values('Exit','$spsTransactionIdExit','$finalImageNameExit','$created_at')";
            // if (mysqli_query($conn, $queryExitEnvImages)) {
            //     //echo "inserted successfully\n";
            // } else {
            //     echo "inserted failed image\n";
            // }

            $image1 = new ImageUpload();
            $image1->module = 'Exit';
            $image1->module_id = $spsTransactionIdExit;
            $image1->file_name = $finalImageNameExit;
            $image1->save();

            if ($image1) {
                $logMsg .= $finalImageNameExit . " inserted successfully\n";
            } else {
                $logMsg .= $finalImageNameExit . " Not inserted successfully\n";
            }


        }
        /*---- check for image present or not(face image) ----*/
        if ($enfImageExit == "-1" || $enfImageExit == "NULL") {
            echo "Image is not captured getting null string for second image\n";
            $finalEnfImageNameExit = "-1";
        } else {
            $fullImageName2 =
                $exitEnfImage .
                "_" .
                $imageTimestampNameExit .
                "_" .
                $spsTransactionIdExit;
            /*---- path for creating directory ----*/
            $dir = "../storage/images/transactions";
            /*---- checking if directory is already exists or not ----*/
            if (!file_exists($dir)) {
                $oldmask = umask(0); // helpful when used in linux server

                /*---- using mkdir to create a directory if not exists and giving permission ----*/
                mkdir($dir, 0777);

                $fileEnfExit = storage_path() . "/images/transactions/$fullImageName2.jpg";
                /*---- writing image to a directory ----*/

                file_put_contents(
                    $fileEnfExit,
                    $contentEnfExit
                );
            } else {
                /*---- if directory name already exists then write image directly to that directory ----*/
                $fileEnfExit = storage_path() . "/images/transactions/$fullImageName2.jpg";
                /*---- writing image to a directory ----*/

                file_put_contents(
                    $fileEnfExit,
                    $contentEnfExit
                );
            }

            $finalEnfImageNameExit = $fullImageName2 . ".jpg";
            //echo "final image of enf:$finalEnfImageNameExit\n\n\n\n\n\n";

            /*---- Inserting image detail into sps_images table ----*/

            // $queryExitEnfImages = "insert into sps_images(module,module_id,file_name,created_at)values('Exit','$spsTransactionIdExit','$finalEnfImageNameExit','$created_at')";
            // if (mysqli_query($conn, $queryExitEnfImages)) {
            //     echo "inserted successfully\n";
            // } else {
            //     echo "Error in inserting images\n";
            // }



            $image1 = new ImageUpload();
            $image1->module = 'Exit';
            $image1->module_id = $spsTransactionIdExit;
            $image1->file_name = $finalEnfImageNameExit;
            $image1->save();

            if ($image1) {
                $logMsg .= $finalEnfImageNameExit . " inserted successfully\n";
            } else {
                $logMsg .= $finalEnfImageNameExit . " Not inserted successfully\n";
            }


        }

        /*---- check for image present or not(vehicle croped image) ----*/
        if (
            $encImageExit == "-1" ||
            $encImageExit == "#" ||
            $encImageExit == "NULL"
        ) {
            echo "Image is not captured getting null string for third image \n";
            $finalEncImageNameExit = "-1";
        } else {
            /*---- creating image name using type of image, timestamp and transaction id ----*/
            $fullImageNameEnc =
                $exitEncImage .
                "_" .
                $imageTimestampNameExit .
                "_" .
                $spsTransactionIdExit;
            $dir = storage_path() . "/images/transactions";
            /*---- checking if directory is already exists or not ----*/
            if (!file_exists($dir)) {
                $oldmask = umask(0); // helpful when used in linux server

                /*---- using mkdir to create a directory if not exists and giving permission ----*/
                mkdir($dir, 0777);
                $fileEncExit = storage_path() . "/images/transactions/$fullImageNameEnc.bmp";
                file_put_contents(
                    $fileEncExit,
                    $contentEncExit
                );
            } else {
                /*---- if directory name already exists then write image directly to that directory ----*/
                $fileEncExit = storage_path() . "/images/transactions/$fullImageNameEnc.bmp";
                file_put_contents(
                    $fileEncExit,
                    $contentEncExit
                );
            }

            $finalEncImageNameExit = $fullImageNameEnc . ".bmp";
            //echo "final image of enc:$finalImageName\n\n\n\n";

            /*---- Inserting image detail into sps_images table ----*/

            // $queryExitEncImages = "insert into sps_images(module,module_id,file_name,created_at)values('Exit','$spsTransactionIdExit','$finalEncImageNameExit','$created_at')";
            // if (mysqli_query($conn, $queryExitEncImages)) {
            //     //echo "inserted successfully\n";
            // } else {
            //     echo "inserted failed image\n";
            // }


            $image1 = new ImageUpload();
            $image1->module = 'Exit';
            $image1->module_id = $spsTransactionIdExit;
            $image1->file_name = $finalEncImageNameExit;
            $image1->save();
            if ($image1) {
                $logMsg .= $finalEncImageNameExit . " inserted successfully\n";
            } else {
                $logMsg .= $finalEncImageNameExit . " Not inserted successfully\n";
            }

        }


    }


    public function storeFastagEntry(FASTagRequest $request)
    {
        $transaction = '';
        $response = [];
        $exception = '';

        try {
            $entryStatus = DB::transaction(function () use (&$request, &$transaction, &$response, &$exception) {
                //Get input request parameters
                try {
                    $input = $request->all();
                    $checkShiftManagement = $this->checkShiftManagementValidation($input);
                    if (!is_array($checkShiftManagement)) {
                        throw new Exception($checkShiftManagement);
                    }

                    $area = $checkShiftManagement['area'];
                    $location = $checkShiftManagement['location'];
                    $gate = $checkShiftManagement['gate'];
                    $userId = $checkShiftManagement['userId'];
                    $shiftId = $checkShiftManagement['shiftId'];
                    $isFastagPayment = $input['isFastagPayment'];
                    $laneId = $input['laneId'];
                    $vehicleNumber = !empty($input['vehicleNumber']) ? $input['vehicleNumber'] : "0";
                    $anprVehicleNumber = !empty($input['vehicleNumber']) ? $input['vehicleNumber'] : "0";

                    //Checking Block vehicle
                    if ($this->FastagEntry->getBlockVehicleDetails($input)) {
                        throw new \Exception('Blocked Vehicle');
                    }

                    // generating barcode
                    $barcode = $input['Barcode'];
                    $checkIfBarcodeExist = Transaction::where('barcode', $barcode)->count();
                    if ($checkIfBarcodeExist > 0) {
                        throw new \Exception('Duplicate entry - ' . $barcode);
                    }


                    //check duplicate vehicle number

                    if(!empty($input['vehicleNumber'])){
                        $checkIfVehicleExist = Transaction::where('vehicle_number', $anprVehicleNumber)->where('out_time', '=', '0000-00-00 00:00:00')->count();
                        //dd(DB::getQueryLog());
                        if ($checkIfVehicleExist > 0) {
                            //throw new \Exception('Duplicate Vehicle entry - ' . $anprVehicleNumber);
                            $anprVehicleNumber = "0";
                            $vehicleNumber = "0";
                        }
                    }

                    $dayTypeEntry = $this->getDaytype($area->area_id, $location->location_id, $input['InTime']);

                    //Payment Mode
                    $paymentMode = $this->PaymentMode->getpaymentModeList(["keyword" => "FASTag", "perpage" => false]);
                    $paymentMode = $paymentMode->toArray();

                    $vehicleType = $this->VehicleType->getVehicleTypeByName("4 Wheeler");
                    if (is_null($vehicleType)) {
                        $vehicleType = 1;
                    } else {
                        $vehicleType = $vehicleType->toArray()['id'];
                    }

                    $inType = 1; // 1 for normal entry, 2 for membership
                    $inTypeId = 0; // 0 for normal entry, 6396907430015851 for membership card
                    $inPaymentMode = isset($paymentMode['data'][0]['id']) ? $paymentMode['data'][0]['id'] : 8;
                    $inMasterPaymentMode = isset($paymentMode['data'][0]['master_id']) ? $paymentMode['data'][0]['master_id'] : 4;


                    $tariff['vehicle_type'] = $vehicleType;
                    $tariff['day_type'] = $dayTypeEntry;
                    $tariff['status'] = 1;

                    $tariffCodeDetails = $this->Tariff->getTariffList($tariff);
                    $tariffCode = 0;
                    if (!empty($tariffCodeDetails)) {
                        $tariffCode = $tariffCodeDetails->first()->tariff_code;
                    }

                    $fastags = $input['Fastags']['Fastag']; // fasTAG Data

                    //print_r($fastags);


                    //Validation if vehicle is already entered -- need check
                    if (!empty($fastags)) {
                        $transaction = $this->FastagEntry->getUniqueFastagDetail($fastags);
                        if ($transaction != False) {
                            $fastags = $transaction;
                        }else{
                            throw new Exception('Vehicle Already Entered-1.');
                        }
                    } else {
                        throw new Exception('FASTag IDs are not found');
                    }




                    $fastagId = null;
                    $fastagEntryTagId = null;
                    $fastagTxnTagId = null;
                    $membership = 0;

                    //die("here");
                    if (!empty($fastags && is_array($fastags))) {

                        //$fastagsArray = [];

                        $fastagId = "";
                        $fastagTagId = "";
                        $fastagTagSig = "";
                        $txnResponse = "";
                        $fastagDetail = [];
                        $vechNo = "0";
                        $fastagVechNo = "0";
                        foreach ($fastags as $fastag) {


                            $validator = Validator::make($fastag, [
                                "epc_id" => "required|string|min:24",
                                "tag_id" => "required|string|min:24",
                                "tag_signature_data_hex" => "required|string",
                            ]);



                            if ($fastagTxnTagId != $fastag['tag_id'] && strlen($validator->errors()->first()) == 0) {


                                $tagDataforCheck = array("fastag_id" => $fastag['tag_id'], "id" => "", "laneId" =>
                                $laneId, "vehicleNo" => $anprVehicleNumber, "in_time" => $input['InTime'], "out_time" => "", "IP" => $input['IP']);

                                $fastagDetail = $this->checkFastagTagDetail($tagDataforCheck, "entry");


                                $fastagMessage = $this->getFastagErrorMessage($fastagDetail['fastagStatusCode']);

                                $fastagDetail["tag_signature_data_hex"] = $fastag['tag_signature_data_hex'];
                                $fastagDetail["fastagMessage"] = $fastagMessage;

                                if ($fastagDetail['fastagStatusCode'] == "00") {

                                    $fastagVechNo = $fastagDetail['fastag_vehicle_no'];
                                    break;
                                }
                            }
                        }

                        $fastagVechNo = $fastagDetail['fastag_vehicle_no'];
                        if($fastagVechNo != "0"){

                            $txnResponse = $this->insertTranscationData($input,$barcode,$vehicleType,$fastagVechNo,$shiftId,$inType,$inTypeId,$gate->gate_id,$userId,$inPaymentMode,$inMasterPaymentMode,$dayTypeEntry,$tariffCode,$area->area_id,$laneId,$fastags,$fastagDetail,$anprVehicleNumber);
                            $response['transaction'] = $txnResponse;
                        }else{
                            throw new \Exception('Invalid FASTag IDs 1');
                        }

                    } else {
                        throw new \Exception('FASTag IDs not found');
                    }

                    if (is_null($fastagId)) {
                        throw new \Exception('Invalid FASTag IDs 2');
                    }
                } catch (Exception $e) {
                    $exception = $e->getMessage();
                }

            });

            //if  $entryStatus is null then transaction is inserted successfully
            if (is_null($entryStatus) && strlen($exception) == 0) {
                $this->createLog(true, $this->logPath, "FASTag Entry ", $request->all(), $this->sendFastageResponse($transaction, 'Successfully'));
                return $this->sendFastageResponse($response, 'Welcome To SecureParking!');
            } else {
                throw new Exception($exception);
            }

        } catch (\Exception $e) {
            //$this->createLog(false, $this->logPath, "FASTag Entry Error", $request->all(), $this->sendFastageError('Error: ' . $e->getMessage(), [], 422));
            return $this->sendFastageError('Error: ' . $e->getMessage(), [], 422);
        }

    }


    public function checkFastagVehicleNo($fastagVehicleNo,$anprVehicleNumber){
        $checkIfVehicleExist = Transaction::where('vehicle_number',$fastagVehicleNo)->where('out_time', '=', '0000-00-00 00:00:00')->count();
        if ($checkIfVehicleExist > 0) {
            return false;
        }

        if($anprVehicleNumber == "0"){
            if(strlen($fastagVehicleNo) > 12){
                return false;
            }
        }

       return true;

    }


    public function insertTranscationData($input,$barcode,$vehicleType,$vehicleNumber,$shiftId,$inType,$inTypeId,$gate_id,$userId,$inPaymentMode,$inMasterPaymentMode,$dayTypeEntry,$tariffCode,$area_id,$laneId,$fastags,$fastagDetail,$anprVehicleNumber){

        $fastagVechNo = $vehicleNumber;


        if($this->checkFastagVehicleNo($fastagVechNo,$anprVehicleNumber)){

            $txnVehicleNumber = $anprVehicleNumber == "0" ? $fastagVechNo : $anprVehicleNumber;


            $vehicle = [];
            $vehicle['vehicleNumber'] = $txnVehicleNumber;
            $vehicle['fastagId'] = $fastagDetail['TAGID'];



            if($txnVehicleNumber != "0"){
                //If FASTag has Sticker membership.
                $membership = $this->StickerMembership->getStickerMembershipByVehicleNo($vehicle);
                if ($membership) {
                    $inType = 5;
                    $inTypeId = $membership[0]->membership_id;
                    $inPaymentMode = 0;
                    $inMasterPaymentMode = 3;
                }else{
                    $inType = 1;
                    $inTypeId = 0;
                    $inPaymentMode = 0; //8
                    $inMasterPaymentMode = 0; //0
                }
            }


            // Setting data in transaction table
            $transaction = new Transaction();
            $transaction->barcode = $barcode;
            $transaction->ticket_no = rand(10000, 99999);
            $transaction->in_time = $input['InTime'];
            $transaction->vehicle_type = $vehicleType;
            $transaction->vehicle_number = $txnVehicleNumber;
            $transaction->in_shift_id = $shiftId;
            $transaction->in_type = $inType;
            $transaction->in_type_id = $inTypeId;
            $transaction->in_gate = $gate_id;//$gate->gate_id;
            $transaction->out_gate = NULL;
            $transaction->in_user_id = $userId;
            $transaction->in_payment_mode = $inPaymentMode;
            $transaction->in_master_payment_mode = $inMasterPaymentMode;
            $transaction->in_day_type = $dayTypeEntry;
            $transaction->in_tariff_code = 0; //$tariffCode;
            $transaction->in_foc_difference = 0;
            $transaction->in_membership_payment_amount = 0;
            $transaction->in_payment_referance_number = 0;
            $transaction->in_payment_amount = 0;
            $transaction->in_standard_parking_amount = 0;
            $transaction->in_foc = 0;
            $transaction->in_foc_reason = 0;
            $transaction->in_foc_approval = 0;
            $transaction->is_nested = 0;
            $transaction->location_id = env('LOCATION_ID');
            $transaction->area_id = $area_id;//$area->area_id;
            $transaction->is_cps = 0;
            $transaction->in_foc_note = 0; // if having sent from binary
            $transaction->total_payment_amount = 0; //$PaymentEntryAmount + $inMembershipPaymentAmountEntry;
            $transaction->vip_membership_slot = ''; // if membership is existed then check sps_socket_server file live no 858
            $transaction->sync_at = "0000-00-00 00:00:00"; // if entry through cps then add date("Y-m-d H:i:s")
            $transaction->offline_ticket = NULL; // if entry through cps then value is 1
            $transaction->entry_process_time = date("Y-m-d H:i:s"); // current time
            $transaction->entry_type = 'FASTag';
            $transaction->fastag_vehicle_no = $fastagDetail['fastag_vehicle_no'];
            $transaction->fastag_exec_code = $fastagDetail['fastag_exec_code'];
            $transaction->fastag_exec_message = $fastagDetail['fastag_exec_message'];
            $transaction->fastag_tag_signature = $fastagDetail['tag_signature_data_hex'];
            $transaction->fastag_id = $fastagDetail['TAGID'];
            $transaction->fastag_epc = $fastagDetail['TID'];
            $transaction->fastag_lane = '';
            $transaction->fastag_exec_message = $fastagDetail['fastagMessage'];


            $transaction->in_type = $inType;
            $transaction->in_type_id = $inTypeId;
            $transaction->in_payment_mode = $inPaymentMode;
            $transaction->in_master_payment_mode = $inMasterPaymentMode;
            $transaction->save();

            $this->storeEntryVehImages($input, $transaction->id);


            
            foreach ($fastags as $fastag) {

                $validator = Validator::make($fastag, [
                    "epc_id" => "required|string|min:24",
                    "t_id" => "required|string|min:24",
                    "tag_signature_data_hex" => "required|string",
                ]);

                if (strlen($validator->errors()->first()) == 0) {
                    $fastagEntry = new FastagEntry();
                    $fastagEntry->txn_id = $transaction->id;
                    $fastagEntry->vehicle_no = 0;
                    $fastagEntry->fastag_id = $fastag['tag_id'];
                    $fastagEntry->fastag_no = $fastag['tag_id'];
                    $fastagEntry->tag_signature_data_hex = $fastag['tag_signature_data_hex'];
                    $fastagEntry->tag_vrn = $fastag['tag_vrn'];
                    $fastagEntry->issuer_bank_id = $fastag['issuer_bank_id'];
                    $fastagEntry->tag_v_class = $fastag['tag_v_class'];
                    $fastagEntry->rfu = $fastag['rfu'];
                    $fastagEntry->epc_id = $fastag['epc_id'];
                    $fastagEntry->user_memory = $fastag['user_memory'];
                    $fastagEntry->created_at = date('Y-m-d H:i:s');
                    $fastagEntry->save();
                }
            }

            $responseTxn = Transaction::where('id', $transaction->id)->first();

            return $responseTxn;

        }else{
            throw new \Exception('FASTag ERROR: DUPLICATE Vehicle OR CHESIS NO found - '.$fastagVechNo);
        }

        //Checking Gate has payment at entry or not
        // if ($gate->is_full == '1') {
        //     $paymentEntryParam = [
        //         'request' => $request,
        //         'shiftId' => $shiftId,
        //         'userId' => $userId,
        //         'inType' => $inType,
        //         'inTypeId' => $inTypeId,
        //         'inPaymentMode' => $inPaymentMode,
        //         'inMasterPaymentMode' => $inMasterPaymentMode,
        //         'gate' => $gate,
        //         'area' => $area,
        //         'location' => $location,
        //         'transaction' => $transaction,
        //         'membership' => $membership,
        //         'isFastagPayment' => $isFastagPayment,
        //         'laneId' => $laneId,
        //     ];
        //     $paymentAtEntryResponse = $this->requestPaymentAtEntry($paymentEntryParam);

        //     if (isset($paymentAtEntryResponse['status']) && !$paymentAtEntryResponse['status']) {
        //         throw new Exception($paymentAtEntryResponse['message']);
        //     }

        //     $response['payment_at_entry'] = $paymentAtEntryResponse;
        // }



    }



    /**
     * Validate location code and area code.
     *
     * @param $locationCode
     * @param $areaCode
     *
     * @return boolean
     */
    public function validateLocationAreaCode($locationCode, $areaCode)
    {
        if (config('sps.area_id') == $areaCode) {
            //check if location code is valid against location table
            $locationData = Location::where('location_code', $locationCode)->get()->toArray();
            if ($locationData) {
                return true;
            } else {
                return false;
            }
        }

        return false;
    }



    public function transactionFastag(FASTagRequest $request)
    {
        $response = '';
        $updateTransactionForFastagTagDetailForPayment = "";
      

        try {

            $statusTransaction = DB::transaction(function () use (&$request, &$response, &$updateTransactionForFastagTagDetailForPayment) {
                //Get input request parameters
                $input = $request->all();
                $checkShiftManagement = $this->checkShiftManagementValidation($input);
                if (!is_array($checkShiftManagement)) {
                    throw new Exception($checkShiftManagement);
                }

                $area = $checkShiftManagement['area'];
                $location = $checkShiftManagement['location'];
                $gate = $checkShiftManagement['gate'];
                $userId = $checkShiftManagement['userId'];
                $shiftId = $checkShiftManagement['shiftId'];
                $laneId = $input['laneId'];
                $txnBarCode = $input['barCode'];
                $vehicleNumber = !empty($input['vehicleNumber']) ? $input['vehicleNumber'] : "0";
                $tariff = !empty($input['tariff']) ? $input['tariff'] : "";
                $fastagExcutionType = $input['fastagExcutionType'];

                $isF8Txn = false;
                $f8TxnData = [];


                $sql = 'Select * from sps_transactions WHERE barcode= "'.$txnBarCode.'" AND deleted_at IS NULL';
                $results = DB::select(DB::raw($sql));


                //print_r(DB::getQueryLog());
                if (isset($results[0])) {
                    $f8TxnData = $results[0];
                    if($results[0]->f_eight == 1){
                        $isF8Txn = true;
                    }else{
                        $isF8Txn = false;
                    }
                } else {
                    $isF8Txn = false;
                }


                
                if($fastagExcutionType == "direct"){

                    //$this->directTransactionFastag($request);
                    $fastagExcutionType = $input['fastagExcutionType'];
        
                    $mixvehicleNumberArray = explode("-",  $vehicleNumber);
            
                    $transactionVehicleNumber =  $mixvehicleNumberArray[0];
                    $fastagVehicleNumber =  $mixvehicleNumberArray[1];
            

                }

                
                if (!$this->validateLocationAreaCode($location->location_code, $area->area_code)) {
                    throw new Exception('Invalid Location or Area Code');
                }


                if($input['Fastags']['Fastag']){
                    if ($this->FastagEntry->getBlockVehicleDetails($input)) { //check blocked vehicle on exit
                        throw new \Exception('RFID Member Vehicle');
                    }
                    $fastags = $input['Fastags']['Fastag'];
                    
                }else{
                    $fastags = [];
                    throw new Exception('FasTag Not Found');
    
    
                }



                
               
                $fastagType = "";


               
                //if (!empty($fastags)) {


                    if ($vehicleNumber != "0") {
                        
                        if($isF8Txn){
                            $response = $f8TxnData;
                        }else{
                            if($fastagExcutionType == "direct"){
                                $response = $this->FastagEntry->getTransactionDetailByVehicleNo($transactionVehicleNumber, $fastags);
                                $response->vehicle_number = $fastagVehicleNumber;
                            }else{
                                $response = $this->FastagEntry->getTransactionDetailByVehicleNo($vehicleNumber, $fastags);

                            }
                        }
                        //$response = $this->FastagEntry->getTransactionDetail($fastags);
                        $fastagType = "exit";
                    } else {

                        if($isF8Txn){
                            $response = $f8TxnData;
                        }else{

                            $response = $this->FastagEntry->getTransactionDetail($fastags);
                        }
                        $fastagType = "txn";


                    }


                    $fastagType = "exit";

                    

                    if (!empty($response)) {
                        // Checking transaction ID , data is saved properly or not.
                        $transaction = $response;

                        $vehicleNumber = $transaction->vehicle_number;
                        if (!empty($transaction->id)) {
                            if (!empty($fastags && is_array($fastags))) {
                                foreach ($fastags as $fastag) {

                                    $validator = Validator::make($fastag, [
                                        "epc_id" => "required|string|min:24",
                                        "t_id" => "required|string|min:24",
                                        "tag_signature_data_hex" => "required|string",
                                    ]);

                                    $fastagEntry = new FastagEntry();
                                    $fastagEntry->txn_id = $transaction->id;
                                    $fastagEntry->vehicle_no = $transaction->vehicle_number;
                                    $fastagEntry->fastag_id = $fastag['tag_id'];
                                    $fastagEntry->fastag_no = $fastag['tag_id'];
                                    $fastagEntry->tag_signature_data_hex = $fastag['tag_signature_data_hex'];
                                    $fastagEntry->tag_vrn = $fastag['tag_vrn'];
                                    $fastagEntry->issuer_bank_id = $fastag['issuer_bank_id'];
                                    $fastagEntry->tag_v_class = $fastag['tag_v_class'];
                                    $fastagEntry->rfu = $fastag['rfu'];
                                    $fastagEntry->epc_id = $fastag['epc_id'];
                                    $fastagEntry->user_memory = $fastag['user_memory'];
                                    $fastagEntry->used_for_payment = "1";
                                    $fastagEntry->created_at = date('Y-m-d H:i:s');
                                    $fastagEntry->save();

                                    //print_r(DB::getQueryLog());

                                }
                            }
                        }

                    }else {
                        throw new Exception('Vehicle not found');
                    }
                    //print_r($response);
                    //die("dfdfdfdf");
                    // if (!$response) {
                    //     throw new Exception('Transaction is not found');
                    // }
                //} else {
                //    throw new Exception('FASTag IDs are not found');
                //}

                //print_r($response);

                // call FASTag Engine for updating FASTag tag details e.g. vehicle no, tag status
                $updateTransactionForFastagTagDetailForPayment = $this->updateTransactionForFastagTagDetailForPayment($response, $laneId, $fastagType, $fastags);

            });


            if ($updateTransactionForFastagTagDetailForPayment != "00") {
                //throw new Exception($updateTransactionForFastagTagDetailForPayment);
                //$responseMessage = $this->getFastagErrorMessage($updateTransactionForFastagTagDetailForPayment);

                $fastagExecMessage = $response->fastag_exec_message;
                $fastagTagId = $response->fastag_id;
                //die("here");
                //print_r($updateTransactionForFastagTagDetailForPayment);

                $responseMessage_final = $this->getFastagErrorMessage($updateTransactionForFastagTagDetailForPayment);
                $responseMessage = "TAG Id: " . $fastagTagId . ", Error: ".$updateTransactionForFastagTagDetailForPayment."-". $responseMessage_final . " - " . $fastagExecMessage . ". Please Manually exit vehicle.";


                if (str_contains($responseMessage, '#423#')) { 
                    return $this->sendFastageError(' Error: ' . $responseMessage, [], 423);
                }else{
                    return $this->sendFastageError(' Error: ' . $responseMessage, [], 422);
                }

                //print_r($response);
                //return $this->sendFastageResponse($response, $responseMessage, 422);
                

            } else {

                if (is_null($statusTransaction)) {
                    $this->createLog(true, $this->logPath, "Get FASTag Information Transaction ", $request->all(), $this->sendFastageResponse($response, 'Successfully'));
                    return $this->sendFastageResponse($response, 'Successfully');

                } else {

                    throw new Exception('Transaction is not found');
                }

            }


        } catch (\Exception $e) {

            //print_r($e->getMessage());
            $this->createLog(false, $this->logPath, "FASTag info Transaction ", $request->all(), $this->sendFastageError(' Error: ' . $e->getMessage(), [], 422));

            $responseMessage = "";
            if (is_numeric($e->getMessage())) {
                $responseMessage = $this->getFastagErrorMessage($e->getMessage());
            } else {
                //print_r($e->getMessage());
                $responseMessage = $e->getMessage()." ";
            }

            $responseMessage = $responseMessage . ". Please use F8 for exit vehicle.";

            //$responseMessage = $e->getMessage();

            if($e->getMessage() == "Vehicle not found"){
                return $this->sendFastageError(' Error: ' . $responseMessage, [], 421);
            }else{

                if (str_contains($responseMessage, '#423#')) { 
                    return $this->sendFastageError(' Error: ' . $responseMessage, [], 423);
                }else{
                    return $this->sendFastageError(' Error: ' . $responseMessage, [], 422);
                }
            }
        }
    }




    public function transactionFastag_ollddd(FASTagRequest $request)
    {
        $response = '';
        $updateTransactionForFastagTagDetailForPayment = "";
      

        try {

            $statusTransaction = DB::transaction(function () use (&$request, &$response, &$updateTransactionForFastagTagDetailForPayment) {
                //Get input request parameters
                $input = $request->all();
                $checkShiftManagement = $this->checkShiftManagementValidation($input);
                if (!is_array($checkShiftManagement)) {
                    throw new Exception($checkShiftManagement);
                }

                $area = $checkShiftManagement['area'];
                $location = $checkShiftManagement['location'];
                $gate = $checkShiftManagement['gate'];
                $userId = $checkShiftManagement['userId'];
                $shiftId = $checkShiftManagement['shiftId'];
                $laneId = $input['laneId'];
                $vehicleNumber = !empty($input['vehicleNumber']) ? $input['vehicleNumber'] : "0";
                $tariff = !empty($input['tariff']) ? $input['tariff'] : "";

                $fastagExcutionType = $input['fastagExcutionType'];
                
                if($fastagExcutionType == "direct"){

                    //$this->directTransactionFastag($request);
                    $fastagExcutionType = $input['fastagExcutionType'];
        
                    $mixvehicleNumberArray = explode("-",  $vehicleNumber);
            
                    $transactionVehicleNumber =  $mixvehicleNumberArray[0];
                    $fastagVehicleNumber =  $mixvehicleNumberArray[1];
            

                }

                
                if (!$this->validateLocationAreaCode($location->location_code, $area->area_code)) {
                    throw new Exception('Invalid Location or Area Code');
                }


                if($input['Fastags']['Fastag']){
                    if ($this->FastagEntry->getBlockVehicleDetails($input)) { //check blocked vehicle on exit
                        throw new \Exception('RFID Member Vehicle');
                    }
    
                    $fastags = $input['Fastags']['Fastag'];

                }else{
                    $fastags = [];
                }



                
               
                $fastagType = "";


               
                //if (!empty($fastags)) {


                    if ($vehicleNumber != "0") {

                        if($fastagExcutionType == "direct"){
                            $response = $this->FastagEntry->getTransactionDetailByVehicleNo($transactionVehicleNumber, $fastags);
                            $response->vehicle_number = $fastagVehicleNumber;
                        }else{
                            $response = $this->FastagEntry->getTransactionDetailByVehicleNo($vehicleNumber, $fastags);

                        }
                        //$response = $this->FastagEntry->getTransactionDetail($fastags);
                        $fastagType = "exit";
                    } else {

                        $response = $this->FastagEntry->getTransactionDetail($fastags);
                        $fastagType = "txn";

                    }


                    $fastagType = "exit";

                    

                    if (!empty($response)) {
                        // Checking transaction ID , data is saved properly or not.
                        $transaction = $response;

                        $vehicleNumber = $transaction->vehicle_number;
                        if (!empty($transaction->id)) {
                            if (!empty($fastags && is_array($fastags))) {
                                foreach ($fastags as $fastag) {

                                    $validator = Validator::make($fastag, [
                                        "epc_id" => "required|string|min:24",
                                        "t_id" => "required|string|min:24",
                                        "tag_signature_data_hex" => "required|string",
                                    ]);

                                    $fastagEntry = new FastagEntry();
                                    $fastagEntry->txn_id = $transaction->id;
                                    $fastagEntry->vehicle_no = $transaction->vehicle_number;
                                    $fastagEntry->fastag_id = $fastag['tag_id'];
                                    $fastagEntry->fastag_no = $fastag['tag_id'];
                                    $fastagEntry->tag_signature_data_hex = $fastag['tag_signature_data_hex'];
                                    $fastagEntry->tag_vrn = $fastag['tag_vrn'];
                                    $fastagEntry->issuer_bank_id = $fastag['issuer_bank_id'];
                                    $fastagEntry->tag_v_class = $fastag['tag_v_class'];
                                    $fastagEntry->rfu = $fastag['rfu'];
                                    $fastagEntry->epc_id = $fastag['epc_id'];
                                    $fastagEntry->user_memory = $fastag['user_memory'];
                                    $fastagEntry->used_for_payment = "1";
                                    $fastagEntry->created_at = date('Y-m-d H:i:s');
                                    $fastagEntry->save();

                                    //print_r(DB::getQueryLog());

                                }
                            }
                        }

                    }else {
                        throw new Exception('Vehicle not found');
                    }
                    //print_r($response);
                    //die("dfdfdfdf");
                    // if (!$response) {
                    //     throw new Exception('Transaction is not found');
                    // }
                //} else {
                //    throw new Exception('FASTag IDs are not found');
                //}

                //print_r($response);

                // call FASTag Engine for updating FASTag tag details e.g. vehicle no, tag status
                $updateTransactionForFastagTagDetailForPayment = $this->updateTransactionForFastagTagDetailForPayment($response, $laneId, $fastagType, $fastags);

            });


            if ($updateTransactionForFastagTagDetailForPayment != "00") {
                //throw new Exception($updateTransactionForFastagTagDetailForPayment);
                //$responseMessage = $this->getFastagErrorMessage($updateTransactionForFastagTagDetailForPayment);

                $fastagExecMessage = $response->fastag_exec_message;
                $fastagTagId = $response->fastag_id;
                //die("here");
                //print_r($updateTransactionForFastagTagDetailForPayment);

                $responseMessage_final = $this->getFastagErrorMessage($updateTransactionForFastagTagDetailForPayment);
                $responseMessage = "TAG Id: " . $fastagTagId . ", Error: ".$updateTransactionForFastagTagDetailForPayment."-". $responseMessage_final . " - " . $fastagExecMessage . ". Please Manually exit vehicle.";


                if (str_contains($responseMessage, '#423#')) { 
                    return $this->sendFastageError(' Error: ' . $responseMessage, [], 423);
                }else{
                    return $this->sendFastageError(' Error: ' . $responseMessage, [], 422);
                }

                //print_r($response);
                //return $this->sendFastageResponse($response, $responseMessage, 422);
                

            } else {

                if (is_null($statusTransaction)) {
                    $this->createLog(true, $this->logPath, "Get FASTag Information Transaction ", $request->all(), $this->sendFastageResponse($response, 'Successfully'));
                    return $this->sendFastageResponse($response, 'Successfully');

                } else {

                    throw new Exception('Transaction is not found');
                }

            }


        } catch (\Exception $e) {

            //print_r($e->getMessage());
            $this->createLog(false, $this->logPath, "FASTag info Transaction ", $request->all(), $this->sendFastageError(' Error: ' . $e->getMessage(), [], 422));

            $responseMessage = "";
            if (is_numeric($e->getMessage())) {
                $responseMessage = $this->getFastagErrorMessage($e->getMessage());
            } else {
                //print_r($e->getMessage());
                $responseMessage = $e->getMessage()." ";
            }

            $responseMessage = $responseMessage . ". Please use F8 for exit vehicle.";

            //$responseMessage = $e->getMessage();

            if($e->getMessage() == "Vehicle not found"){
                return $this->sendFastageError(' Error: ' . $responseMessage, [], 421);
            }else{

                if (str_contains($responseMessage, '#423#')) { 
                    return $this->sendFastageError(' Error: ' . $responseMessage, [], 423);
                }else{
                    return $this->sendFastageError(' Error: ' . $responseMessage, [], 422);
                }
            }
        }
    }




    public function directTransactionFastag($request){


        $input = $request->all();
        $checkShiftManagement = $this->checkShiftManagementValidation($input);
        if (!is_array($checkShiftManagement)) {
            throw new Exception($checkShiftManagement);
        }

        $area = $checkShiftManagement['area'];
        $location = $checkShiftManagement['location'];
        $gate = $checkShiftManagement['gate'];
        $userId = $checkShiftManagement['userId'];
        $shiftId = $checkShiftManagement['shiftId'];
        $laneId = $input['laneId'];
        $vehicleNumber = !empty($input['vehicleNumber']) ? $input['vehicleNumber'] : "0";
        $tariff = !empty($input['tariff']) ? $input['tariff'] : "";

        $fastagExcutionType = $input['fastagExcutionType'];
        
        $mixvehicleNumberArray = explode("-",  $vehicleNumber);

        $transactionVehicleNumber =  $mixvehicleNumberArray[0];
        $fastagVehicleNumber =  $mixvehicleNumberArray[1];

        


        if (!$this->validateLocationAreaCode($location->location_code, $area->area_code)) {
            throw new Exception('Invalid Location or Area Code');
        }

        if ($this->FastagEntry->getBlockVehicleDetails($input)) { //check blocked vehicle on exit
            throw new \Exception('RFID Member Vehicle');
        }


        //$fastags = $input['Fastags']['Fastag'];

        if($input['Fastags']['Fastag']){
            // if ($this->FastagEntry->getBlockVehicleDetails($input)) { //check blocked vehicle on exit
            //     throw new \Exception('RFID Member Vehicle');
            // }

            $fastags = $input['Fastags']['Fastag'];

        }else{
            $fastags = [];
        }




        $fastagType = "";



        if (!empty($fastags)) {


            if ($vehicleNumber != "0") {
                $response = $this->FastagEntry->getTransactionDetailByVehicleNo($transactionVehicleNumber, $fastags);
                //$response = $this->FastagEntry->getTransactionDetail($fastags);
                $fastagType = "exit";
            } else {

                $response = $this->FastagEntry->getTransactionDetail($fastags);
                $fastagType = "txn";

            }

            $response->vehicle_number = $fastagVehicleNumber;



            $fastagType = "exit";

            if (!empty($response)) {
                // Checking transaction ID , data is saved properly or not.
                $transaction = $response;

                $vehicleNumber = $fastagVehicleNumber;
                if (!empty($transaction->id)) {
                    if (!empty($fastags && is_array($fastags))) {
                        foreach ($fastags as $fastag) {

                            $validator = Validator::make($fastag, [
                                "epc_id" => "required|string|min:24",
                                "t_id" => "required|string|min:24",
                                "tag_signature_data_hex" => "required|string",
                            ]);


                            $fastagEntry = new FastagEntry();
                            $fastagEntry->txn_id = $transaction->id;
                            $fastagEntry->vehicle_no = $fastagVehicleNumber;
                            $fastagEntry->fastag_id = $fastag['tag_id'];
                            $fastagEntry->fastag_no = $fastag['tag_id'];
                            $fastagEntry->tag_signature_data_hex = $fastag['tag_signature_data_hex'];
                            $fastagEntry->tag_vrn = $fastag['tag_vrn'];
                            $fastagEntry->issuer_bank_id = $fastag['issuer_bank_id'];
                            $fastagEntry->tag_v_class = $fastag['tag_v_class'];
                            $fastagEntry->rfu = $fastag['rfu'];
                            $fastagEntry->epc_id = $fastag['epc_id'];
                            $fastagEntry->user_memory = $fastag['user_memory'];
                            $fastagEntry->used_for_payment = "1";
                            $fastagEntry->created_at = date('Y-m-d H:i:s');
                            $fastagEntry->save();

                        }
                    }
                }

            }else {
                throw new Exception('Vehicle not found');
            }
            //print_r($response);
            //die("dfdfdfdf");
            // if (!$response) {
            //     throw new Exception('Transaction is not found');
            // }
        } else {
            throw new Exception('FASTag IDs are not found');
        }

        //print_r($response);

        // call FASTag Engine for updating FASTag tag details e.g. vehicle no, tag status
        $updateTransactionForFastagTagDetailForPayment = $this->updateTransactionForFastagTagDetailForPayment($response, $laneId, $fastagType, $fastags);

    }


    
    public function requestPayFastag(FASTagRequest $request)
    {
        $response = [];
        $responseMsg = '';
        $transactionDetails = '';
        try {

            $statusExitTransaction = DB::transaction(function () use (&$request, &$response, &$responseMsg, &$transactionDetails) {
                //Get input request parameters
                $input = $request->all();
                $isFastagPayment = $input['isFastagPayment'];
                $barcode = $input['Barcode'];
                $laneId = $input['laneId'];
                $setting = $this->settings;
                $checkShiftManagement = $this->checkShiftManagementValidation($input, "Exit");

                if (!is_array($checkShiftManagement)) {
                    throw new Exception($checkShiftManagement);
                }

                $area = $checkShiftManagement['area'];
                $location = $checkShiftManagement['location'];
                $gate = $checkShiftManagement['gate'];
                $userId = $checkShiftManagement['userId'];
                $shiftId = $checkShiftManagement['shiftId'];

                $fastags = "";
                $transactionId = '';
                $response = [];


                $isF8Txn = false;
                $isCPSTxn = false;
                $f8TxnData = [];


                $sql = 'Select * from sps_transactions WHERE barcode= "'.$barcode.'" AND deleted_at IS NULL';
                $results = DB::select(DB::raw($sql));


                //print_r(DB::getQueryLog());
                if (isset($results[0])) {
                    $f8TxnData = $results[0];
                    if($results[0]->f_eight == 1){
                        $isF8Txn = true;
                    }else{
                        $isF8Txn = false;
                    }

                    if($results[0]->is_cps == 1){
                        $isCPSTxn = true;
                    }else{
                        $isCPSTxn = false;
                    }

                } else {
                    $isF8Txn = false;
                }




                if($isF8Txn){
                    $transaction = $f8TxnData;
                }else{
                    $transaction = $this->FastagEntry->getTransactionDetailByBarcode($barcode);

                }



                if (!$transaction) {
                    throw new Exception('Vehicle Not Present. Use F8 for exit Vehicle');
                }
                $transactionId = $transaction->id;


                // $checkIfVehicleExist = Transaction::where('vehicle_number',$vehicleNo)->where('out_time', '=', '0000-00-00 00:00:00')->count();
                // //dd(DB::getQueryLog());
                // if ($checkIfVehicleExist > 1) {
                //     Transaction::where('id', $txnid)-> ();
                //     throw new \Exception('There are some error with fastag, Please choose other payment method.');
                // }



                if($isF8Txn){
                    $checkExitTransaction = (array)$f8TxnData;
                }else{
                    // Checking exit vehicle
                    $checkExitTransaction = $this->FastagEntry->checkVehicleExitTransaction($transaction->id);

                    if ($checkExitTransaction === true) {
                        throw new Exception('Vehicle Already Exited.');
                    }
                }



                $dayTypeExit = $this->getDaytype($area->area_id, $location->location_id, $input['OutTime']);

                //Getting FASTag Payment Modes
                $paymentMode = $this->PaymentMode->getpaymentModeList(["keyword" => "FASTag", "perpage" => false]);
                $paymentMode = $paymentMode->toArray();

                //Out Gate ID
                $outPaymentModeId = isset($paymentMode['data'][0]['id']) ? $paymentMode['data'][0]['id'] : 8;

                $transactionDetails = $checkExitTransaction;
                $inGateId = $transactionDetails['in_gate'];
                $inTimeEntry = $transactionDetails['in_time'];
                $vehicleType = $transactionDetails['vehicle_type'];
                $transactionData = [];
                $transactionData['vehicle_info'] = $transactionDetails;
                $transactionData['id'] = $transactionId;
                $transactionData['barcode'] = $transactionDetails['barcode'];
                $transactionData['vehicle_type'] = $vehicleType;
                $transactionData['vehicle_number'] = $transactionDetails['vehicle_number'];

                $transactionData['in_time'] = $inTimeEntry;
                $transactionData['out_time'] = $input['OutTime'];
                $transactionData['in_gate'] = $inGateId;
                $transactionData['out_gate'] = $gate->gate_id;
                $transactionData['location'] = $location;
                $transactionData['area'] = $area;
                $outGateId = $gate->gate_id;
                $outGateType=$gate->gate_type;
                $payAmount = $input['tariff'];
                $paymentOrderId = '';
                






                $outMasterPaymentMode = isset($paymentMode['data'][0]['master_id']) ? $paymentMode['data'][0]['master_id'] : 4;
                $outTypeId = 0;
                $outTypeEntryGate = 1;
                $payMembershipAmount = 0;
                $transactionType = "";
                $input['fastagId'] = $transactionDetails['fastag_id'];
                //If FASTag has Sticker membership.
                $membership = $this->StickerMembership->getStickerMembershipByVehicleNo($input);


                if ($membership) {
                    $outTypeEntryGate = 5;
                    $outTypeId = $membership[0]->membership_id;
                    $outPaymentModeId = 0;
                    $outMasterPaymentMode = 3;
                    $payMembershipAmount = $payAmount;
                    $transactionType = "Sticker Membership";
                }else{
                    if(!$isCPSTxn){
                        if(floatval($payAmount) < 1){
                            throw new Exception('There is some issue. Please manually exit vehicle.');
                        }
    
                    }

                }

                $totalTimeSpent = $this->getTotalTimeSpent($inTimeEntry, $input['OutTime']);

                $tariff['total_time'] = $totalTimeSpent;
                $tariff['vehicle_type'] = $vehicleType;
                $tariff['day_type'] = $dayTypeExit;
                $tariff['status'] = 1;

                $tariffCodeDetails = $this->Tariff->getTariffList($tariff);
                $tariffCode = 0;
                if (!empty($tariffCodeDetails)) {
                    $tariffCode = $tariffCodeDetails->first()->tariff_code;
                }

                $this->storeExitVehImages($input, $transaction->id);
                //Start - Update sps_transaction  using transction id
                if($tariffCodeDetails->first()->payment_at_entry == 1){
                   
                        $paymentData = [
                            'exit_type' => 'FASTag',
                            'entry_type' => 'FASTag',
                            'fastag_pay' => 'pending'];
                    
    
                    $updateTransaction = Transaction::where('id', $transactionId)
                        ->update($paymentData);
    

                }else{
                    $fastag_f_eight_in_gate = $setting->fastag_f_eight_in_gate;

                    if($isF8Txn){

                        
                        $updateTransactionData = [
                            'in_gate' => $fastag_f_eight_in_gate,
                            'out_payment_mode' => $outPaymentModeId,
                            'out_master_payment_mode' => $outMasterPaymentMode,
                        ];
            
                        if ($isFastagPayment && $outTypeEntryGate != 5) {
                            $paymentData = [
                                'exit_type' => 'FASTag',
                                'fastag_pay' => 'pending'];
                            $updateTransactionData = array_merge($paymentData, $updateTransactionData);
                        }
        
                        $updateTransaction = Transaction::where('id', $transactionId)->update($updateTransactionData);

                    }else if($isCPSTxn){

                        if($payAmount == "0"){
                            $outMasterPaymentMode = 4;
                            $outPaymentModeId = 8;
                        }
                        $updateTransactionData =[
                            'out_payment_mode' => $outPaymentModeId,
                            'out_master_payment_mode' => $outMasterPaymentMode
                        ];

                        if($outGateType!=5){

                            $updateTransactionData = [
                                'out_time' => $input['OutTime'],
                                'total_time' => round($totalTimeSpent['minutes']),
                                'out_shift_id' => $shiftId,
                                'out_type' => $outTypeEntryGate, //  1for normal entry, 2 for membership entry
                                'out_type_id' => $outTypeId,
                                'out_gate' => $outGateId,
                                'out_user_id' => $userId,
                                'out_payment_mode' => $outPaymentModeId,
                                'out_master_payment_mode' => $outMasterPaymentMode,
                                'out_day_type' => $dayTypeExit,
                                'out_tariff_code' => $tariffCode,
                                'out_membership_payment_amount' => $payMembershipAmount,
                                'out_payment_amount' => $payAmount,
                                'out_standard_parking_amount' => $payAmount,
                                'total_payment_amount' => $payAmount,
                                'penalty_charge' => 0, // no penalty here
                                'overnight_charges' => 0,
                                'additional_charges' => 0,
                                'exit_process_time' => date("Y-m-d H:i:s"),
                                'in_gate' => $fastag_f_eight_in_gate
                            ];

                        }
                        

            
                        if ($isFastagPayment && $outTypeEntryGate != 5 && $payAmount != "0") {
                            $paymentData = [

                                'exit_type' => 'FASTag',
                                'fastag_pay' => 'pending'];
                            $updateTransactionData = array_merge($paymentData, $updateTransactionData);
                        }
        
                        $updateTransaction = Transaction::where('id', $transactionId)->update($updateTransactionData);


                    }else{

                        $updateTransactionData = [
                            'out_time' => $input['OutTime'],
                            'total_time' => round($totalTimeSpent['minutes']),
                            'out_shift_id' => $shiftId,
                            'out_type' => $outTypeEntryGate, //  1for normal entry, 2 for membership entry
                            'out_type_id' => $outTypeId,
                            'out_gate' => $outGateId,
                            'out_user_id' => $userId,
                            'out_payment_mode' => $outPaymentModeId,
                            'out_master_payment_mode' => $outMasterPaymentMode,
                            'out_day_type' => $dayTypeExit,
                            'out_tariff_code' => $tariffCode,
                            'out_membership_payment_amount' => $payMembershipAmount,
                            'out_payment_amount' => $payAmount,
                            'out_standard_parking_amount' => $payAmount,
                            'total_payment_amount' => $payAmount,
                            'penalty_charge' => 0, // no penalty here
                            'overnight_charges' => 0,
                            'additional_charges' => 0,
                            'exit_process_time' => date("Y-m-d H:i:s"),
                        ];
            
                        if ($isFastagPayment && $outTypeEntryGate != 5) {
                            $paymentData = [
                                'exit_type' => 'FASTag',
                                'fastag_pay' => 'pending'];
                            $updateTransactionData = array_merge($paymentData, $updateTransactionData);
                        }
        
                        $updateTransaction = Transaction::where('id', $transactionId)->update($updateTransactionData);
                    }
    

                }
                
                if($isCPSTxn){
                    $updatedTxn = $this->FastagEntry->getCPSFastagTransaction($transactionId);
                }else{
                    $updatedTxn = $this->FastagEntry->getFastagTransaction($transactionId);
                }



                $response['transaction_details'] = $updatedTxn;
                //End - Update sps_transaction  using transction id
                $responseMsg = 'Vehicle Successfully Detail Fetched';

               
                if (!$updateTransaction) {
                    throw new \Exception('Error While Updating Transaction');
                }
            });

            if (is_null($statusExitTransaction)) {
                //$responseMsg = "Transaction Details";
                //$response['transaction_info'] = $transactionDetails;
                $this->createLog(true, $this->logPath, "FASTag Exit ", $request->all(), $this->sendFastageResponse($response, $responseMsg));
                return $this->sendFastageResponse($response, $responseMsg);
            }
            $this->createLog(true, $this->logPath, "FASTag Exit ", $request->all(), "Error While Processing Transaction");
            throw new \Exception("Error While Processing Transaction");

        } catch (\Exception $e) {
            $this->createLog(false, $this->logPath, "FASTag  Exit ", $request->all(), $this->sendFastageError(' Error : ' . $e->getMessage(), [], 422));
            return $this->sendFastageError(' Error : ' . $e->getMessage(), [], 422);
        }
    }


    public function whitelistedFastag(Request $request)
    {
        try {
            $input = $request->all();

            //Validate request parameters
            $validator = Validator::make($input, [
                'Fastag' => 'required',
            ]);

            if ($validator->fails()) {
                throw new Exception('Validation Error4.' . $validator->errors()->first());
            }

            return $this->reqQueryExceptionList($input['Fastag']);

        } catch (Exception $e) {
            $this->createLog(false, $this->logPath, "FASTag Exit ", $request->all(), $e->getMessage());

            return $this->sendFastageError('Validation Error5.' . $e->getMessage(), 422);
        }

    }


    public function validateVehicleFASTag(FASTagRequest $request){

        $response = [];
        $input = $request->all();
        $vehNo = $input["vehicleNumber"];
        $tagStatus  = $this->validateFastagVehicleNumber($vehNo);
        $response['tagStatus'] = $tagStatus;
        return $this->sendFastageResponse($response, 'Successfully'); 
        //die("here");
    }

    public function fastagConfiguration()
    {
        try {
            $monitoringData = [];
            $html = \View::make('admin.fastag_configuration', array('monitoringData' => $monitoringData))->render();
            return \Response::json(array('html' => $html));
        } catch (\Exception $e) {
            return $e->getMessage();
            exit;
        }
    }

    public function requestPaymentAtEntry($paymentEntryParam)
    {
        $response = [];
        $request = $paymentEntryParam['request'];
        try {
            $exitTransactionDBStatus = DB::transaction(function () use (&$response, &$request, &$paymentEntryParam) {

                $shiftId = $paymentEntryParam['shiftId'];
                $userId = $paymentEntryParam['userId'];
                $inType = $paymentEntryParam['inType'];
                $inTypeId = $paymentEntryParam['inTypeId'];
                $inPaymentMode = $paymentEntryParam['inPaymentMode'];
                $inMasterPaymentMode = $paymentEntryParam['inMasterPaymentMode'];
                $gate = $paymentEntryParam['gate'];
                $area = $paymentEntryParam['area'];
                $location = $paymentEntryParam['location'];
                $transaction = $paymentEntryParam['transaction'];
                $membership = $paymentEntryParam['membership'];
                $isFastagPayment = $paymentEntryParam['isFastagPayment'];
                $laneId = $paymentEntryParam['laneId'];

                $input = $request->all();
                $transaction = $transaction->toArray();
                $transactionId = $transaction['id'];
                $inTimeEntry = $input['InTime'];
                $dayTypeEntry = $this->getDaytype($area->area_id, $location->location_id, $input['InTime']);

                $params = [
                    'id' => $transactionId,
                    'barcode' => $transaction['barcode'],
                    'location' => $location,
                    'area' => $area,
                    'in_time' => $inTimeEntry,
                    'out_time' => $inTimeEntry,
                    'in_gate' => $gate->gate_id,
                    'out_gate' => $gate->gate_id,
                    'vehicle_type' => $transaction['vehicle_type'],
                    'gate_id' => $gate->gate_id,
                    'day_type' => $dayTypeEntry,
                    'vehicle_number' => 0,
                ];

                $getTariff = $this->getTariff($params);

                if (isset($getTariff['status']) && !$getTariff['status']) {
                    $message = isset($getTariff['message']) ? $getTariff['message'] : "Something went wrong. Please try again";
                    throw new Exception($message);
                }

                $totalPaymentAmount = isset($getTariff['parking_tariff']['total_payable']) ? $getTariff['parking_tariff']['total_payable'] : 0;
                $additionalAmount = isset($getTariff['tariff_info']['additional_tariff']['tariff'][0]['additional_tariff']) ? $getTariff['tariff_info']['additional_tariff']['tariff'][0]['additional_tariff'] : 0;
                $overnightCharge = isset($getTariff['parking_tariff']['tariff']['overnight_charge']) ? $getTariff['parking_tariff']['tariff']['overnight_charge'] : 0;

                $inMembershipTotalPaymentAmount = 0;
                if ($membership) {
                    $inMembershipTotalPaymentAmount = $totalPaymentAmount;
                }

                $transactionData = [
                    'in_membership_payment_amount' => $inMembershipTotalPaymentAmount,
                    'in_payment_amount' => $totalPaymentAmount,
                    'in_standard_parking_amount' => $totalPaymentAmount,
                    'out_time' => $inTimeEntry,
                    'total_time' => $getTariff['vehicle_info']['parking_duration_in_min'],
                    'out_shift_id' => $shiftId,
                    'out_type' => $inType, //  1 for normal entry, 2 for membership entry
                    'out_type_id' => $inTypeId,
                    'out_gate' => $gate->gate_id,
                    'out_user_id' => $userId,
                    'out_payment_mode' => $inPaymentMode,
                    'out_master_payment_mode' => $inMasterPaymentMode,
                    'out_day_type' => $dayTypeEntry,
                    'out_tariff_code' => isset($getTariff['tariff_info']['casual_tariff']['casual_tariff_code']) ? $getTariff['tariff_info']['casual_tariff']['casual_tariff_code'] : 0,
                    'out_payment_amount' => $totalPaymentAmount,
                    'out_standard_parking_amount' => $totalPaymentAmount,
                    'total_payment_amount' => $totalPaymentAmount,
                    'penalty_charge' => 0, // no penalty here
                    'overnight_charges' => $overnightCharge,
                    'additional_charges' => $additionalAmount,
                    'exit_type' => 'FASTag',
                    'exit_process_time' => date("Y-m-d H:i:s"),
                ];
                //Start - Update sps_transaction  using transction id


                // If FASTag payment is true then it go for FASTag payment
                if ($isFastagPayment && $inType != 5) {
                    $transactionData = array_merge(['exit_type' => 'FASTag', 'fastag_pay' => 'pending'], $transactionData);
                }

                $updateTransaction = Transaction::where('id', $transactionId)
                    ->update($transactionData);
                //End - Update sps_transaction  using transction id

                if (!$updateTransaction) {
                    throw new Exception('Error While Updating Transaction');
                }
                $response['transaction_details'] = $updateTransaction;
            });

            if (is_null($exitTransactionDBStatus)) {
                return $response;
            } else {
                throw new Exception('Error While Entry Process');
            }
        } catch (Exception $e) {
            $this->createLog(false, $this->logPath, "FASTag Entry ", $request->all(), $e->getMessage());
            return ["status" => false, "message" => $e->getMessage()];
        }
    }

    private function checkShiftManagementValidation($input, $type = "Entry")
    {
        $data = [];
        try {
            $setting = $this->settings;
            $area = Area::where('area_id', $setting->area_id)->first();
            $location = Location::where('location_id', $setting->location_id)->first();

            //validate location code and area code
            if (!$this->validateLocationAreaCode($location->location_code, $area->area_code)) {
                throw new Exception('Invalid Location or Area Code');
            }

            $userName = $input['User'];
            $userId = $this->User->getUserIdWithUsername($userName); // getting user id

            if (!$userId) { // if user id is not found then send error
                throw new Exception('User has not been found');
            }

            $gate = $this->Gate->getGateDetailByIP($input['IP']); // get gate details

            if (!$gate) { // send error if gate id not found
                throw new Exception('Gate has not been found');
            }

            if ($gate->fastag != 1) { // send error if gate is not enable for fastag
                throw new Exception('FASTag is not enable for gate');
            }

            if ($input['IP'] != $gate->ip_address) { // verify gate IP
                throw new Exception('IP has not been match');
            }

            $shiftId = $this->ShiftManagment->getShiftIdByUserId($userId); // getting shift id

            if (!$shiftId) { // send error if shift id is not found
                throw new Exception('Shift ID has not been assign');
            }

            $data['area'] = $area;
            $data['location'] = $location;
            $data['userId'] = $userId;
            $data['gate'] = $gate;
            $data['shiftId'] = $shiftId;

            return $data;
        } catch (Exception $e) {
            return $e->getMessage();
        }

    }

    public function getFastagErrorMessage($checkFastagTagStatus)
    {
        if ($checkFastagTagStatus) {
            $errorMsg = FastagErrorList::where('error_code', $checkFastagTagStatus)->get()->first();
            if (!empty($errorMsg)) {
                return $errorMsg->description;
            }
            return '';
        }
        return '';
    }


}
