<?php

namespace Tests\Tenant;

use App\Facades\Feature;
use App\Jobs\AssignFilterFeatures;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Queue;
use Mtc\MercuryDataModels\FilterFeature;
use Mtc\MercuryDataModels\VehicleStandardEquipment;
use Tests\TenantTestCase;
use Tests\UserForTenant;

class StandardEquipmentManagementTest extends TenantTestCase
{
    use UserForTenant;

    private function enableFeature(): void
    {
        Feature::setEnabled(tenant(), ['manage-standard-equipment']);
    }

    // --- Export tests ---

    public function testExportReturnsCsv(): void
    {
        $this->enableFeature();
        VehicleStandardEquipment::factory()->create([
            'description' => 'Leather Seats',
            'category' => 'Interior',
            'feature_id' => null,
        ]);

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.standard-equipment.export'));

        $response->assertStatus(200);
        $response->assertDownload('standard_equipment.csv');
    }

    public function testExportIncludesFriendlyNameFromLinkedFilterFeature(): void
    {
        $this->enableFeature();
        $feature = FilterFeature::factory()->create(['name' => 'Leather Upholstery']);
        VehicleStandardEquipment::factory()->create([
            'description' => 'Leather Seats',
            'category' => 'Interior',
            'feature_id' => $feature->id,
        ]);

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.standard-equipment.export'));

        $response->assertStatus(200);
        $content = $response->streamedContent();
        $this->assertStringContainsString('Leather Seats', $content);
        $this->assertStringContainsString('Interior', $content);
        $this->assertStringContainsString('Leather Upholstery', $content);
    }
    public function testExportDeduplicatesDescriptionCategoryPairs(): void
    {
        $this->enableFeature();
        VehicleStandardEquipment::factory(5)->create([
            'description' => 'Bluetooth',
            'category' => 'Technology',
            'feature_id' => null,
        ]);

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.standard-equipment.export'));

        $response->assertStatus(200);
        $content = $response->streamedContent();
        $rows = array_filter(explode("\n", trim($content)));
        // 1 header + 1 data row despite 5 identical records
        $this->assertCount(2, $rows);
    }

    public function testExportRequiresFeatureEnabled(): void
    {
        // Feature is not enabled — route should return 401

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.standard-equipment.export'));

        $response->assertStatus(401);
    }

    // --- Import tests ---

    public function testImportUpdatesCategoryForMatchingDescriptions(): void
    {
        $this->enableFeature();
        Queue::fake();
        VehicleStandardEquipment::factory(3)->create([
            'description' => 'Leather Seats',
            'category' => 'OldCategory',
        ]);

        $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->postJson(route('tenant.standard-equipment.import'), [
                'file' => UploadedFile::fake()->createWithContent(
                    'standard_equipment.csv',
                    "description,category,friendly_name\nLeather Seats,Interior,Leather Upholstery\n"
                ),
            ])
            ->assertStatus(200)
            ->assertJson(['success' => true]);

        $this->assertEquals(
            3,
            VehicleStandardEquipment::query()
                ->where('description', 'Leather Seats')
                ->where('category', 'Interior')
                ->count()
        );
    }

    public function testImportCreatesNewFilterFeatureWhenNoneExists(): void
    {
        $this->enableFeature();
        Queue::fake();
        VehicleStandardEquipment::factory()->create([
            'description' => 'Bluetooth',
            'category' => 'Tech',
            'feature_id' => null,
        ]);

        $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->postJson(route('tenant.standard-equipment.import'), [
                'file' => UploadedFile::fake()->createWithContent(
                    'standard_equipment.csv',
                    "description,category,friendly_name\nBluetooth,Technology,Bluetooth Connectivity\n"
                ),
            ])
            ->assertStatus(200);

        $feature = FilterFeature::whereJsonContains('terms', 'Bluetooth')->first();
        $this->assertNotNull($feature);
        $this->assertEquals('Bluetooth Connectivity', $feature->name);
        $this->assertContains('Bluetooth', $feature->terms);
    }

    public function testImportAddsDescriptionToExistingFilterFeatureByFriendlyName(): void
    {
        $this->enableFeature();
        Queue::fake();
        $feature = FilterFeature::factory()->create([
            'name' => 'Roof Options',
            'terms' => ['Panoramic Sunroof'],
        ]);

        $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->postJson(route('tenant.standard-equipment.import'), [
                'file' => UploadedFile::fake()->createWithContent(
                    'standard_equipment.csv',
                    "description,category,friendly_name\nSunroof,Comfort,Roof Options\n"
                ),
            ])
            ->assertStatus(200);

        $refreshed = $feature->refresh();
        $this->assertContains('Sunroof', $refreshed->terms);
        $this->assertContains('Panoramic Sunroof', $refreshed->terms);
    }

    public function testImportDoesNotDuplicateTermInExistingFilterFeature(): void
    {
        $this->enableFeature();
        Queue::fake();
        $feature = FilterFeature::factory()->create([
            'name' => 'Roof Options',
            'terms' => ['Sunroof'],
        ]);

        $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->postJson(route('tenant.standard-equipment.import'), [
                'file' => UploadedFile::fake()->createWithContent(
                    'standard_equipment.csv',
                    "description,category,friendly_name\nSunroof,Comfort,Roof Options\n"
                ),
            ])
            ->assertStatus(200);

        $this->assertCount(1, $feature->refresh()->terms);
    }

    public function testImportDispatchesAssignFilterFeaturesJob(): void
    {
        $this->enableFeature();
        Queue::fake();

        $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->postJson(route('tenant.standard-equipment.import'), [
                'file' => UploadedFile::fake()->createWithContent(
                    'standard_equipment.csv',
                    "description,category,friendly_name\nLeather Seats,Interior,Leather Upholstery\n"
                ),
            ])
            ->assertStatus(200);

        Queue::assertPushed(AssignFilterFeatures::class);
    }

    public function testImportSkipsFilterFeatureWhenFriendlyNameIsBlank(): void
    {
        $this->enableFeature();
        Queue::fake();

        $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->postJson(route('tenant.standard-equipment.import'), [
                'file' => UploadedFile::fake()->createWithContent(
                    'standard_equipment.csv',
                    "description,category,friendly_name\nSunroof,Comfort,\n"
                ),
            ])
            ->assertStatus(200);

        $this->assertEquals(0, FilterFeature::query()->count());
        Queue::assertNotPushed(AssignFilterFeatures::class);
    }

    public function testImportHandlesMultipleRows(): void
    {
        $this->enableFeature();
        Queue::fake();

        $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->postJson(route('tenant.standard-equipment.import'), [
                'file' => UploadedFile::fake()->createWithContent(
                    'standard_equipment.csv',
                    file_get_contents(dirname(__DIR__) . '/data/standard_equipment_import.csv')
                ),
            ])
            ->assertStatus(200);

        // Leather Seats and Bluetooth get filter features; Sunroof (blank friendly_name) does not
        $this->assertEquals(2, FilterFeature::query()->count());
        Queue::assertPushed(AssignFilterFeatures::class, 2);
    }

    public function testImportRequiresFeatureEnabled(): void
    {
        // Feature is not enabled — route should return 401
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->postJson(route('tenant.standard-equipment.import'), [
                'file' => UploadedFile::fake()->createWithContent(
                    'standard_equipment.csv',
                    "description,category,friendly_name\nLeather Seats,Interior,Leather Upholstery\n"
                ),
            ]);

        $response->assertStatus(401);
    }

    public function testImportRequiresFile(): void
    {
        $this->enableFeature();
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->postJson(route('tenant.standard-equipment.import'), []);

        $response->assertStatus(422);
    }
}
