<?php

use App\Libraries\BookingInventorySupport;
use App\Libraries\TripJourneyDateHelper;
use PHPUnit\Framework\TestCase;

/**
 * Trip 117 regression: BB @ 03:00 (pickstand 8612) must not alias AA @ 09:30 PM on stand_id alone.
 */
final class TripJourneyDateHelperPickupOffsetTest extends TestCase
{
    public function testBbThreeAmPickupBoardingOct2ResolvesToOct1BusRun(): void
    {
        $helper = $this->trip117HelperStub();

        $this->assertSame(
            '2026-10-01',
            $helper->boardingDayToBusRunDate(117, 401, '2026-10-02', 8612)
        );
        $this->assertSame(
            '2026-10-02',
            $helper->getBoardingDateFromBusStartDate(117, 401, '2026-10-01', 8612)
        );
    }

    public function testAaNineThirtyPmPickupKeepsSameDayOffset(): void
    {
        $helper = $this->trip117HelperStub();

        $this->assertSame(
            '2026-10-01',
            $helper->boardingDayToBusRunDate(117, 396, '2026-10-01', 8606)
        );
    }

    public function testOct2BbSearchSharesBusRunWithOct1AaBooking(): void
    {
        try {
            $db = \Config\Database::connect();
            $pickdrop = $db->table('pickdrops')->select('id')->where('id', 8612)->get()->getRow();
            if (! $pickdrop) {
                $this->markTestSkipped('Pickstand 8612 not in database');
            }
        } catch (\Throwable $e) {
            $this->markTestSkipped('Database not available: ' . $e->getMessage());
        }

        $searchDates = BookingInventorySupport::resolveSearchDepartureDates(117, 401, '2026-10-02', 8612);

        $this->assertSame('2026-10-01', $searchDates['bus_start']);
        $this->assertSame('2026-10-02', $searchDates['boarding']);

        $this->assertTrue(BookingInventorySupport::ticketBelongsToBusRun(
            117,
            396,
            '2026-10-01 00:00:00',
            8606,
            $searchDates['bus_start']
        ));
    }

    private function trip117HelperStub(): TripJourneyDateHelper
    {
        return new class extends TripJourneyDateHelper {
            protected function getTrip(int $mainTripId): ?object
            {
                return (object) ['schedule_id' => 99];
            }

            protected function getSchedule(int $scheduleId): ?object
            {
                return (object) ['start_time' => '09:30 PM'];
            }

            protected function getMainSubtripPickdrops(int $mainTripId): array
            {
                return [
                    (object) ['id' => 8606, 'stand_id' => 86, 'time' => '09:30PM', 'type' => 1],
                    (object) ['id' => 8607, 'stand_id' => 87, 'time' => '10:30PM', 'type' => 1],
                    (object) ['id' => 8608, 'stand_id' => 88, 'time' => '11:30PM', 'type' => 1],
                    (object) ['id' => 8609, 'stand_id' => 89, 'time' => '01:30AM', 'type' => 1],
                ];
            }

            protected function getPickdropById(int $pickStandId): ?object
            {
                if ($pickStandId === 8606) {
                    return (object) ['id' => 8606, 'stand_id' => 86, 'time' => '09:30PM', 'type' => 1, 'trip_id' => 117];
                }
                if ($pickStandId === 8612) {
                    return (object) ['id' => 8612, 'stand_id' => 86, 'time' => '03:00AM', 'type' => 1, 'trip_id' => 401];
                }

                return null;
            }

            protected function getSubtripPickups(int $subtripId): array
            {
                if ($subtripId === 401) {
                    return [
                        (object) ['id' => 8612, 'stand_id' => 86, 'time' => '03:00AM', 'type' => 1],
                    ];
                }

                return [];
            }
        };
    }
}
