<?php

namespace Tests\Tenant;

use App\Imports\VehicleImport;
use App\Models\ImportMap;
use App\Models\ImportMapField;
use Illuminate\Support\Facades\Event;
use Mtc\MercuryDataModels\Vehicle;
use Tests\TenantTestCase;

class ImportMapUpdateOnlyTest extends TenantTestCase
{
    private function makeImport(ImportMap $map): 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, []);

        $delimProp = new \ReflectionProperty($import, 'subFieldDelimiter');
        $delimProp->setAccessible(true);
        $delimProp->setValue($import, '|');

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

        return $import;
    }

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

    public function testUpdateOnlySkipsRowWithNoMatchingVehicle(): void
    {
        Event::fake();

        $map = ImportMap::factory()->create(['data' => ['update_only' => true]]);
        ImportMapField::create([
            'map_id' => $map->id,
            'on_file' => 'vin',
            'on_model' => 'vin',
            'is_match_key' => true,
        ]);
        $map->load('fields');

        $import = $this->makeImport($map);

        $before = Vehicle::query()->count();

        $result = $this->processRow($import, ['vin' => 'WPZZZ91ZZZS801001']);

        $this->assertNull($result);
        $this->assertEquals($before, Vehicle::query()->count(), 'No vehicle should have been created');
    }

    public function testUpdateOnlyUpdatesExistingMatchingVehicle(): void
    {
        Event::fake();

        $vehicle = Vehicle::factory()->create(['vin' => 'WPZZZ91ZZZS801001']);

        $map = ImportMap::factory()->create(['data' => ['update_only' => true]]);
        ImportMapField::create([
            'map_id' => $map->id,
            'on_file' => 'vin',
            'on_model' => 'vin',
            'is_match_key' => true,
        ]);
        $map->load('fields');

        $import = $this->makeImport($map);

        $result = $this->processRow($import, ['vin' => 'WPZZZ91ZZZS801001']);

        $this->assertNotNull($result);
        $this->assertEquals($vehicle->id, $result->id, 'Should have matched the existing vehicle');
    }

    public function testCreatesNewVehicleWhenUpdateOnlyDisabled(): void
    {
        Event::fake();

        $map = ImportMap::factory()->create(['data' => ['update_only' => false]]);
        // No match key fields → falls back to default behavior (registration_number → uuid)
        $map->load('fields');

        $import = $this->makeImport($map);

        $before = Vehicle::query()->count();

        $result = $this->processRow($import, ['registration_number' => 'NEW123']);

        $this->assertNotNull($result);
        $this->assertEquals($before + 1, Vehicle::query()->count(), 'A new vehicle should have been created');
    }
}
