<?php

namespace App\Libraries;

use CodeIgniter\Database\BaseConnection;

/**
 * DISPLAY-ONLY seat counts for the triplist search API.
 *
 * Used only to populate `available_seat` on search results for customer UX.
 * Read-only: queries ticket/temp inventory; never creates holds or bookings.
 *
 * NOT used by: seatnew, checkseats, bookingcheck, payment-process, temporary holds, admin booking.
 */
class TripListSeatCountEstimator
{
    protected ?BaseConnection $db;

    public function __construct(?BaseConnection $db = null)
    {
        $this->db = $db;
    }

    /**
     * @param int $pickStandForInventory Pickdrop id used to resolve bus run (same as seatnew when pickstand sent)
     * @param bool $isEstimate True when the client has not chosen boarding yet (triplist reference only)
     *
     * @return array{
     *   available_seat: int,
     *   booked_seats: int,
     *   totalbooking: int,
     *   seat_count_estimated: bool
     * }
     */
    public function estimateForSubtrip(
        int $mainTripId,
        int $subtripId,
        string $searchDate,
        int $segmentPickId,
        int $segmentDropId,
        int $totalFleetSeats,
        int $pickStandForInventory,
        bool $isEstimate = false
    ): array {
        $empty = [
            'available_seat' => max(0, $totalFleetSeats),
            'booked_seats' => 0,
            'totalbooking' => 0,
            'seat_count_estimated' => $isEstimate,
        ];

        if ($mainTripId <= 0 || $subtripId <= 0 || $segmentPickId <= 0 || $segmentDropId <= 0) {
            return $empty;
        }

        $stops = SegmentSeatAvailability::parseStoppage(
            BookingInventorySupport::resolveTripStoppageForOverlap($mainTripId, $subtripId)
        );

        if ($stops === [] || ! SegmentSeatAvailability::canResolveSegment($stops, $segmentPickId, $segmentDropId)) {
            return $empty;
        }

        if ($pickStandForInventory <= 0) {
            $pickStandForInventory = BookingInventorySupport::resolveDefaultPickStandId($mainTripId, $subtripId);
        }

        $inventoryService = new SegmentSeatInventoryService($this->db);
        $unavailable = $inventoryService->collectUnavailableSeatNumbers(
            $subtripId,
            $searchDate,
            $pickStandForInventory,
            null,
            $segmentPickId,
            $segmentDropId
        );

        $booked = count($unavailable);

        return [
            'available_seat' => max(0, $totalFleetSeats - $booked),
            'booked_seats' => $booked,
            'totalbooking' => $booked,
            'seat_count_estimated' => $isEstimate,
        ];
    }
}
