<?php

require_once __DIR__ . '/SegmentSeatAvailabilityBootstrap.php';

use App\Libraries\SegmentSeatAvailability;
use PHPUnit\Framework\TestCase;

/**
 * Route A→B→C→D→E→F (indices 0..5). Location IDs are letters for readability.
 *
 * @internal
 */
final class SegmentSeatAvailabilityTest extends TestCase
{
    /** @var list<string> */
    private array $stops = ['A', 'B', 'C', 'D', 'E', 'F'];

    public function testNoOverlapWhenSegmentsOnlyTouchAtHandoff(): void
    {
        $this->assertFalse(SegmentSeatAvailability::segmentsOverlap($this->stops, 'A', 'C', 'C', 'E'));
        $this->assertFalse(SegmentSeatAvailability::segmentsOverlap($this->stops, 'C', 'E', 'A', 'C'));
    }

    public function testNoOverlapAdjacentLegs(): void
    {
        $this->assertFalse(SegmentSeatAvailability::segmentsOverlap($this->stops, 'B', 'E', 'A', 'B'));
    }

    public function testOverlapWhenInnerSegmentInsideOuter(): void
    {
        $this->assertTrue(SegmentSeatAvailability::segmentsOverlap($this->stops, 'A', 'D', 'B', 'C'));
    }

    public function testOverlapWhenLongerSegmentContainsShorter(): void
    {
        $this->assertTrue(SegmentSeatAvailability::segmentsOverlap($this->stops, 'B', 'E', 'A', 'D'));
        $this->assertTrue(SegmentSeatAvailability::segmentsOverlap($this->stops, 'B', 'E', 'B', 'E'));
    }

    public function testNoOverlapWhenOnlyShareDropOfFirstWithPickOfSecond(): void
    {
        $this->assertFalse(SegmentSeatAvailability::segmentsOverlap($this->stops, 'B', 'E', 'A', 'B'));
    }

    public function testUnknownStopsDoNotOverlap(): void
    {
        $this->assertFalse(SegmentSeatAvailability::segmentsOverlap($this->stops, 'B', 'E', 'X', 'Y'));
        $this->assertFalse(SegmentSeatAvailability::segmentsOverlap($this->stops, 'B', 'B', 'A', 'C'));
    }

    public function testResolveBookingSegmentPrefersTicketPickDrop(): void
    {
        $segment = SegmentSeatAvailability::resolveBookingSegmentFromRow($this->stops, [
            'pick_location_id' => 'B',
            'drop_location_id' => 'D',
            'subtrip_pick_id' => 'A',
            'subtrip_drop_id' => 'F',
        ]);
        $this->assertSame(['pick' => 'B', 'drop' => 'D'], $segment);
    }

    public function testParseStoppageTrimsAndFilters(): void
    {
        $this->assertSame(['55', '41', '43'], SegmentSeatAvailability::parseStoppage(' 55, 41 ,,43 '));
    }

    /** Trip 75-style main stoppage: Cairo, Sharm, El Tor, Ras Sudr, … */
    public function testNoOverlapWhenLaterLegStartsWhereEarlierBookingEnds(): void
    {
        $stops = ['32', '41', '43', '54', '65', '66'];

        $this->assertFalse(SegmentSeatAvailability::segmentsOverlap($stops, '54', '43', '32', '54'));
    }

    public function testOverlapWhenExistingBookingStoredWithReversedPickDrop(): void
    {
        $stops = ['32', '41', '43', '54'];

        $this->assertTrue(SegmentSeatAvailability::segmentsOverlap($stops, '32', '41', '41', '32'));
    }

    public function testOverlapForNestedSegmentOnSameRoute(): void
    {
        $stops = ['32', '41', '43', '54'];

        $this->assertTrue(SegmentSeatAvailability::segmentsOverlap($stops, '32', '41', '32', '43'));
    }
}
