<?php

namespace Tests\Tenant;

use App\Filter\FilterIndex;
use App\Jobs\RefreshFilterIndexJob;
use App\VehicleType;
use Carbon\Carbon;
use Mtc\MercuryDataModels\FuelType;
use Mtc\MercuryDataModels\Vehicle;
use Mtc\MercuryDataModels\VehicleMake;
use Mtc\MercuryDataModels\VehicleModel;
use Tests\TenantTestCase;

class RefreshFilterIndexJobTest extends TenantTestCase
{
    public function testFullReindexIndexesEverything(): void
    {
        $carMake = VehicleMake::factory()->create(['name' => 'Carco', 'cars' => true]);
        $bikeMake = VehicleMake::factory()->create(['name' => 'Bikeco', 'motorcycles' => true]);
        $carModel = VehicleModel::factory()->create([
            'name' => 'Saloon',
            'make_id' => $carMake->id,
            'type' => VehicleType::CAR->value,
        ]);

        Vehicle::factory()->create([
            'make_id' => $carMake->id,
            'model_id' => $carModel->id,
            'type' => VehicleType::CAR->value,
        ]);

        new RefreshFilterIndexJob()->handle();

        $this->assertTrue(
            FilterIndex::query()->where('filter_type', 'make')->where('filter_id', $carMake->id)->exists()
        );
        $this->assertFalse(
            FilterIndex::query()->where('filter_type', 'make')->where('filter_id', $bikeMake->id)->exists(),
            'Bike make should be excluded since no motorcycles in stock'
        );
        $this->assertTrue(
            FilterIndex::query()->where('filter_type', 'model')->where('filter_id', $carModel->id)->exists()
        );
    }

    public function testIncrementalReindexSkipsUnchangedTaxonomies(): void
    {
        $carMake = VehicleMake::factory()->create(['name' => 'Carco', 'cars' => true]);
        $carModel = VehicleModel::factory()->create([
            'name' => 'Saloon',
            'make_id' => $carMake->id,
            'type' => VehicleType::CAR->value,
        ]);

        Vehicle::factory()->create([
            'make_id' => $carMake->id,
            'model_id' => $carModel->id,
            'type' => VehicleType::CAR->value,
        ]);

        VehicleMake::query()->where('id', $carMake->id)->update(['updated_at' => Carbon::now()->subDays(7)]);
        VehicleModel::query()->where('id', $carModel->id)->update(['updated_at' => Carbon::now()->subDays(7)]);

        new RefreshFilterIndexJob(Carbon::now()->subDay())->handle();

        $this->assertFalse(
            FilterIndex::query()->where('filter_type', 'make')->where('filter_id', $carMake->id)->exists(),
            'Old make should not be re-indexed when since is set'
        );
        $this->assertFalse(
            FilterIndex::query()->where('filter_type', 'model')->where('filter_id', $carModel->id)->exists(),
            'Old model should not be re-indexed when since is set'
        );
    }

    public function testIncrementalReindexCoversRecentlyTouchedTaxonomies(): void
    {
        $carMake = VehicleMake::factory()->create(['name' => 'Carco', 'cars' => true]);
        $carModel = VehicleModel::factory()->create([
            'name' => 'Saloon',
            'make_id' => $carMake->id,
            'type' => VehicleType::CAR->value,
        ]);

        Vehicle::factory()->create([
            'make_id' => $carMake->id,
            'model_id' => $carModel->id,
            'type' => VehicleType::CAR->value,
        ]);

        VehicleMake::query()->where('id', $carMake->id)->update(['updated_at' => Carbon::now()->subMinutes(30)]);
        VehicleModel::query()->where('id', $carModel->id)->update(['updated_at' => Carbon::now()->subMinutes(30)]);

        new RefreshFilterIndexJob(Carbon::now()->subDay())->handle();

        $this->assertTrue(
            FilterIndex::query()->where('filter_type', 'make')->where('filter_id', $carMake->id)->exists()
        );
        $this->assertTrue(
            FilterIndex::query()->where('filter_type', 'model')->where('filter_id', $carModel->id)->exists()
        );
    }

    public function testEmptyStockSkipsMakeAndModelButNotOtherFilters(): void
    {
        VehicleMake::factory()->create(['name' => 'Carco', 'cars' => true]);
        VehicleModel::factory()->create(['name' => 'Saloon', 'type' => VehicleType::CAR->value]);
        FuelType::factory()->create(['name' => 'Petrol']);

        new RefreshFilterIndexJob()->handle();

        $this->assertEquals(0, FilterIndex::query()->where('filter_type', 'make')->count());
        $this->assertEquals(0, FilterIndex::query()->where('filter_type', 'model')->count());
        $this->assertGreaterThan(
            0,
            FilterIndex::query()->where('filter_type', 'fuel_type')->count(),
            'Non make/model taxonomies should still be indexed even when stock is empty'
        );
    }

    public function testIndexCopiesSlugFromTaxonomyTable(): void
    {
        $make = VehicleMake::factory()->create(['name' => 'Carco', 'slug' => 'preset-slug', 'cars' => true]);
        Vehicle::factory()->create(['make_id' => $make->id, 'type' => VehicleType::CAR->value]);

        new RefreshFilterIndexJob()->handle();

        $entry = FilterIndex::query()->where('filter_type', 'make')->where('filter_id', $make->id)->first();
        $this->assertNotNull($entry);
        $this->assertEquals('preset-slug', $entry->slug);
    }
}
