<?php

namespace Tests\Tenant;

use App\Imports\VehicleImport;
use App\Models\ImportMap;
use App\Models\ImportMapField;
use Mtc\MercuryDataModels\Vehicle;
use Tests\TenantTestCase;

class ImportMapMatchKeyTest extends TenantTestCase
{
    /**
     * Same construction trick used in VehicleImportFlowTest — avoids the
     * heavy loadRelationships DB queries during instantiation.
     */
    private function makeImport(?ImportMap $map = null): VehicleImport
    {
        $ref = new \ReflectionClass(VehicleImport::class);
        /** @var VehicleImport $import */
        $import = $ref->newInstanceWithoutConstructor();

        $importMapProp = $ref->getProperty('import_map');
        $importMapProp->setAccessible(true);
        $importMapProp->setValue($import, $map);

        foreach (['dealerships', 'makes', 'models', 'fuel_types', 'body_styles', 'drivetrains', 'transmissions'] as $prop) {
            $p = $ref->getProperty($prop);
            $p->setAccessible(true);
            $p->setValue($import, collect());
        }

        $attrProp = new \ReflectionProperty($import, 'vehicleAttributes');
        $attrProp->setAccessible(true);
        $attrProp->setValue($import, []);

        $fillableProp = $ref->getProperty('vehicleFillable');
        $fillableProp->setAccessible(true);
        if (empty($fillableProp->getValue())) {
            $fillableProp->setValue(null, (new Vehicle())->getFillable());
        }

        return $import;
    }

    private function callImportRowSearchParams(VehicleImport $import, array $row): ?array
    {
        $method = new \ReflectionMethod($import, 'importRowSearchParams');
        $method->setAccessible(true);
        return $method->invoke($import, $row);
    }

    public function testFallsBackToLegacyMatchLogicWhenNoMatchKeyFlagged(): void
    {
        $map = ImportMap::factory()->create();
        $map->load('fields');
        $import = $this->makeImport($map);

        $this->assertEquals(
            ['slug' => 'taycan-2022'],
            $this->callImportRowSearchParams($import, ['slug' => 'taycan-2022']),
        );
        $this->assertEquals(
            ['uuid' => 'import-AB12CDE'],
            $this->callImportRowSearchParams($import, ['registration_number' => 'AB12CDE']),
        );
        $this->assertNull($this->callImportRowSearchParams($import, []));
    }

    public function testHonoursIsMatchKeyFieldWhenSet(): void
    {
        $map = ImportMap::factory()->create();
        ImportMapField::create([
            'map_id' => $map->id,
            'on_file' => 'vin',
            'on_model' => 'vin',
            'is_match_key' => true,
        ]);
        $map->load('fields');
        $import = $this->makeImport($map);

        $this->assertEquals(
            ['vin' => 'WP0AB2Y14JSA00001'],
            $this->callImportRowSearchParams($import, ['vin' => 'WP0AB2Y14JSA00001']),
        );
    }

    public function testFirstNonEmptyMatchKeyWinsForFallbackChain(): void
    {
        // Simulates VIN primary, registration fallback — a real Hippo case.
        $map = ImportMap::factory()->create();
        ImportMapField::create([
            'map_id' => $map->id,
            'on_file' => 'vin',
            'on_model' => 'vin',
            'is_match_key' => true,
        ]);
        ImportMapField::create([
            'map_id' => $map->id,
            'on_file' => 'registration',
            'on_model' => 'registration_number',
            'is_match_key' => true,
        ]);
        $map->load('fields');
        $import = $this->makeImport($map);

        // Both present → VIN wins (declared first).
        $this->assertEquals(
            ['vin' => 'WP0AB2Y14JSA00001'],
            $this->callImportRowSearchParams($import, [
                'vin' => 'WP0AB2Y14JSA00001',
                'registration_number' => 'AB12CDE',
            ]),
        );

        // VIN missing → falls through to registration.
        $this->assertEquals(
            ['registration_number' => 'AB12CDE'],
            $this->callImportRowSearchParams($import, [
                'vin' => '',
                'registration_number' => 'AB12CDE',
            ]),
        );

        // Neither → null.
        $this->assertNull($this->callImportRowSearchParams($import, [
            'vin' => '',
            'registration_number' => '',
        ]));
    }
}
