<?php



namespace Modules\HoldSeat\Controllers;



use App\Controllers\BaseController;

use Modules\HoldSeat\Models\HoldSeatModel;

use Modules\Company\Models\CompanyModel;

use Modules\Trip\Models\SubtripModel;

use Modules\Location\Models\LocationModel;

use App\Libraries\Rolepermission;

use Modules\Trip\Models\TripModel;

use Modules\Fleet\Models\FleetModel;

use Modules\Fleet\Models\VehicleModel;

use Modules\Employee\Models\EmployeeModel;

use Modules\Ticket\Models\TemporaryBook;

use Modules\Ticket\Models\TicketModel;

use App\Libraries\HoldSeatSupport;



class HoldSeat extends BaseController

{

    protected $holdSeatModel;

    protected $companyModel;

    protected $vehicleModel;

    protected $fleetTypeModel;

    protected $employeeModel;

    protected $TemporaryBook;

    protected $ticketModel;
    
    protected $db;



    public function __construct()

    {

        $this->holdSeatModel = new HoldSeatModel();

        $this->companyModel = new CompanyModel();

        $this->tripModel = new TripModel();

        $this->subtripModel = new SubtripModel();

        $this->locationModel = new LocationModel();

        $this->fleetTypeModel = new FleetModel();

        $this->vehicleModel = new VehicleModel();

        $this->employeeModel = new EmployeeModel();

        $this->TemporaryBook = new TemporaryBook();

        $this->ticketModel = new TicketModel();

        $this->db = \Config\Database::connect();


        $this->Viewpath = "Modules\HoldSeat\Views\holdseat";

    }



    public function index()

    {

        $data['module'] = lang("Localize.hold_seat");

        $data['title'] = lang("Localize.hold_seat");

        $data['pageheading'] = lang("Localize.hold_seat_list");

        

        $roleId     = session()->get("role_id");

        $companyId  = session()->get("company_id");

        if($roleId == 1){

            $data['holdSeats'] = $this->holdSeatModel

                                    ->select("hold_seats.*, companies.name as companyname, trips.*, subtrips.*, pic_location.name as pic_location_name,

                                    hold_seats.id as hold_id,hold_seats.status as hold_status, drop_location.name as drop_location_name, hold_seats.startdate as startdate")

                                    ->join('companies', 'companies.id = hold_seats.company_id', "left")

                                    ->join('trips', 'trips.id = hold_seats.trip_id', "left")

                                    ->join('subtrips', 'subtrips.id = hold_seats.subtrip_id', "left")

                                    ->join('locations as pic_location', 'pic_location.id = trips.pick_location_id', 'left')

                                    ->join('locations as drop_location', 'drop_location.id = trips.drop_location_id', 'left')

                                    ->findAll();

        }else{

            $data['holdSeats'] = $this->holdSeatModel

                        ->select("hold_seats.*, companies.name as companyname, trips.*, subtrips.*, pic_location.name as pic_location_name, hold_seats.id as hold_id, hold_seats.status as hold_status, drop_location.name as drop_location_name, hold_seats.startdate as startdate")

                        ->join('companies', 'companies.id = hold_seats.company_id', "left")

                        ->join('trips', 'trips.id = hold_seats.trip_id', "left")

                        ->join('subtrips', 'subtrips.id = hold_seats.subtrip_id', "left")

                        ->join('locations as pic_location', 'pic_location.id = trips.pick_location_id', 'left')

                        ->join('locations as drop_location', 'drop_location.id = trips.drop_location_id', 'left')

                        ->where('trips.company_id', $companyId)

                        ->findAll();

        }

        // print_r($data);

        // exit;

        echo view($this->Viewpath.'/index', $data);

    }



    public function create()

    {

        $companyId = session()->get('company_id'); 

        $data['pageheading'] = lang("Localize.add_hold_seat");

        $data['module'] = lang("Localize.hold_seat");

        $data['title']  = lang("Localize.add_seat_list");

        $data['companies'] = $this->companyModel->findAll();

        $data['roleId'] = session()->get('role_id');

        $data['companyId'] = $companyId;



        $data['fleet_type'] = $this->fleetTypeModel->findAll();

        $data['vehicle'] = $this->vehicleModel->findAll();

        

        $company_id = session()->get('company_id') ?? 0;

        if(($this->request->getVar('company_id') || $this->request->getVar('company_id') == 0) && session()->get('role_id') == "1"){

            $data['companies'] = $this->companyModel->findAll();

        }else{

            $company_ids = explode(',', $company_id);

            $data['companies'] = $this->companyModel->whereIn('id', $company_ids)->findAll();

        }

            

        $data['trip'] = $this->tripModel->select('trips.id as tripid, trips.*, schedules.*, vehicles.*, pic_location.name as pic_location_name, drop_location.name as drop_location_name')

                ->join('schedules', 'schedules.id = trips.schedule_id','left')

                ->join('vehicles', 'vehicles.id = trips.vehicle_id','left')

                ->join('locations as pic_location', 'pic_location.id = trips.pick_location_id', 'left')

                ->join('locations as drop_location', 'drop_location.id = trips.drop_location_id', 'left')

                ->findAll();

            

        $data['driver'] = $this->employeeModel->where('employeetype_id', 1)->findAll();

        $data['assistant'] = $this->employeeModel->where('employeetype_id', 2)->findAll();

        return view($this->Viewpath . '/new', $data);

    }

    public function new()

    {

        // build layout data

        $data['pageheading'] = lang("Localize.add_company");

        $data['module'] = lang("Localize.hold_seat");

        $data['title']  = lang("Localize.add_seat_list");

        return view($this->Viewpath . '/new', $data);

    }

    public function getSubTripsByTrip($tripID, $companyId)

    {

        $subtripInfo = $this->tripModel

                        ->select('subtrips.*,pic_location.name as pic_location_name, drop_location.name as drop_location_name,fleets.total_seat as total_seat, fleets.forth_seat as forth_seat, fleets.last_seat as last_seat, fleets.wc as wc, fleets.layout as layout,fleets.seat_number as seat_number ')

                        ->join('subtrips', 'subtrips.trip_id = trips.id', 'left')

                        ->join('locations as pic_location', 'pic_location.id = subtrips.pick_location_id', 'left')

                        ->join('locations as drop_location', 'drop_location.id = subtrips.drop_location_id', 'left')

                        ->join('fleets', 'fleets.id = trips.fleet_id', 'left')

                        ->where('trips.id', $tripID)

                        ->where('trips.status', 1)

                        ->where('subtrips.status', 1)

                        ->findAll();



        $bookedSeats = $this->ticketModel->select('seatnumber')

                                    ->where('journeydata >=', egypt_today())

                                    ->where('trip_id', $tripID)

                                    ->where('cancel_status', 0)

                                    ->where('refund', 0)

                                    ->findAll();

        $now = HoldSeatSupport::nowString();

        $blockedSeats = $this->holdSeatModel->select('seat_number')

                                    ->where('trip_id', $tripID)

                                    ->where('status', 1);

        HoldSeatSupport::applyClientBlockWindow($blockedSeats);

        $blockedSeats = $blockedSeats->findAll();

        $booked = [];

        foreach ($bookedSeats as $seatRow) {

            $booked = array_merge($booked, explode(',', $seatRow->seatnumber));

        }

        sort($booked, SORT_NATURAL);

        $blocked = [];

        foreach ($blockedSeats as $seatRows) {
            $seatCsv = is_array($seatRows)
                ? ($seatRows['seat_number'] ?? '')
                : ($seatRows->seat_number ?? '');
            $blocked = array_merge($blocked, explode(',', (string) $seatCsv));
        }

        $response = [

            'subtrips' => $subtripInfo,

            'booked_seats' => array_values(array_unique($booked)),



            'blocked' => array_values(array_unique($blocked)),

        ];



        echo json_encode($response);

        exit;

    }

    public function holdseat(){

        $subtripIds = $this->request->getVar('subtripid');
        $seatNumbers = $this->request->getVar('seatblock');

        if (is_array($seatNumbers)) {
            $seatNumbers = array_values(array_filter(array_map('trim', $seatNumbers), static fn ($s) => $s !== ''));
        } else {
            $seatNumbers = array_values(array_filter(array_map('trim', explode(',', (string) $seatNumbers))));
        }

        if ($seatNumbers === []) {
            return redirect()
                ->back()
                ->withInput()
                ->with('error', 'Please select at least one seat to block.');
        }

        if (is_array($subtripIds)) {
            $subtripIds = array_values(array_filter($subtripIds, static function ($id) {
                $id = trim((string) $id);

                return $id !== '' && $id !== 'select_all';
            }));
            $subtripIds = implode(',', $subtripIds);
        }

        $seatNumbers = implode(',', $seatNumbers);

        $tripId = (int) $this->request->getVar('tripid');
        if ($tripId <= 0) {
            return redirect()->back()->withInput()->with('error', 'Please select a trip.');
        }

        $subtripIdList = HoldSeatSupport::parseSubtripIds($subtripIds);
        if ($subtripIdList === []) {
            return redirect()->back()->withInput()->with('error', 'Please select at least one subtrip.');
        }

        $journeyStart = trim((string) $this->request->getVar('journeydate'));
        $journeyEnd = trim((string) ($this->request->getVar('journeydateend') ?: $journeyStart));
        if ($journeyStart === '' || $journeyEnd === '') {
            return redirect()->back()->withInput()->with('error', 'Journey start and end dates are required.');
        }
        $journeySpan = HoldSeatSupport::resolveJourneyInventorySpan(
            $tripId,
            $subtripIdList,
            $journeyStart,
            $journeyEnd,
            0
        );

       $holdseat = [

            'company_id'   => $this->request->getVar('company_id'),

            'subtrip_id'   => $subtripIds,

            'trip_id'      => $tripId,

            'seat_number'  => $seatNumbers,

            'hold_by'      => session()->get("first_name")." ".session()->get("last_name"),

            'notes'        => $this->request->getVar('notes'),

            'journeydata'  => $journeySpan['journeydata'],

            'journeydataend'  => $journeySpan['journeydataend'],

            'status'       => 1,

            'created_at'   => HoldSeatSupport::nowString(),

            'updated_at'   => HoldSeatSupport::nowString(),

        ];

        $blockWindow = HoldSeatSupport::parseBlockWindow(
            $this->request->getVar('startdate'),
            $this->request->getVar('enddate')
        );

        if (! $blockWindow['ok']) {
            return redirect()->back()->withInput()->with('error', $blockWindow['error']);
        }

        $holdseat['startdate'] = $blockWindow['start'];
        $holdseat['enddate'] = $blockWindow['end'];

        if (! $this->holdSeatModel->insert($holdseat)) {
            $errors = $this->holdSeatModel->errors();
            $message = $errors !== [] ? implode(' ', $errors) : 'Could not save hold seat. Please try again.';

            return redirect()->back()->withInput()->with('error', $message);
        }

        return redirect()->route('index-holdseat')->with('success', 'Hold seat saved successfully.');
    }

    public function getSubTripsByDates()

    {

        $startdate = $this->request->getGet('startdate')??"";

        $enddate   = $this->request->getGet('enddate')??"";

        $tripID    = $this->request->getGet('trip_id');

        $companyId = $this->request->getGet('company_id');

        $journeydata    = $this->request->getGet('journeydate');

        $journeydataend    = $this->request->getGet('journeydateend');
        
        $selectedSubTrips = $this->request->getVar('subtripselected');




        $subtripInfo = $this->tripModel

            ->select('subtrips.*, pic_location.name as pic_location_name, drop_location.name as drop_location_name,

                      fleets.total_seat, fleets.forth_seat, fleets.last_seat, fleets.wc, fleets.layout, fleets.seat_number')

            ->join('subtrips', 'subtrips.trip_id = trips.id', 'left')

            ->join('locations as pic_location', 'pic_location.id = subtrips.pick_location_id', 'left')

            ->join('locations as drop_location', 'drop_location.id = subtrips.drop_location_id', 'left')

            ->join('fleets', 'fleets.id = trips.fleet_id', 'left')

            ->where('trips.id', $tripID)

            ->where('trips.status', 1)

            ->where('subtrips.status', 1)

            ->findAll();



        $bookedSeats = $this->ticketModel->select('seatnumber')

            ->where('journeydata >=', $journeydata)

            ->where('journeydata <=', $journeydataend)
            
            ->whereIn('subtrip_id', $selectedSubTrips)

            // ->where('trip_id', $tripID)

            ->where('cancel_status', 0)

            ->where('refund', 0)

            ->findAll();



        $startdate = HoldSeatSupport::normalizeDateTime($startdate) ?? $startdate;
        $enddate = HoldSeatSupport::normalizeDateTime($enddate) ?? $enddate;

        $blockedSeats = [];

        if($enddate != "" && $startdate != ""){

            // $blockedSeats = $this->holdSeatModel->select('seat_number')

            // ->where('trip_id', $tripID)
            
            //  ->groupStart();
            //     foreach ($selectedSubs as $sub) {
            //         $this->holdSeatModel->orWhere("FIND_IN_SET('$sub', subtrip_id) !=", 0);
            //     }
            // ->groupEnd()

            // ->where('status', 1)

            // ->groupStart()

            //     ->where('journeydata <=', $journeydata)  // overlap check

            //     ->where('journeydataend >=', $journeydataend)

            // ->groupEnd()

            // ->groupStart()

            //     ->where('startdate <=', $enddate)  // overlap check

            //     ->where('enddate >=', $startdate)

            // ->groupEnd()

            // ->findAll();


            $model = $this->holdSeatModel;
            
            $model = $model->select('seat_number')
                ->where('trip_id', $tripID)
                ->groupStart();
            
            foreach ($selectedSubTrips as $sub) {
                $model->orWhere("FIND_IN_SET('$sub', subtrip_id) !=", 0);
            }
            
            $blockedSeats = $model->groupEnd()
                ->where('status', 1);

            if (! empty($journeydata) && ! empty($selectedSubTrips)) {
                $span = HoldSeatSupport::resolveJourneyInventorySpan(
                    (int) $tripID,
                    HoldSeatSupport::parseSubtripIds($selectedSubTrips),
                    (string) $journeydata,
                    (string) ($journeydataend ?: $journeydata),
                    0
                );
                HoldSeatSupport::applyJourneyDateFilter($model, $span['all']);
            } elseif (! empty($journeydata)) {
                HoldSeatSupport::applyJourneyDateFilter($model, $journeydata);
            }

            $blockedSeats = $model
                ->groupStart()
                    ->where('startdate <=', $enddate)
                    ->where('enddate >=', $startdate)
                ->groupEnd()
                ->findAll();



        }

        



        $booked = [];

        foreach ($bookedSeats as $seatRow) {

            $booked = array_merge($booked, explode(',', $seatRow->seatnumber));

        }

        sort($booked, SORT_NATURAL);

        $blocked = [];

        foreach ($blockedSeats as $seatRows) {
            $seatCsv = is_array($seatRows)
                ? ($seatRows['seat_number'] ?? '')
                : ($seatRows->seat_number ?? '');
            $blocked = array_merge($blocked, explode(',', (string) $seatCsv));
        }

        return $this->response->setJSON([

            'subtrips'      => $subtripInfo,

            'booked_seats' => array_values(array_unique($booked)),

            'blocked'       => array_values(array_unique($blocked)),

        ]);

    }

    public function unholdseat($id)
    {
        $unholdBy = trim(session()->get('first_name') . ' ' . session()->get('last_name'));
        HoldSeatSupport::releaseAdminHold((int) $id, $unholdBy, $this->db);

        return redirect()->route('index-holdseat');
    }
    
    public function serverList()
    {
        HoldSeatSupport::expireStaleAdminHolds($this->db);

        $request = service('request');

        // Role and company ID from session
        $roleId = session()->get('role_id');
        $companyId = session()->get('company_id');

        // DataTables request values
        $draw   = $request->getPost('draw');
        $start  = $request->getPost('start');
        $length = $request->getPost('length');
        $searchValue = $request->getPost('search')['value'] ?? '';

        // Column map
        $columns = [
            0 => 'hold_seats.id',
            1 => 'companies.name',
            2 => 'hold_seats.seat_number',
            3 => null, // trip (computed from locations)
            4 => null, // subtrip (computed from comma-separated IDs)
            5 => 'hold_seats.journeydata',
            6 => 'hold_seats.journeydataend',
            7 => 'hold_seats.hold_by',
            8 => 'hold_seats.unhold_by',
            9 => 'hold_seats.notes',
            10 => 'hold_seats.startdate',
            11 => 'hold_seats.enddate',
            12 => null // action column
        ];

        // Order column & direction
        $order = $request->getPost('order');
        $orderColumnIndex = !empty($order) && isset($order[0]['column']) ? $order[0]['column'] : 0;
        $orderDirection   = !empty($order) && isset($order[0]['dir']) ? $order[0]['dir'] : 'desc';

        // ---- TOTAL RECORDS ----
        $countBuilder = $this->db->table('hold_seats');
        $countBuilder->select('hold_seats.id')
            ->join('companies', 'companies.id = hold_seats.company_id', 'left')
            ->join('trips', 'trips.id = hold_seats.trip_id', 'left')
            ->join('subtrips', 'subtrips.id = hold_seats.subtrip_id', 'left')
            ->join('locations as pic_location', 'pic_location.id = trips.pick_location_id', 'left')
            ->join('locations as drop_location', 'drop_location.id = trips.drop_location_id', 'left');

        // Apply role-based filtering for total count
        if ($roleId != 1) {
            $countBuilder->where('trips.company_id', $companyId);
        }

        $totalRecords = $countBuilder->countAllResults(false);

        // ---- FILTERED QUERY ----
        $builder = $this->db->table('hold_seats');
        $builder->select('hold_seats.id as hold_id, hold_seats.status as hold_status, hold_seats.seat_number, hold_seats.notes, hold_seats.subtrip_id, hold_seats.journeydata, hold_seats.journeydataend, hold_seats.hold_by, hold_seats.unhold_by, hold_seats.startdate, hold_seats.enddate, hold_seats.created_at, hold_seats.updated_at, companies.name as companyname, trips.id as trip_id, trips.pick_location_id, trips.drop_location_id, pic_location.name as pic_location_name, drop_location.name as drop_location_name')
            ->join('companies', 'companies.id = hold_seats.company_id', 'left')
            ->join('trips', 'trips.id = hold_seats.trip_id', 'left')
            ->join('subtrips', 'subtrips.id = hold_seats.subtrip_id', 'left')
            ->join('locations as pic_location', 'pic_location.id = trips.pick_location_id', 'left')
            ->join('locations as drop_location', 'drop_location.id = trips.drop_location_id', 'left');

        // Apply role-based filtering
        if ($roleId != 1) {
            $builder->where('trips.company_id', $companyId);
        }

        // Apply search filter
        if (!empty($searchValue)) {
            $builder->groupStart()
                ->like('companies.name', $searchValue)
                ->orLike('hold_seats.seat_number', $searchValue)
                ->orLike('pic_location.name', $searchValue)
                ->orLike('drop_location.name', $searchValue)
                ->orLike('trips.id', $searchValue)
                ->orLike('hold_seats.subtrip_id', $searchValue)
                ->orLike('hold_seats.journeydata', $searchValue)
                ->orLike('hold_seats.journeydataend', $searchValue)
                ->orLike('hold_seats.hold_by', $searchValue)
                ->orLike('hold_seats.unhold_by', $searchValue)
                ->orLike('hold_seats.notes', $searchValue)
                ->orLike('hold_seats.startdate', $searchValue)
                ->orLike('hold_seats.enddate', $searchValue)
                ->groupEnd();
        }

        // Create a separate builder for filtered count
        $filteredCountBuilder = $this->db->table('hold_seats');
        $filteredCountBuilder->select('hold_seats.id')
            ->join('companies', 'companies.id = hold_seats.company_id', 'left')
            ->join('trips', 'trips.id = hold_seats.trip_id', 'left')
            ->join('subtrips', 'subtrips.id = hold_seats.subtrip_id', 'left')
            ->join('locations as pic_location', 'pic_location.id = trips.pick_location_id', 'left')
            ->join('locations as drop_location', 'drop_location.id = trips.drop_location_id', 'left');

        // Apply role-based filtering for filtered count
        if ($roleId != 1) {
            $filteredCountBuilder->where('trips.company_id', $companyId);
        }

        // Apply search filter for filtered count
        if (!empty($searchValue)) {
            $filteredCountBuilder->groupStart()
                ->like('companies.name', $searchValue)
                ->orLike('hold_seats.seat_number', $searchValue)
                ->orLike('pic_location.name', $searchValue)
                ->orLike('drop_location.name', $searchValue)
                ->orLike('trips.id', $searchValue)
                ->orLike('hold_seats.subtrip_id', $searchValue) 
                ->orLike('hold_seats.journeydata', $searchValue)
                ->orLike('hold_seats.journeydataend', $searchValue)
                ->orLike('hold_seats.hold_by', $searchValue)
                ->orLike('hold_seats.unhold_by', $searchValue)
                ->orLike('hold_seats.notes', $searchValue)
                ->orLike('hold_seats.startdate', $searchValue)
                ->orLike('hold_seats.enddate', $searchValue)
                ->groupEnd();
        }

        // ---- TOTAL FILTERED ----
        $totalRecordwithFilter = $filteredCountBuilder->countAllResults(false);

        // ---- ORDERING ----
        if (isset($columns[$orderColumnIndex]) && $columns[$orderColumnIndex] !== null) {
            $builder->orderBy($columns[$orderColumnIndex], $orderDirection);
        } else {
            $builder->orderBy('hold_seats.id', 'desc');
        }

        // ---- PAGINATION ----
        if ($length > 0) {
            $builder->limit($length, $start);
        }

        // ---- FETCH RECORDS ----
        $records = $builder->get()->getResult();
        
        $subtripsQuery = $this->db->table('subtrips')
            ->select('subtrips.id, l1.name AS picklocation, l2.name AS droplocation')
            ->join('locations l1', 'subtrips.pick_location_id = l1.id', 'left')
            ->join('locations l2', 'subtrips.drop_location_id = l2.id', 'left')
            ->where('subtrips.status', 1);
        
        $allSubtrips = $subtripsQuery->get()->getResult();
        
        // Create a lookup array for quick access
        $subtripsMap = [];
        foreach ($allSubtrips as $st) {
            $subtripsMap[(int)$st->id] = ($st->picklocation ?? '') . ' - ' . ($st->droplocation ?? '');
        }

        // ---- FORMAT JSON ----
        $data = [];
        $i = $start + 1;

        foreach ($records as $row) {
            // Format trip column
            $tripDisplay = esc($row->pic_location_name ?? '') . '-' . esc($row->drop_location_name ?? '') . '( ' . esc($row->trip_id ?? '') . ' )';
            
            $subtripDisplay = '';
            if (!empty($row->subtrip_id)) {
                $subtripIds = explode(',', $row->subtrip_id);
                $subtripNames = [];
                foreach ($subtripIds as $stId) {
                    $stId = (int)trim($stId);
                    if (!empty($stId) && isset($subtripsMap[$stId])) {
                        $subtripNames[] = $subtripsMap[$stId];
                    }
                }
                $subtripDisplay = !empty($subtripNames) ? esc(implode(', ', array_unique($subtripNames))) : '';
            }

            // Format hold_by
            $holdByDisplay = '';
            if (!empty($row->hold_by)) {
                $holdByDisplay = esc($row->hold_by);
                if (!empty($row->created_at)) {
                    $holdByDisplay .= '<br/>' . esc($row->created_at);
                }
            }

            // Format unhold_by
            $unholdByDisplay = '';
            if (!empty($row->unhold_by)) {
                $unholdByDisplay = esc($row->unhold_by);
                if (!empty($row->updated_at)) {
                    $unholdByDisplay .= '<br/>' . esc($row->updated_at);
                }
            }

            $timingStatus = HoldSeatSupport::timingStatus(
                (int) ($row->hold_status ?? 0),
                $row->startdate ?? null,
                $row->enddate ?? null
            );
            $timingBadge = [
                'scheduled' => '<span class="badge bg-info">Scheduled</span>',
                'active' => '<span class="badge bg-success">Active</span>',
                'expired' => '<span class="badge bg-secondary">Expired</span>',
                'unheld' => '<span class="badge bg-warning text-dark">Unheld</span>',
            ][$timingStatus] ?? '';

            // Format action button (manual unhold while not expired)
            $actionHtml = '';
            if (isset($row->hold_status) && (int) $row->hold_status === 1 && in_array($timingStatus, ['scheduled', 'active'], true)) {
                $actionHtml .= '<a href="' . base_url(route_to('unhold-seat', $row->hold_id)) . '" ';
                $actionHtml .= 'class="btn btn-danger btn-sm" ';
                $actionHtml .= 'onclick="return confirm(\'Are you sure you want to unblock this seat?\');">';
                $actionHtml .= '<i class="fas fa-trash"></i> UnBlock</a>';
            }

            $rowData = [
                "index" => $i++,
                "companyname" => esc($row->companyname ?? ''),
                "seat_number" => esc($row->seat_number ?? ''),
                "trip" => $tripDisplay,
                "subtrip" => $subtripDisplay,
                "journeydata" => esc($row->journeydata ?? ''),
                "journeydataend" => esc($row->journeydataend ?? ''),
                "hold_by" => $holdByDisplay,
                "unhold_by" => $unholdByDisplay,
                "notes" => esc($row->notes ?? ''),
                "hold_timing" => $timingBadge,
                "startdate" => esc($row->startdate ?? ''),
                "enddate" => esc($row->enddate ?? ''),
                "action" => $actionHtml
            ];

            $data[] = $rowData;
        }

        return $this->response->setJSON([
            "draw" => intval($draw),
            "recordsTotal" => $totalRecords,
            "recordsFiltered" => $totalRecordwithFilter,
            "data" => $data
        ]);
    }





}