<?php

namespace Tests\Tenant;

use App\Facades\Feature;
use App\Facades\Settings;
use App\Filter\FilterIndex;
use Illuminate\Support\Facades\Storage;
use Mtc\MercuryDataModels\SearchFacet;
use Mtc\MercuryDataModels\Vehicle;
use Mtc\MercuryDataModels\VehicleMake;
use Mtc\MercuryDataModels\VehicleModel;
use Tests\TenantTestCase;

class MakeSitemapFacetsTest extends TenantTestCase
{
    private string $sitemapPath;

    protected function setUp(): void
    {
        parent::setUp();

        Storage::fake('file-storage');

        Feature::setEnabled(tenant(), ['sitemap', 'search-facets']);

        $this->setSetting('seo-sitemap-include-srp', true);
        $this->setSetting('seo-sitemap-srp-type', 'fixed-path');
        $this->setSetting('seo-sitemap-srp-path', '/used-cars');
        $this->setSetting('seo-sitemap-include-srp-facets', true);

        $this->sitemapPath = tenant('id') . '/sitemap.xml';
    }

    public function testFacetedSrpUrlsAreGeneratedForMakesWithActiveVehicles(): void
    {
        SearchFacet::create([
            'position' => 1,
            'filter_type' => 'make',
            'robots_index' => true,
            'robots_follow' => true,
        ]);

        $ford = VehicleMake::factory()->create(['name' => 'Ford', 'slug' => 'ford']);
        $volvo = VehicleMake::factory()->create(['name' => 'Volvo', 'slug' => 'volvo']);

        $this->indexMake($ford);
        $this->indexMake($volvo);

        Vehicle::factory()->create(['make_id' => $ford->id, 'is_published' => 1]);

        $this->artisan('make:sitemap')->assertExitCode(0);

        $xml = $this->getSitemapContent();

        $this->assertStringContainsString('/used-cars/ford', $xml);
        $this->assertStringNotContainsString('/used-cars/volvo', $xml);
    }

    public function testNestedFacetUrlsAreGeneratedBelowMakeLevel(): void
    {
        SearchFacet::create([
            'position' => 1,
            'filter_type' => 'make',
            'robots_index' => true,
            'robots_follow' => true,
        ]);
        SearchFacet::create([
            'position' => 2,
            'filter_type' => 'model',
            'robots_index' => true,
            'robots_follow' => true,
        ]);

        $volvo = VehicleMake::factory()->create(['name' => 'Volvo', 'slug' => 'volvo']);
        $c30 = VehicleModel::factory()->create([
            'name' => 'C30',
            'slug' => 'c30',
            'make_id' => $volvo->id,
        ]);

        $this->indexMake($volvo);
        $this->indexModel($c30);

        Vehicle::factory()->create([
            'make_id' => $volvo->id,
            'model_id' => $c30->id,
            'is_published' => 1,
        ]);

        $this->artisan('make:sitemap')->assertExitCode(0);

        $xml = $this->getSitemapContent();

        $this->assertStringContainsString('/used-cars/volvo', $xml);
        $this->assertStringContainsString('/used-cars/volvo/c30', $xml);
    }

    public function testFacetWithRobotsIndexFalseIsExcluded(): void
    {
        SearchFacet::create([
            'position' => 1,
            'filter_type' => 'make',
            'robots_index' => false,
            'robots_follow' => true,
        ]);

        $ford = VehicleMake::factory()->create(['name' => 'Ford', 'slug' => 'ford']);
        $this->indexMake($ford);

        Vehicle::factory()->create(['make_id' => $ford->id, 'is_published' => 1]);

        $this->artisan('make:sitemap')->assertExitCode(0);

        $xml = $this->getSitemapContent();

        // Base SRP path still appears
        $this->assertStringContainsString('/used-cars', $xml);
        // Faceted URL with noindex is skipped
        $this->assertStringNotContainsString('/used-cars/ford', $xml);
    }

    public function testLegacyHierarchyUsedWhenFacetSettingDisabled(): void
    {
        $this->setSetting('seo-sitemap-include-srp-facets', false);
        $this->setSetting('seo-sitemap-include-srp-makes', true);

        $ford = VehicleMake::factory()->create(['name' => 'Ford', 'slug' => 'ford']);
        Vehicle::factory()->create(['make_id' => $ford->id, 'is_published' => 1]);

        // SearchFacet rows present but the opt-in setting is off — should be ignored.
        SearchFacet::create([
            'position' => 1,
            'filter_type' => 'colour',
            'robots_index' => true,
            'robots_follow' => true,
        ]);

        $this->artisan('make:sitemap')->assertExitCode(0);

        $xml = $this->getSitemapContent();

        // Legacy: /used-cars/{make}
        $this->assertStringContainsString('/used-cars/ford', $xml);
    }

    public function testLegacyHierarchyUsedWhenSearchFacetsFeatureDisabled(): void
    {
        Feature::setEnabled(tenant(), ['search-facets']); // toggles search-facets off; sitemap stays on

        $this->setSetting('seo-sitemap-include-srp-makes', true);

        $ford = VehicleMake::factory()->create(['name' => 'Ford', 'slug' => 'ford']);
        Vehicle::factory()->create(['make_id' => $ford->id, 'is_published' => 1]);

        // SearchFacet rows present but feature off — should be ignored.
        SearchFacet::create([
            'position' => 1,
            'filter_type' => 'colour',
            'robots_index' => true,
            'robots_follow' => true,
        ]);

        $this->artisan('make:sitemap')->assertExitCode(0);

        $xml = $this->getSitemapContent();

        // Legacy: /used-cars/{make}
        $this->assertStringContainsString('/used-cars/ford', $xml);
    }

    private function indexMake(VehicleMake $make): void
    {
        FilterIndex::query()->create([
            'filter_type' => 'make',
            'filter_id' => $make->id,
            'slug' => $make->slug,
            'name' => $make->name,
        ]);
    }

    private function indexModel(VehicleModel $model): void
    {
        FilterIndex::query()->create([
            'filter_type' => 'model',
            'filter_id' => $model->id,
            'slug' => $model->slug,
            'name' => $model->name,
        ]);
    }

    private function setSetting(string $key, mixed $value): void
    {
        if (Settings::exists($key)) {
            Settings::update($key, $value);
            return;
        }

        Settings::make([
            'tab' => 'Site',
            'section' => 'SEO',
            'group' => 'Sitemap',
            'name' => $key,
            'config_key' => $key,
            'type' => is_bool($value) ? 'boolean' : 'string',
            'value' => $value,
        ]);
    }

    private function getSitemapContent(): string
    {
        Storage::disk('file-storage')->assertExists($this->sitemapPath);

        return Storage::disk('file-storage')->get($this->sitemapPath);
    }
}
