<?php

namespace Tests\Unit;

use Mtc\MercuryDataModels\VehicleType;
use Mtc\MercuryDataModels\VehicleTypeProfile;
use PHPUnit\Framework\Attributes\DataProvider;
use Tests\TestCase;

class VehicleTypeProfileTest extends TestCase
{
    /**
     * The reservation key each type resolved to BEFORE the profile refactor.
     * These must stay byte-identical: car/caravan/motorhome/campervan fell to
     * the `default` arm (car key), lcv and motorcycle had their own keys.
     */
    public static function reservationKeyProvider(): array
    {
        return [
            'car' => ['car', 'sales-reserve_price'],
            'lcv' => ['lcv', 'sales-reserve_price_lcv'],
            'motorcycle' => ['motorcycle', 'sales-reserve-price-motorcycle'],
            'caravan' => ['caravan', 'sales-reserve_price'],
            'motorhome' => ['motorhome', 'sales-reserve_price'],
            'campervan' => ['campervan', 'sales-reserve_price'],
        ];
    }

    #[DataProvider('reservationKeyProvider')]
    public function testReservationKeyIsByteIdenticalToLegacyBehaviour(string $type, string $expectedKey): void
    {
        $this->assertSame($expectedKey, VehicleTypeProfile::for($type)->reservationKey());
    }

    public function testUnknownTypeFallsBackToCarProfileAndNeverThrows(): void
    {
        $profile = VehicleTypeProfile::for('something-unknown');

        $this->assertSame('car', $profile->type());
        $this->assertSame('sales-reserve_price', $profile->reservationKey());
        $this->assertSame('cars', $profile->filterFlag());
        $this->assertSame('odometer', $profile->measurement());
        $this->assertFalse($profile->usesHours());
        $this->assertTrue($profile->expectsRegistration());
    }

    public function testNullTypeFallsBackToCarProfile(): void
    {
        $this->assertSame('sales-reserve_price', VehicleTypeProfile::for(null)->reservationKey());
    }

    public function testEveryKnownTypeExposesCoreCapabilities(): void
    {
        foreach (VehicleType::values() as $type) {
            $profile = VehicleTypeProfile::for($type);

            $this->assertNotEmpty($profile->reservationKey(), "reservationKey null for {$type}");
            $this->assertNotEmpty($profile->measurement(), "measurement null for {$type}");
            $this->assertNotEmpty($profile->taxonomies(), "taxonomies empty for {$type}");
            $this->assertTrue(VehicleTypeProfile::isKnown($type), "type should be known: {$type}");
            // All current types are road vehicles: registration expected, odometer metric.
            $this->assertTrue($profile->expectsRegistration(), "registration should be true for {$type}");
            $this->assertSame('odometer', $profile->measurement(), "measurement should be odometer for {$type}");
        }
    }

    public function testFilterFlagIsByteIdenticalToLegacyMap(): void
    {
        // These reproduce the old RefreshFilterIndexJob::TYPE_FLAG_BY_VEHICLE_TYPE map.
        $this->assertSame('cars', VehicleTypeProfile::for('car')->filterFlag());
        $this->assertSame('lcvs', VehicleTypeProfile::for('lcv')->filterFlag());
        $this->assertSame('motorcycles', VehicleTypeProfile::for('motorcycle')->filterFlag());
        $this->assertSame('caravans', VehicleTypeProfile::for('caravan')->filterFlag());
        $this->assertSame('motorhomes', VehicleTypeProfile::for('motorhome')->filterFlag());
        // Campervan was absent from the legacy map (no vehicle_makes column), so it
        // resolves to null and is skipped, exactly as before. Closing the gap needs
        // a `campervans` column + backfill, deferred to the make-flag work.
        $this->assertNull(VehicleTypeProfile::for('campervan')->filterFlag());
    }

    public function testUnknownTypeIsNotTreatedAsKnown(): void
    {
        $this->assertFalse(VehicleTypeProfile::isKnown('gibberish'));
        $this->assertFalse(VehicleTypeProfile::isKnown(null));
        $this->assertTrue(VehicleTypeProfile::isKnown('CAR'));
    }
}
