<?php

namespace Tests\Tenant\Services;

use App\Services\AutoTraderVehicleMapper;
use Tests\TenantTestCase;

class AutoTraderVehicleMapperTest extends TenantTestCase
{
    private AutoTraderVehicleMapper $mapper;

    #[\Override]
    protected function setUp(): void
    {
        parent::setUp();
        $this->mapper = new AutoTraderVehicleMapper();
    }

    private function sampleData(array $overrides = []): array
    {
        return array_merge([
            'id' => 42,
            'condition' => 'Used',
            'vin' => 'VIN123',
            'make' => 'Ford',
            'model' => 'Fiesta',
            'derivative' => 'ST-Line',
            'derivative_id' => 'DERIV1',
            'type' => 'Car',
            'trim' => 'Lux',
            'body_type' => 'Hatchback',
            'fuel_type' => 'Petrol',
            'transmission_type' => 'Manual',
            'drivetrain' => 'FWD',
            'seats' => 5,
            'doors' => 5,
            'co2' => 99,
            'colour' => 'Red',
            'manufacture_year' => 2020,
            'vehicle_length' => 4000,
            'engine_size_cc' => 1498,
            'registration_number' => 'AB12 CDE',
            'odometer_mi' => 12345,
            'first_registration' => '2020-01-01',
            'previous_owner_count' => 1,
            'price' => 10995,
            'rrp_price' => 15000,
            'admin_fee' => 99,
            'attention_grabber' => 'Quick',
            'description' => 'Nice car',
            'published' => true,
            'publish_advert' => true,
            'publish_profile' => false,
            'at_disabled' => false,
            'lifecycleState' => 'FORECOURT',
            'vat_scheme' => 'Marginal',
            'exDemo' => false,
            'video_url' => 'https://video.example/1',
            'images' => [
                ['media_id' => 1, 'auto_trader_id' => 'IMG1', 'url' => 'u1'],
                ['media_id' => 2, 'auto_trader_id' => null, 'url' => 'u2'],
                ['media_id' => 3, 'auto_trader_id' => 'IMG3', 'url' => 'u3'],
            ],
            'features' => [['name' => 'Air Conditioning', 'type' => 'comfort']],
        ], $overrides);
    }

    public function testBuildsCoreApiSchemaFromIntermediateArray(): void
    {
        $payload = $this->mapper->toApiSchema($this->sampleData());

        $this->assertStringEndsWith('_42', $payload['metadata']['externalStockId']);
        $this->assertEquals('FORECOURT', $payload['metadata']['lifecycleState']);

        $this->assertEquals('DERIV1', $payload['vehicle']['derivativeId']);
        $this->assertEquals('Ford', $payload['vehicle']['make']);
        $this->assertEquals('AB12CDE', $payload['vehicle']['registration']);
        $this->assertEquals(12345, $payload['vehicle']['odometerReadingMiles']);
        $this->assertEquals('2020-01-01', $payload['vehicle']['firstRegistrationDate']);

        $this->assertEquals(10995, $payload['adverts']['retailAdverts']['suppliedPrice']['amountGBP']);
        $this->assertEquals('Nice car', $payload['adverts']['retailAdverts']['description']);

        // Only non-empty AutoTrader image ids, in order.
        $this->assertEquals(['IMG1', 'IMG3'], $payload['media']['images']);
        $this->assertEquals('https://video.example/1', $payload['media']['video']['href']);

        $this->assertEquals([['name' => 'Air Conditioning', 'type' => 'comfort']], $payload['features']);
    }

    public function testAdvertStatusesReflectPublishFlagsWhenForecourt(): void
    {
        $payload = $this->mapper->toApiSchema($this->sampleData());
        $adverts = $payload['adverts']['retailAdverts'];

        $this->assertEquals('PUBLISHED', $adverts['advertiserAdvert']['status']);
        $this->assertEquals('PUBLISHED', $adverts['autotraderAdvert']['status']);
        $this->assertEquals('NOT_PUBLISHED', $adverts['profileAdvert']['status']);
        $this->assertNull($payload['adverts']['reservationStatus']);
    }

    public function testNotPublishedLifecycleForcesAllAdvertsUnpublished(): void
    {
        $payload = $this->mapper->toApiSchema($this->sampleData(['lifecycleState' => 'SOLD']));
        $adverts = $payload['adverts']['retailAdverts'];

        foreach (['advertiserAdvert', 'autotraderAdvert', 'profileAdvert', 'locatorAdvert', 'exportAdvert'] as $key) {
            $this->assertEquals('NOT_PUBLISHED', $adverts[$key]['status'], "{$key} should be NOT_PUBLISHED when SOLD");
        }
    }

    public function testReservedLifecycleSetsReservationStatus(): void
    {
        $payload = $this->mapper->toApiSchema($this->sampleData(['lifecycleState' => 'SALE_IN_PROGRESS']));

        $this->assertEquals('Reserved', $payload['adverts']['reservationStatus']);
    }

    public function testAtDisabledForcesAdvertsUnpublishedWhilePublished(): void
    {
        $payload = $this->mapper->toApiSchema($this->sampleData(['at_disabled' => true]));
        $adverts = $payload['adverts']['retailAdverts'];

        // advertiserAdvert follows 'published' directly, the rest honour at_disabled.
        $this->assertEquals('PUBLISHED', $adverts['advertiserAdvert']['status']);
        $this->assertEquals('NOT_PUBLISHED', $adverts['autotraderAdvert']['status']);
        $this->assertEquals('NOT_PUBLISHED', $adverts['profileAdvert']['status']);
    }

    public function testEmptyRegistrationNullsRegistrationAndPlate(): void
    {
        $payload = $this->mapper->toApiSchema($this->sampleData(['registration_number' => null]));

        $this->assertNull($payload['vehicle']['registration']);
        $this->assertNull($payload['vehicle']['plate']);
    }
}
