<?php

namespace App\Sitemap;

use App\Facades\Settings;
use App\Http\Controllers\SearchFacetController;
use Illuminate\Support\Facades\Config;
use Mtc\Filter\Contracts\CustomPatternFilter;
use Mtc\MercuryDataModels\Contracts\MinMaxFilter;
use Mtc\MercuryDataModels\Filters\IndexedFilter;

/**
 * Resolves which filter types may be appended to legacy SRP sitemap URLs as
 * query parameters (e.g. /used-cars/ford?body_type=hatchback).
 *
 * A filter type is selectable only when:
 *  - it is registered in config/filter.php
 *  - the tenant has it enabled (automotive-vehicle-filters-{type})
 *  - it has discrete slug values (extends IndexedFilter, not a MinMaxFilter
 *    range, not a CustomPatternFilter pattern)
 *  - it isn't make/model — those already form the legacy hierarchy path.
 */
class QueryParamFilterRegistry
{
    private const HIERARCHY_FILTERS = ['make', 'model'];

    /**
     * Filter types that admins may pick for query-param fan-out, with display labels.
     *
     * @return array<int, array{filter_type: string, filter_name: string}>
     */
    public function selectable(): array
    {
        return collect($this->selectableTypes())
            ->map(fn(string $type) => [
                'filter_type' => $type,
                'filter_name' => SearchFacetController::getFilterName($type),
            ])
            ->values()
            ->all();
    }

    /**
     * Filter types currently selected by the admin and still valid (selectable).
     *
     * @return list<string>
     */
    public function configured(): array
    {
        $raw = (string) Settings::get('seo-sitemap-srp-query-param-filters', '');
        $selected = collect(explode("\n", $raw))
            ->map(fn(string $line) => trim($line))
            ->filter()
            ->values();

        $allowed = $this->selectableTypes();

        return $selected->intersect($allowed)->values()->all();
    }

    /**
     * @return list<string>
     */
    private function selectableTypes(): array
    {
        return collect(array_keys(Config::get('filter.filters', [])))
            ->reject(fn(string $type) => in_array($type, self::HIERARCHY_FILTERS, true))
            ->filter(fn(string $type) => Settings::get("automotive-vehicle-filters-{$type}") === true)
            ->filter(fn(string $type) => $this->isDiscrete($type))
            ->values()
            ->all();
    }

    private function isDiscrete(string $type): bool
    {
        $class = Config::get('filter.filters.' . $type);

        return $class
            && is_subclass_of($class, IndexedFilter::class)
            && !is_subclass_of($class, MinMaxFilter::class)
            && !is_subclass_of($class, CustomPatternFilter::class);
    }
}
