<?php



namespace Modules\Trip\Controllers\Api;







use App\Controllers\BaseController;

use Modules\Trip\Models\TripModel;

use Modules\Trip\Models\StuffassignModel;

use Modules\Trip\Models\SubtripModel;

use Modules\Trip\Models\PickdropModel;

use Modules\Location\Models\LocationModel;

use Modules\Employee\Models\EmployeeModel;

use Modules\Fleet\Models\FleetModel;

use Modules\Fleet\Models\VehicleModel;

use Modules\Schedule\Models\ScheduleModel;

use CodeIgniter\API\ResponseTrait;

use CodeIgniter\Database\RawSql;

use Modules\Rating\Models\RatingModel;

use Modules\Cancellation\Models\GlobalCancellationModel;

use Modules\Trip\Models\RoundtripdiscoundModel;



use Modules\Ticket\Models\TicketModel;

use App\Libraries\BookingInventorySupport;

use App\Libraries\SegmentSeatAvailability;

use App\Libraries\SegmentSeatInventoryService;

use Modules\Offer\Models\OfferModel;

use Modules\Page\Models\PrivacyModel;
use Modules\Page\Models\TermsModel;




class Trip extends BaseController

{

    use ResponseTrait;



    protected $Viewpath;

    protected $tripModel;

    protected $subtripModel;

    protected $stuffassignModel;

    protected $locationModel;

    protected $employeeModel;

    protected $fleetTypeModel;

    protected $scheduleeModel;

    protected $vehicleModel;

    protected $pickdropModel;

    protected $db;

    protected $ratingModel;

    protected $ticketModel;

    protected $globalCancellationModel;

    protected $picdropModel;
    
    protected $roundtripdiscoundModel;

    protected $offerModel;

    protected $privacyModel;

    protected $termsModel;



    public function __construct()

    {

        $this->Viewpath = "Modules\Trip\Views";

        $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->pickdropModel = new PickdropModel();

        $this->picdropModel = new PickdropModel();

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



        $this->ratingModel = new RatingModel();

        $this->ticketModel = new TicketModel();

        $this->offerModel = new OfferModel();

        $this->privacyModel = new PrivacyModel();

        $this->globalCancellationModel = new GlobalCancellationModel();

        $this->termsModel = new TermsModel();
        
        $this->roundtripdiscoundModel = new RoundtripdiscoundModel();

    }



    public function test()

    {

        echo "helo";

    }



    public function getAllTrip()

    {

        $fleet_id         = $this->request->getVar('fleet_id');

        $pick_location_id = $this->request->getVar('pick_location_id');

        $drop_location_id = $this->request->getVar('drop_location_id');

        $journey_date     = $this->request->getVar('journeydate');

        $offer = $this->request->getVar('offer')??"";

        $discountAmount = 0;
        $discountPercent = 0;
        $offerSeatClasses = [];


        if($offer != ""){
            $offers = $this->offerModel->where('code', $offer)
                                        // ->where('start_date <=', date('Y-m-d'))
                                        // ->where('end_date >=', date('Y-m-d'))
                                        ->first();
            if(isset($offers) && !empty($offers)){
                 $offerSeatClasses = !empty($offers->seat_class) ? json_decode($offers->seat_class, true) : [];
            
                if (is_array($offerSeatClasses)) {
                    $offerSeatClasses = array_map('strval', $offerSeatClasses);
                } else {
                    $offerSeatClasses = [];
                }
                if ($offers->discount_type == 1) {
                    $discountAmount = (float) $offers->discount;
                } elseif ($offers->discount_type == 2) {
                    $discountPercent = (float) $offers->discount;
                }
            }

        }

        




        $journeyDate = date('Y-m-d', strtotime($journey_date));

        $journeyDayOfWeek = date('N', strtotime($journey_date));

        $maxBookDay = get_egypt_time('+1 month')->format('Y-m-d');



        if (empty($pick_location_id)) {

            $data = [

                'message' => "Please pick a location",

                'status' => "failed",

                'response' => 204,

            ];

            return $this->response->setJSON($data);

        }



        if (empty($drop_location_id)) {

            $data = [

                'message' => "Please pick a droping point",

                'status' => "failed",

                'response' => 204,

            ];

            return $this->response->setJSON($data);

        }



        if (empty($journey_date)) {

            $data = [

                'message' => "Please select your journey date",

                'status' => "failed",

                'response' => 204,

            ];

            return $this->response->setJSON($data);

        }



        if (strtotime(date('Y-m-d')) > strtotime($journey_date)) {

            $data = [

                'message' => "No Past Data allow",

                'status' => "failed",

                'response' => 204,

            ];



            return $this->response->setJSON($data);

        }



        if (strtotime($journey_date) > strtotime($maxBookDay)) {

            $data = [

                'message' => "No advance booking for this day",

                'status' => "failed",

                'response' => 204,

            ];

            return $this->response->setJSON($data);

        }



        // bind search query

        $main_privacy_policy = $this->termsModel->first();

        $this->subtripModel

            ->select('trips.id as tripid, trips.*, fleets.*, schedules.*, vehicles.*, subtrips.id as subtripId, subtrips.*, companies.name as companyName,companies.id as companyId, companies.logo as company_logo, company_terms.description as privacy_policy, trip_category.name as trip_category, trip_bus_types.name as trip_bus_types, GROUP_CONCAT(fleetimages.img_path) as bus_images')



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

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

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

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

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

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

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

            ->join('trip_category', 'trip_category.id = trips.trip_category_id', 'left')

            ->join('trip_bus_types', 'trip_bus_types.id = trips.trip_bus_type_id', 'left')

            ->join('vehicalimages', 'vehicalimages.vehicle_id = vehicles.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)

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

            ->groupBy('subtrips.id')

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



        $this->db->transStart();

        $classDataRaw = $this->db->table('seat_class')

        ->get()

        ->getResult();

        $this->db->transComplete();

        $classData = [];

        foreach ($classDataRaw as $class) {

            $classData[$class->id] = $class;

        }
        $economy = new \stdClass();
        $economy->id = 999;
        $economy->name = "Economy class";
        
        $classData[999] = $economy;


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

        $allSubTrips =  $this->subtripModel->findAll();

        $data = array('trips' => [], 'in_holiday' => [], 'to_open' => [], 'inactive' => [], 'you_may_like' => []);

        $globalCancellationRows = $this->globalCancellationModel
            ->select('hours, charges')
            ->findAll();
        $globalCancelationPolicy = array_map(static function ($row) {
            return [
                'charges' => $row->charges,
                'hours'   => $row->hours,
            ];
        }, $globalCancellationRows);

        foreach ($allSubTrips as $subTrip) {

            // Default busStartDate to journeyDate; will be recalculated after pickdrop offset detection
            $busStartDate = $journeyDate;

            // build rating for trip

            $totalRating = $this->ratingModel

                ->select('COUNT(*) AS t_rat, SUM(rating) AS s_rat, AVG(rating) AS avg_rat')

                ->where('subtrip_id', $subTrip->subtripId)

                ->where('status', 1)

                ->first();

            // $stoppages = $this->locationModel

            //                     ->select('id, name')

            //                     ->whereIn('id', array_filter(explode(',', $subTrip->stoppage)))
            //                     ->whereNotIn('id', [$drop_location_id, $pick_location_id])
            //                     ->findAll();
                                
            $stoppages = $this->locationModel
                            ->select('id, name')
                            ->whereIn('id', array_filter(explode(',', $subTrip->stoppage)))
                            ->whereNotIn('id', [$drop_location_id, $pick_location_id])
                            ->findAll();


            $subTrip->stoppage_stand = array_column($stoppages, 'name', 'id');
            
             $roundtripDiscount = $this->roundtripdiscoundModel
                ->where('status', 1)
                ->where('company_id', $subTrip->companyId)
                ->first();
            
            // Add roundTripDiscount key to trip data
            $subTrip->roundTripDiscount = !empty($roundtripDiscount) ? (float) $roundtripDiscount->onlinediscountrate : 0;

            $subtripSeatclass = json_decode($subTrip->subtrip_seatclass, true);

            $subtripSeatclass[] = [
                "seatClass" => "999",
                "seatNo" => [],
                "fare" => $subTrip->adult_fair
            ];
            
            // Encode back if needed
            $subTrip->subtrip_seatclass = json_encode($subtripSeatclass);

            $subtripSeatClassArray = json_decode($subTrip->subtrip_seatclass, true);

            $seatClassDetails = [];



            if (!empty($subTrip->subtrip_seatclass) && is_string($subTrip->subtrip_seatclass)) {

                $subtripSeatClassArray = json_decode($subTrip->subtrip_seatclass, true);


                if (json_last_error() === JSON_ERROR_NONE && is_array($subtripSeatClassArray)) {

                    foreach ($subtripSeatClassArray as $item) {
                        
                        $currentSeatClassId = isset($item['seatClass']) ? (string) $item['seatClass'] : '';
                        
                        $shouldApplyDiscount = false;
                        if($offer != ""){
                            
                            if (empty($offerSeatClasses) || in_array($currentSeatClassId, $offerSeatClasses)) {
                                $shouldApplyDiscount = true;
                            }
                        }
                        
                        if($offer != "" && $shouldApplyDiscount){

                            if($discountAmount !=  0){
                                    $seatClassDetails[] = [

                                    'seatClass' => $item['seatClass'] ?$classData[$item['seatClass']]->name :'',

                                    'seatClassId' => $item['seatClass'] ?? '',

                                    'fare'      => $item['fare'] ?? '',

                                    'discountAmount' => $discountAmount,

                                    'FinalFare' => $discountAmount ? max(0, $item['fare'] - $discountAmount) : $item['fare'],


                                ];

                            }else if ($discountPercent != 0) {

                                // $discountAmount = ($item['fare'] ?? 0) * ($discountPercent / 100);

                                // // Calculate final fare ensuring it doesn't go below 0
                                // $finalFare = max(0, ($item['fare'] ?? 0) - $discountAmount);

                                $seatClassDetails[] = [
                                    'seatClass'      => $item['seatClass'] ? $classData[$item['seatClass']]->name : '',
                                    'seatClassId'    => $item['seatClass'] ?? '',
                                    'fare'           => $item['fare'] ?? 0,
                                    'discountAmount' => round($item['fare'] && $discountPercent ? ($item['fare'] * $discountPercent) / 100 : 0, 2),
                                    'FinalFare'      => round(max(0, ($item['fare'] ?? 0) - ($item['fare'] && $discountPercent ? ($item['fare'] * $discountPercent) / 100 : 0)), 2),

                                ];
                            }else{
                                $seatClassDetails[] = [

                                'seatClass' => $item['seatClass'] ?$classData[$item['seatClass']]->name :'',

                                'seatClassId' => $item['seatClass'] ?? '',

                                'fare'      => $item['fare'] ?? '',

                                'discountAmount' => 0,

                                'FinalFare'      => $item['fare'] ?? '',

                                ];

                            }
                            

                        }else{

                            $seatClassDetails[] = [

                                'seatClass' => $item['seatClass'] ?$classData[$item['seatClass']]->name :'',

                                'seatClassId' => $item['seatClass'] ?? '',

                                'fare'      => $item['fare'] ?? '',

                                'discountAmount' => 0,

                                'FinalFare'      => $item['fare'] ?? '',

                            ];

                        }

                    }

                }

            }





            $subTrip->seatclass_price = $seatClassDetails;



            

            $facilityIds = array_filter(explode(',', $subTrip->facility ?? ''));



            $facilitys = [];



            if (!empty($facilityIds)) {

                $this->db->transStart();

                $facilitys = $this->db->table('facilitys')

                    ->whereIn('id', $facilityIds)

                    ->get()

                    ->getResult();

                $this->db->transComplete();

            }



            

            $subTrip->facility = implode(",", array_column($facilitys, 'name', 'id'));



            $subTrip->cancelation_policy = $globalCancelationPolicy;





            $totalRating = $this->ratingModel

                ->select('COUNT(*) AS t_rat, SUM(rating) AS s_rat, AVG(rating) AS avg_rat')

                ->where('subtrip_id', $subTrip->subtripId)

                ->where('status', 1)

                ->first();



            $subTrip->rating = number_format($totalRating->avg_rat, 1);







            $pickup_time = null;

            $drop_time = null;

            $pickup_list = [];

            $drop_list   = [];



            $pickdrop = $this->pickdropModel->select('pickdrops.id as pickdropid,pickdrops.*,stands.*')

                ->join('stands', 'stands.id = pickdrops.stand_id')

                ->where('trip_id', $subTrip->id)
                
                ->orderBy('pickdrops.id','ASC')

                ->findAll();

            if(empty($pickdrop)){

                $pickdrop = $this->pickdropModel->select('pickdrops.id as pickdropid,pickdrops.*,stands.*')

                    ->join('stands', 'stands.id = pickdrops.stand_id')

                    ->where('trip_id', $subTrip->trip_id)
                    
                    ->orderBy('pickdrops.id','ASC')

                    ->findAll();

            }

            // print_r($pickdrop);

            $subTripStartTime = $subTrip->start_time; // e.g. "09:00:00"
            $last_stop_time = $subTripStartTime;
            $current_day_offset = 0;
            $searched_pickup_offset = 0;
            $max_drop_offset = 0;
            $earliest_pickup_time = null;
            $latest_drop_time = null;
            
            $pickup_time = null;
            $drop_time = null;
            $pickup_list = [];
            $drop_list   = [];

            // Trace day offsets through all stops in chronological order
            foreach ($pickdrop as $item) {
                $item_time = $item->time;
                
                // Detect day rollover (heuristic: if current time < last stop time, a day has passed)
                // Note: This assumes stops are entered in chronological order.
                if (strtotime("1970-01-01 " . $item_time) < strtotime("1970-01-01 " . $last_stop_time)) {
                    $current_day_offset++;
                }
                $last_stop_time = $item_time;

                if ($item->type == 1) { // Pickup
                    // Smallest pickup time
                    if (is_null($pickup_time) || strtotime($item->time) < strtotime($pickup_time)) {
                        $pickup_time = $item->time;
                    }
                    
                    $pickup_list[] = [
                        'id' => $item->id,
                        'time' => $item->time,
                        'place' => $item->name,
                        'pickid' => $item->pickdropid,
                        'offset' => $current_day_offset // Store offset for debugging/display if needed
                    ];
                    
                    // The start time of this sub-trip (from the user's perspective) 
                    // is the time of the first pickup point.
                    if (is_null($earliest_pickup_time)) {
                        $searched_pickup_offset = $current_day_offset;
                        $earliest_pickup_time = $item_time;
                    } else if (($current_day_offset * 86400 + strtotime("1970-01-01 " . $item_time)) < ($searched_pickup_offset * 86400 + strtotime("1970-01-01 " . $earliest_pickup_time))) {
                        $searched_pickup_offset = $current_day_offset;
                        $earliest_pickup_time = $item_time;
                    }
                } elseif ($item->type == 0) { // Drop
                    // Largest drop time
                    if (is_null($drop_time) || strtotime($item->time) > strtotime($drop_time)) {
                        $drop_time = $item->time;
                    }
                    
                    $drop_list[] = [
                        'id' => $item->id,
                        'time' => $item->time,
                        'place' => $item->name,
                        'dropid' => $item->pickdropid,
                        'offset' => $current_day_offset
                    ];
                    
                    if ($item->stand_id == $drop_location_id) {
                        $latest_drop_time = $item_time;
                        $max_drop_offset = $current_day_offset;
                    }
                }
            }

            // Fallback for offsets if location-specific check didn't trigger
            if (is_null($earliest_pickup_time)) {
                // If we didn't find the specific stand (unlikely in sub-trip), use 1st pickup
                foreach($pickdrop as $p) { if($p->type == 1) { $earliest_pickup_time = $p->time; break; } }
            }
            if (is_null($latest_drop_time)) {
                 foreach(array_reverse($pickdrop) as $p) { if($p->type == 0) { $latest_drop_time = $p->time; break; } }
            }

            // Calculate "Bus Start Date" relative to the search date.
            $busStartDate = date('Y-m-d', strtotime($journeyDate . " -$searched_pickup_offset day"));
            $busStartDayOfWeek = date('N', strtotime($busStartDate));

            // Legacy: broad ticket count on bus departure (not segment-aware — fallback only).
            $bookedTickets = $this->ticketModel
                ->select(new RawSql('SUM(LENGTH(seatnumber) - LENGTH(REPLACE(seatnumber, ",", "")) + 1) s_length'))
                ->where('journeydata', $busStartDate)
                ->where('cancel_status', 0);



            if ($subTrip->type == 'subtrip') {

                $mainTripId = $subTrip->trip_id;

                $subtripStoppagePointsArr = array_filter(explode(',', $subTrip->stoppage));

                $mainTraipMainSubtripId = $this->subtripModel->where('trip_id', $mainTripId)->where('type', 'main')->first();

                $this->ticketModel

                    ->groupStart()

                        ->whereIn('tickets.subtrip_id', [$subTrip->id ?? "", $mainTraipMainSubtripId->id ?? ""])



                        ->orGroupStart()

                            ->where('trip_id', $subTrip->trip_id)

                            ->whereIn('pick_location_id', array_filter($subtripStoppagePointsArr, fn ($stp_id) => $stp_id != $subTrip->drop_location_id))

                        ->groupEnd()



                        ->orGroupStart()

                            ->where('trip_id', $subTrip->trip_id)

                            ->whereIn('drop_location_id', array_filter($subtripStoppagePointsArr, fn ($stp_id) => $stp_id != $subTrip->pick_location_id))

                        ->groupEnd()

                    ->groupEnd();

            } else {

                $this->ticketModel->where('tickets.trip_id', $subTrip->trip_id);

            }



            $legacyBookedRow = $bookedTickets->get()->getRow();
            $legacyBooked = (int) ($legacyBookedRow->s_length ?? 0);

            // Segment-aware seats unavailable for the searched pick/drop (same logic as seat map / booking).
            $mainTripIdInt = (int) $subTrip->trip_id;
            $subtripIdInt = (int) $subTrip->subtripId;
            $stops = SegmentSeatAvailability::parseStoppage(
                BookingInventorySupport::resolveTripStoppageForOverlap($mainTripIdInt, $subtripIdInt)
            );

            if ($stops !== [] && SegmentSeatAvailability::canResolveSegment($stops, $pick_location_id, $drop_location_id)) {
                $pickStandId = (int) ($this->request->getVar('pickstand') ?? $this->request->getVar('pickstand_id') ?? 0);
                if ($pickStandId <= 0) {
                    $pickStandId = BookingInventorySupport::resolveDefaultPickStandId($mainTripIdInt, $subtripIdInt);
                }
                $inventoryService = new SegmentSeatInventoryService($this->db);
                $unavailableForSegment = $inventoryService->collectUnavailableSeatNumbers(
                    $subtripIdInt,
                    $journeyDate,
                    $pickStandId,
                    null,
                    $pick_location_id,
                    $drop_location_id
                );
                $subTrip->booked_seats = count($unavailableForSegment);
            } else {
                $subTrip->booked_seats = $legacyBooked;
            }

            $subTrip->totalbooking = $subTrip->booked_seats;

            // $subTrip->available_seat = (int) $subTrip->total_seat + (int) $subTrip->last_seat - $totalBoking;

            $subTrip->available_seat = max(0, (int) $subTrip->total_seat - (int) $subTrip->booked_seats);



            // The absolute drop time for this bus instance
            $dropDate = date('Y-m-d', strtotime($busStartDate . " +$max_drop_offset day"));
            $journeyDateTime = new \DateTime("$dropDate $latest_drop_time");

            // Boarding DateTime for the passenger at the searched location


            $egyptNow = get_egypt_time();
            $nowPlusTwoHours = (clone $egyptNow)->modify('+2 hours');
            $boardingDateTime = new \DateTime("$journeyDate $earliest_pickup_time", new \DateTimeZone("Africa/Cairo"));

            // Hide trip if it starts within 2 hours from now
            if ($nowPlusTwoHours > $boardingDateTime) {
                $data['in_holiday'][] = $subTrip;
                continue;
            }





            if ($subTrip->status == 0) {

                // subtrip is inactive

                $data['inactive'][] = $subTrip;

                continue;

            }

            // The true departure time for this passenger's sub-trip
            // (Already checked above with $boardingDateTime)



            if (strtotime($busStartDate) < strtotime($subTrip->startdate)) {

                // subtrip yet not begin

                $data['to_open'][] = $subTrip;

                continue;

            }



            $cleanedoffdates = preg_replace('/\s+/', '', $subTrip->offdates);

            // Holiday checks use absolute search date ($journeyDate)
            if (in_array($journeyDate,explode(",", $cleanedoffdates))) {

                // subtrip is off today

                $data['in_holiday'][] = $subTrip;

                continue;

            }

            if ($this->isDateInRange($journeyDate, $subTrip->startdateinrange, $subTrip->enddateinrange)) {

                // subtrip is not in range

                $data['in_holiday'][] = $subTrip;

                continue;

            }

            $offdateranges = json_decode($subTrip->offdateranges, true);

            $isInAnyRange = false;

            if (is_array($offdateranges) && !empty($offdateranges)) {

                foreach ($offdateranges as $range) {

                    $start = $range['start'] ?? null;

                    $end = $range['end'] ?? null;



                    if ($start && $end && $this->isDateInRange($journeyDate, $start, $end)) {

                        $isInAnyRange = true;

                        break;

                    }

                }

            }



            if ($isInAnyRange) {

                $data['in_holiday'][] = $subTrip;

                continue;

            }

            // Existence and repetition checks use the adjusted $busStartDate
            if (!$this->isDateInRange($busStartDate, $subTrip->repetedstartdate, $subTrip->repetedenddate)) {

                if($busStartDate != date('Y-m-d',strtotime($subTrip->startdate))){

                    //start date and not between start and edn date

                    $data['in_holiday'][] = $subTrip;

                    continue;    

                }

                

            }



            if (@in_array($journeyDayOfWeek, explode(',', $subTrip->weekend))) {
                // subtrip is on holiday for the boarding day
                $data['in_holiday'][] = $subTrip;
                continue;
            }



            // The 'journeydate' returned to the API should be the date the passenger actually boards!
            $subTrip->journeydate = $journeyDate; 
            // We provide the physical bus start date as well for the booking process
            $subTrip->busStartDate = $busStartDate;

            if (($subTrip->pick_location_id != $pick_location_id) || ($subTrip->drop_location_id != $drop_location_id)) {

                // subtrip is related to selected locations

                $data['you_may_like'][] = $subTrip;

                continue;

            }

            $subTrip->privacy_policy = !empty($subTrip->privacy_policy) ? strip_tags($subTrip->privacy_policy) : "";

            $subTrip->pickup_points = $pickup_list;

            $subTrip->drop_points   = $drop_list;



            $subTrip->company_logo = !empty($subTrip->company_logo) ? "https://data.busvalley.net/busvalley_new/public/".$subTrip->company_logo : "";

            $subTrip->privacy_policy = !empty($subTrip->privacy_policy) ? strip_tags($subTrip->privacy_policy) : "";

            if (!empty($subTrip->bus_images)) {

                $pics = explode(',', $subTrip->bus_images);

                $subTrip->bus_images = array_map(function($pic) {

                    return "https://data.busvalley.net/busvalley_new/public/" . trim($pic);

                }, $pics);

            } else {

                $subTrip->bus_images = [];

            }
            
            $subTrip->main_privacy_policy = $main_privacy_policy ?? "";
            $data['trips'][] = $subTrip;

        }



        if (!count($data['trips']) && !count($data['you_may_like'])) {

            if (count($data['in_holiday'])) {

                return $this->response->setJSON([

                    'message' => "Holiday for all trips! No trip found.",

                    'status' => "failed",

                    'response' => 204,

                ]);

            }



            if (count($data['to_open'])) {

                return $this->response->setJSON([

                    'message' => "Trips yet not started! No trip found.",

                    'status' => "failed",

                    'response' => 204,

                ]);

            }



            return $this->response->setJSON([

                'message' => "No trip found for this route!",

                'status' => "failed",

                'response' => 204,

            ]);

        }


        return $this->response->setJSON([

            'status' => "success",

            'response' => 200,

            'data' => $data['trips'],

            'suggestions' => $data['you_may_like']

        ]);

    }



    public function showsubtrip()

    {

        $url = base_url();

        $allFronSubTrip =  $this->subtripModel->select('trips.id as tripid,trips.*,schedules.*,subtrips.id as subtripId,subtrips.*')

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

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

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

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

            ->findAll();



        if ($allFronSubTrip) {

            foreach ($allFronSubTrip as $key => $value) {

                $value->imglocation = $url . '/public/' . $value->imglocation;

            }



            $data = [

                'status' => "success",

                'response' => 200,

                'data' => $allFronSubTrip,

            ];



            return $this->response->setJSON($data);

        } else {

            $data = [

                'message' => "No trip found for this location",

                'status' => "failed",

                'response' => 204,

            ];



            return $this->response->setJSON($data);

        }

    }



    public function boarding($id)

    {

        $boarding =  $this->pickdropModel->where('type', 1)->where('trip_id', $id)->findAll();



        if ($boarding) {



            $data = [

                'status' => "success",

                'response' => 200,

                'data' => $boarding,

            ];



            return $this->response->setJSON($data);

        } else {

            $data = [

                'message' => "No Boarding Pint Found",

                'status' => "failed",

                'response' => 204,

            ];



            return $this->response->setJSON($data);

        }

    }



    public function dropping($id)

    {

        $boarding =  $this->pickdropModel->where('type', 0)->where('trip_id', $id)->findAll();



        if ($boarding) {



            $data = [

                'status' => "success",

                'response' => 200,

                'data' => $boarding,

            ];



            return $this->response->setJSON($data);

        } else {

            $data = [

                'message' => "No Dropping Pint Found",

                'status' => "failed",

                'response' => 204,

            ];



            return $this->response->setJSON($data);

        }

    }

    public function getClassName($id){

        $this->db->transStart();

        $classData = $this->db->table('seat_class')

        ->get()

        ->getResult();

        $this->db->transComplete();



        $data = [

            'status' => "success",

            'response' => 200,

            'data' => $classData,

        ];

        return $this->response->setJSON($data);

    }

    public function isDateInRange($dateToCheck, $startDate, $endDate) {

        // Convert dates to DateTime objects

        $date       = new \DateTime($dateToCheck);

        $start      = new \DateTime($startDate);

        $end        = new \DateTime($endDate);



        // Check if the date is in the range

        return ($date >= $start && $date <= $end);

    }

}

