<?php

namespace Modules\Ticket\Controllers;

use App\Controllers\BaseController;
use CodeIgniter\API\ResponseTrait;
use Modules\Employee\Models\EmployeeModel;
use Modules\Fleet\Models\FleetModel;
use Modules\Fleet\Models\VehicleModel;
use Modules\Location\Models\LocationModel;
use Modules\Location\Models\StandModel;
use Modules\Paymethod\Models\PaymethodModel;
use Modules\Schedule\Models\ScheduleModel;
use Modules\Tax\Models\TaxModel;
use Modules\Ticket\Models\JourneylistModel;
use Modules\Ticket\Models\PartialpaidModel;
use Modules\Ticket\Models\TicketModel;
use Modules\Ticket\Models\MaxtimeModel;
use Modules\Trip\Models\FacilityModel;
use Modules\Trip\Models\PickdropModel;
use Modules\Trip\Models\StuffassignModel;
use Modules\Trip\Models\SubtripModel;
use Modules\Trip\Models\TripModel;
use Modules\User\Models\UserDetailModel;
use Modules\User\Models\UserModel;
use Modules\Company\Models\CompanyModel;
use Modules\Role\Models\RoleModel;

class Journeylist extends BaseController
{
    protected $Viewpath;
    protected $ticketModel;
    protected $tripModel;
    protected $subtripModel;
    protected $stuffassignModel;
    protected $locationModel;
    protected $employeeModel;
    protected $fleetTypeModel;
    protected $scheduleeModel;
    protected $vehicleModel;
    protected $standModel;
    protected $picdropModel;
    protected $facilitypModel;
    protected $taxModel;
    protected $db;
    protected $paymethodModel;
    protected $userModel;
    protected $userDetailModel;
    protected $journeylistModel;
    protected $partialpaidModel;
    protected $maxtimeModel;
    protected $CompanyModel;
    protected $roleModel;

    public function __construct()
    {

        $this->Viewpath = "Modules\Ticket\Views";
        $this->ticketModel = new TicketModel();
        $this->tripModel = new TripModel();
        $this->subtripModel = new SubtripModel();
        $this->stuffassignModel = new StuffassignModel();
        $this->locationModel = new LocationModel();
        $this->employeeModel = new EmployeeModel();
        $this->fleetTypeModel = new FleetModel();
        $this->vehicleModel = new VehicleModel();
        $this->scheduleeModel = new ScheduleModel();
        $this->standModel = new StandModel();
        $this->picdropModel = new PickdropModel();
        $this->facilitypModel = new FacilityModel();
        $this->taxModel = new TaxModel();
        $this->db = \Config\Database::connect();
        $this->paymethodModel = new PaymethodModel();

        $this->userModel = new UserModel();
        $this->userDetailModel = new UserDetailModel();

        $this->journeylistModel = new JourneylistModel();
        $this->partialpaidModel = new PartialpaidModel();

        $this->maxtimeModel = new MaxtimeModel();
        $this->CompanyModel = new CompanyModel();
        $this->roleModel = new RoleModel();
    }


    function new()
    {
        $rolepermissionLibrary = new \App\Libraries\Rolepermission();
        if (!$rolepermissionLibrary->read('journey_list') && (int)session()->get('role_id') != 1) {
            return redirect()->back()->with('fail', 'You do not have permission to access journey lists.');
        }
        $data['pick_location_id'] = null;
        $data['drop_location_id'] = null;
        $data['filterjourneydate'] = null;
        $data['filterreturndate'] = null;
        $data['fleet_id'] = null;

        $data['filterpath'] = $this->Viewpath;
        $data['location'] = $this->locationModel->findAll();
        $data['fleet_type'] = $this->fleetTypeModel->findAll();

        $data['module'] =    lang("Localize.ticket_booking");
        $data['title']  =    lang("Localize.journey_list");

        $data['pageheading'] = lang("Localize.journey_list");
        $data['company_id'] = 0;
        $data['companies'] = $this->CompanyModel->findAll();

        echo view($this->Viewpath . '\journeylist/new', $data);
    }

    public function findtrip()
    {
        $rolepermissionLibrary = new \App\Libraries\Rolepermission();
        if (!$rolepermissionLibrary->read('journey_list') && (int)session()->get('role_id') != 1) {
            return redirect()->back()->with('fail', 'You do not have permission to access journey lists.');
        }
        $pick_location_id = $this->request->getVar('pick_location_id');
        $drop_location_id = $this->request->getVar('drop_location_id');
        $filterjourneydate = $this->request->getVar('filterjourneylistdate');
        $fleet_id = $this->request->getVar('fleet_id');

        $journeyDate = date('Y-m-d', strtotime($filterjourneydate));
        $today = date('Y-m-d');
        if (!in_array((int)session()->get('role_id'), [1, 7]) && $journeyDate < $today) {
            return redirect()->back()->with('fail', 'Searching for backdated trips is not allowed for your role.');
        }

        $company_id        = $this->request->getVar('company_id') ?: session('company_id');
        $data['pick_location_id'] = $pick_location_id;
        $data['drop_location_id'] = $drop_location_id;
        $data['filterjourneydate'] = $filterjourneydate;
        $data['company_id'] = $company_id;

        $data['fleet_id'] = $fleet_id;

        $data['filterpath'] = $this->Viewpath;
        $data['location'] = $this->locationModel->findAll();
        $data['fleet_type'] = $this->fleetTypeModel->findAll();

        $checked_company_id = 0;
        if(is_array(session()->get('company_id')) > 0 && session()->get('role_id') != "1"){
            if (strpos(session()->get('company_id'), ',')) { 
                $checked_company_id = explode(',', session()->get('company_id'));
            } else {
                $checked_company_id = [session()->get('company_id')];
            }

            // $checked_company_id = session()->get('company_id');
        } else {
            if (strpos($company_id, ',')) { 
                $checked_company_id = explode(',', $company_id);
            } else {
                $checked_company_id = [$company_id];
            }
            // $checked_company_id = $company_id;
        }


        // bind search query
        //updated on 16-01-2025

        $this->subtripModel
            ->select('trips.id as tripid, trips.*, fleets.*, schedules.*, vehicles.*, subtrips.id as subtripId, subtrips.*,companies.name as company')

            ->join('trips', 'trips.id = subtrips.trip_id')
            ->join('fleets', 'fleets.id = trips.fleet_id')
            ->join('schedules', 'schedules.id = trips.schedule_id')
            ->join('vehicles', 'vehicles.id = trips.vehicle_id',"left")
            ->join('companies', 'companies.id = trips.company_id',"left")

            ->groupStart()
                ->groupStart()
                    ->where('subtrips.pick_location_id', $pick_location_id)
                    ->where('subtrips.drop_location_id', $drop_location_id)
                ->groupEnd()

                ->orGroupStart()
                    ->whereIn('subtrips.trip_id', function ($subQuery) use ($pick_location_id, $drop_location_id) {
                        $subQuery
                            ->select('sm.trip_id')
                            ->from('subtrips sm')
                            ->where('sm.pick_location_id', $pick_location_id)
                            ->where('sm.drop_location_id', $drop_location_id)
                            ->where('sm.type', 'subtrip');
                    })
                    ->where('subtrips.type', 'main')
                ->groupEnd()
            ->groupEnd()
            ->where('subtrips.status', 1);

            $nonEmptyCompanyId = array_filter($checked_company_id);
            if(!empty($nonEmptyCompanyId)){
                $this->subtripModel->whereIn('trips.company_id', $nonEmptyCompanyId);
            }
                

            $this->subtripModel->orderBy('subtrips.id', 'DESC');

        $fleet_id && $this->subtripModel->where('trips.fleet_id', $fleet_id);

        //OLD query
        // $this->subtripModel
        //     ->select('trips.id as tripid, trips.*, fleets.*, schedules.*, vehicles.*, subtrips.id as subtripId, subtrips.*')

        //     ->join('trips', 'trips.id = subtrips.trip_id')
        //     ->join('fleets', 'fleets.id = trips.fleet_id')
        //     ->join('schedules', 'schedules.id = trips.schedule_id')
        //     ->join('vehicles', 'vehicles.id = trips.vehicle_id',"left")

        //     ->groupStart()
        //     ->where('subtrips.pick_location_id', $pick_location_id)
        //     ->where('subtrips.drop_location_id', $drop_location_id);
        //     if($checked_company_id){
        //         $this->subtripModel->whereIn('trips.company_id', $checked_company_id);   
        //     }
        //     $this->subtripModel->groupEnd()

        //     ->orGroupStart()
        //     ->whereIn('subtrips.trip_id', function ($subQuery) use ($pick_location_id, $drop_location_id, $checked_company_id) {
        //         $subQuery
        //             ->select('sm.trip_id')
        //             ->from('subtrips sm')
        //             ->where('sm.pick_location_id', $pick_location_id)
        //             ->where('sm.drop_location_id', $drop_location_id)
        //             ->where('sm.type', 'subtrip');
        //         if($checked_company_id){
        //             $subQuery->whereIn('trips.company_id', $checked_company_id);
        //         }
        //     })
        //     ->where('subtrips.type', 'main')
        //     ->groupEnd()

        //     ->orderBy('subtrips.id', 'DESC');

        // $fleet_id && $this->subtripModel->where('trips.fleet_id', $fleet_id);

        // $query = $this->subtripModel->builder()->getCompiledSelect();dd($query);

        $data['alltriplist'] = $this->subtripModel->findAll();
        $data['module'] = lang("Localize.ticket_booking");
        $data['title']  = lang("Localize.journey_list");
        $data['pageheading'] = lang("Localize.journey_list");
        $data['companies'] = $this->CompanyModel->findAll();

        return view($this->Viewpath . '\journeylist/index', $data);
    }

    public function getJourneylistData($tripid, $date, $print)
    {
        $rolepermissionLibrary = new \App\Libraries\Rolepermission();
        if (!$rolepermissionLibrary->read('journey_list') && (int)session()->get('role_id') != 1) {
            return redirect()->back()->with('fail', 'You do not have permission to access journey lists.');
        }
        $company_id = session()->get('company_id');
        if (strpos($company_id, ',')) { 
            $company_ids = explode(',', $company_id);
        } else {
            $company_ids = [$company_id];
        }

        // For cross-midnight trips, the bus departs on Day 1 (main trip) and some
        // sub-trip passengers board on Day 2. We include both the selected date AND
        // the day before so the admin sees the complete bus manifest.
        if(is_array($company_ids) && !empty($company_ids) && session()->get('role_id') != "1"){
            $journeyList = $this->journeylistModel
                            ->select('journeylists.*,companies.name as company_name, tickets.note as note , trips.seatclass as seatClass, tickets.bookby_user_id as bookby_user_id, tickets.bookby_user_type as bookby_user_type')
                            ->join('trips', 'trips.id = journeylists.trip_id')
                            ->join('tickets', 'tickets.booking_id = journeylists.booking_id', 'left')
                            ->join('companies', 'trips.company_id = companies.id')
                            ->where('journeylists.trip_id', $tripid)
                            ->where('journeylists.journeydate', $date)
                            ->where('tickets.cancel_status', 0)
                            ->where('tickets.refund', 0)
                            ->whereIn('trips.company_id', $company_ids)
                            ->orderBy('tickets.seatnumber', 'ASC')
                            ->withDeleted()->findAll();
        }else{
            $journeyList = $this->journeylistModel
            ->select('journeylists.*,companies.name as company_name, tickets.note as note, trips.seatclass as seatClass, tickets.bookby_user_type as bookby_user_type')
            ->join('trips', 'trips.id = journeylists.trip_id')
            ->join('tickets', 'tickets.booking_id = journeylists.booking_id', 'left')
            ->join('companies', 'trips.company_id = companies.id', 'left')
            ->where('journeylists.trip_id', $tripid)
            ->where('journeylists.journeydate', $date)
            ->where('tickets.cancel_status', 0)
            ->where('tickets.refund', 0)
            ->orderBy('tickets.seatnumber', 'ASC')
            ->withDeleted()->findAll();
        }
        // Build the query
        $builder = $this->journeylistModel
            ->select('journeylists.*, companies.name as company_name, tickets.note as note, trips.seatclass as seatClass')
            ->join('trips', 'trips.id = journeylists.trip_id')
            ->join('tickets', 'tickets.booking_id = journeylists.booking_id', 'left')
            ->join('companies', 'trips.company_id = companies.id', 'left')
            ->where('journeylists.trip_id', $tripid)
            ->where('journeydate', $date)
            ->where('tickets.cancel_status', 0)
            ->where('tickets.refund', 0)
            ->orderBy('tickets.seatnumber', 'ASC');

        // Get the compiled SQL query
        $sql = $builder->builder()->getCompiledSelect();

        // dd($sql);


        // $query = $this->journeylistModel->builder()->getCompiledSelect();dd($query);
       
        $CheckBookingId = "";
        $NewFirstName = "";
        $NewLastName = "";
        $NewPhone = "";
        $finalList = [];

        $journeyDateHelper = new \App\Libraries\TripJourneyDateHelper();
        foreach ($journeyList as $key => $value) {
            
            // Calculate actual boarding date for display in the manifest
            $value->boarding_date = $journeyDateHelper->getBoardingDateFromBusStartDate(
                (int) $value->trip_id,
                (int) $value->subtrip_id,
                $value->journeydate,
                (int) $value->pick_stand_id
            );

            $bookUserType = $value->bookby_user_type ??"";
            $bookUserId = $value->bookby_user_id ??"";
            // if($bookUserId != ""){
            //     $roelinfo = $this->roleModel->find($bookUserId);
            //     $bookUserType = $roelinfo->name;
            // }
            
            if($value->booking_id != $CheckBookingId){
                
                $NewFirstName = $value->first_name;
                $NewLastName = $value->last_name;
                $NewPhone = $value->phone;

                $CheckBookingId = $value->booking_id;
                $CheckRecordindex = 0;
            }

            $value->first_name  = $NewFirstName;
            $value->last_name   = $NewLastName;
            $value->phone       = $NewPhone;
            $value->bookby_user_type = $bookUserType ?? "offline";

            $BookingRecords = 0;
            // $company_name = $value->company_name ?? "";
            if(!empty($value->booking_id)){
                

                $data['ticket'] =   $this->ticketModel->where('booking_id', $value->booking_id)->where('cancel_status', 0)->withDeleted()->first();

// print_r($data['ticket']);
                $existSeats = $data['ticket']->seatnumber ?? "";
                $BookingRecords = explode(',', $existSeats);
                
            //   foreach ($BookingRecords as $singleSeat) {

            //         $newRow = clone $value;  // clone original row
            //         $newRow->seatnumbers = $singleSeat; // assign seat
        
            //         $finalList[] = $newRow; // push into final array
            //     }
                

                if($CheckBookingId == $value->booking_id){
                    $value->seatnumbers = $BookingRecords[$CheckRecordindex];
                    $CheckRecordindex++;
                }
                
                // if($CheckBookingId == $value->booking_id){
                //     $value->seatnumbers = $existSeats;
                // }
                
            }
        }
        // print_r($journeyList);
        // exit;
        usort($journeyList, function ($a, $b) {
            return (int)$a->seatnumbers <=> (int)$b->seatnumbers;
        });
        $data['pageheading'] = lang("Localize.journey_list");


        // show section copu
        $namefacility = array();
        $stopagepoint = array();
        $start = null;
        $destination = null;



        $gettripdata =  $this->tripModel
                            ->join('companies', 'companies.id = trips.company_id', 'left')
                            ->withDeleted()->find($tripid);
        $company_name = $gettripdata->name ?? "" ;

        $travelartripdata = $this->picdropModel
            ->select('pickdrops.*,stands.*,pickdrops.id as pickdropid')
            ->join('stands', 'stands.id = pickdrops.stand_id')
            // ->where('trip_id', $tripid)
            ->withDeleted()
            ->findAll();

        $locationModel = $this->locationModel->withDeleted()->findAll();

        foreach ($journeyList as $key => $picdropvalue) {
            if(!empty($picdropvalue)){
                foreach ($locationModel as $key => $locvalue) {
                    if ($locvalue->id == $picdropvalue->pick_location_id) {
                        $picdropvalue->pick_loc_name = $locvalue->name;
                    }
                    if ($locvalue->id == $picdropvalue->drop_location_id) {
                        $picdropvalue->drop_loc_name = $locvalue->name;
                    }
                }
            }
        }


        foreach ($journeyList as $key => $standpicdropvalue) {
            if(!empty($standpicdropvalue)){
                foreach ($travelartripdata as $key => $picdropstandvalue) {


                    if ($picdropstandvalue->pickdropid == $standpicdropvalue->pick_stand_id) {

                        $standpicdropvalue->picstand = $picdropstandvalue->name . '(' . $picdropstandvalue->time . ')';
                    }

                    if ($picdropstandvalue->pickdropid == $standpicdropvalue->drop_stand_id) {

                        $standpicdropvalue->dropstand = $picdropstandvalue->name . '(' . $picdropstandvalue->time . ')';
                    }
                }
            }
        }



        foreach ($locationModel as $key => $locvalue) {
            if(!empty($locvalue)){

                if ($locvalue->id == $gettripdata->pick_location_id) {
                    $start = $locvalue->name;
                }
                if ($locvalue->id == $gettripdata->drop_location_id) {
                    $destination = $locvalue->name;
                }
            }
        }


        $data['from'] = $start;
        $data['to'] = $destination;




        $data['schedule'] = $this->scheduleeModel->withDeleted()->find($gettripdata->schedule_id);

        $getfacility = $gettripdata->facility;

        if (!empty($getfacility)) {

            $facility = explode(",", $getfacility);
            foreach ($facility as $key => $facilityvalue) {
                $facilityname =  $this->facilitypModel->withDeleted()->find($facilityvalue);
                array_push($namefacility, $facilityname->name);
            }
            $data['facility'] = implode(", ", $namefacility);
        } else {
            $data['facility'] = "No facility";
        }


        $getstopagepoint = $gettripdata->stoppage;

        if (!empty($getstopagepoint)) {
            $getstopagepoint = explode(",", $getstopagepoint);
            foreach ($getstopagepoint as $key => $stopvalue) {
                $stopname =  $this->locationModel->withDeleted()->find($stopvalue);
                array_push($stopagepoint, $stopname->name);
            }
            $data['stopagepoint'] = implode(", ", $stopagepoint);
        } else {
            $data['stopagepoint'] = "No Stoppage Point";
        }


        $drivername =  array();
        $assistance =  array();
        $driver =  $this->stuffassignModel->select('stuffassigns.*,employees.*')
            ->join('employees', 'employees.id = stuffassigns.employee_id')
            ->where('trip_id', $tripid)
            ->where('DATE(stuffassigns.created_at)', $date)
            ->withDeleted()
            ->findAll();
    
        // print_r($driver);die;
        $data['drivephone'] = "";
        $data['assistphone'] = "";
        foreach ($driver as $key => $dvalue) {
            if ($dvalue->employee_type == 1) {
                array_push($drivername, $dvalue->first_name . ' ' . $dvalue->last_name);
                $data['drivephone'] = $dvalue->phone;
            } else {
                array_push($assistance, $dvalue->first_name . ' ' . $dvalue->last_name);
                $data['assistphone'] = $dvalue->phone;
            }
        }

        $data['drivername'] = implode(", ", $drivername);
        $data['assistance'] = implode(", ", $assistance);


        $data['pageheading'] = lang("Localize.journey_list");
        $data['pickdrop'] = $this->picdropModel
            ->select('pickdrops.*,stands.*,pickdrops.id as pickdropid')
            ->join('stands', 'stands.id = pickdrops.stand_id')
            ->withDeleted()
            ->findAll();
        $this->db->transStart();
        $classData = $this->db->table('seat_class')
                        ->get()
                        ->getResultArray();
        $this->db->transComplete();

        $classArray = array_column($classData, 'name', 'id');

        foreach($journeyList as $k=>$journeyListData){
            $seatclass = implode(", ", array_values($this->getSeatClasses($journeyListData->seatClass, $journeyListData->seatnumbers, $classArray)));
            $journeyList[$k]->seatclass  = is_array($seatclass) && !empty($seatclass) ? $seatclass[0] : $seatclass;
        }

        $data['journeydate'] =      $date;
        $data['journeylist'] =     $journeyList;
        // echo "<pre>";print_r($journeyList);exit;
        $data['tripId'] = $tripid;
        $data['date'] = $date;
        $data['company_name'] = $company_name;
        
        
        // print_r($data);die;

        if ($print == 0) {
// return "gfdgd";
            $data['module'] =    lang("Localize.ticket_booking");
            $data['title']  =    lang("Localize.journey_list");
            return view($this->Viewpath . '\journeylist\show', $data);
        }
        return view($this->Viewpath . '\journeylist\print', $data);
    }

    function getSeatClasses($seatsData, $seatNumbers, $classData) {
        if (is_string($seatsData)) {
            $seatsData = json_decode($seatsData, true);
        }

        if (!is_array($seatNumbers)) {
            $seatNumbers = explode(",", $seatNumbers);
        }

        $seatClasses = [];
        $seatClassesArray = [];
        // print_r($seatNumbers);exit;
        foreach ($seatNumbers as $seatNo) {
            $found = false; 
            foreach ($seatsData as $seatInfo) {
                if (in_array($seatNo, $seatInfo['seatNo'])) {
                    $seatClasses[$seatNo] = $classData[$seatInfo['seatClass']];
                    $found = true;
                    break;
                }
            }
            if (!$found) {
                $seatClasses[$seatNo] = "Economy";
            }
            $seatClassesArray[] = $seatClasses[$seatNo];
        }
        $uniqueSeatClassesArray = array_unique($seatClassesArray);
        return $uniqueSeatClassesArray;

    }
}
