<?php

namespace App\Http\Controllers;

use App\Facades\Settings;
use App\Http\Requests\ReorderSearchFacetsRequest;
use App\Http\Requests\StoreSearchFacetRequest;
use App\Http\Requests\UpdateSearchFacetRequest;
use App\Http\Resources\SearchFacetResource;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Mtc\MercuryDataModels\SearchFacet;

class SearchFacetController extends Controller
{
    /**
     * Filter types that can be used as URL facets.
     * These are filters that have simple slug-based values suitable for URL paths.
     */
    private const FACETABLE_FILTERS = [
        'make',
        'model',
        'body_type',
        'colour',
        'fuel_type',
        'transmission',
        'location',
        'franchise',
    ];

    /**
     * List all configured facets ordered by position.
     */
    public function index(): JsonResponse
    {
        return response()->json([
            'data' => SearchFacetResource::collection(
                SearchFacet::query()->orderByPosition()->get()
            ),
            'max_facets' => Config::get('filter.max_facets'),
        ]);
    }

    /**
     * List available filters that can be used as facets.
     * Returns enabled filters that are not already configured as facets.
     */
    public function available(): JsonResponse
    {
        $configuredFacets = SearchFacet::query()->pluck('filter_type')->toArray();
        $configFilters = array_keys(Config::get('filter.filters', []));

        $available = collect(self::FACETABLE_FILTERS)
            ->filter(fn($type) => in_array($type, $configFilters))
            ->filter(fn($type) => Settings::get("automotive-vehicle-filters-{$type}") === true)
            ->reject(fn($type) => in_array($type, $configuredFacets))
            ->map(fn($type) => [
                'filter_type' => $type,
                'filter_name' => self::getFilterName($type),
            ])
            ->values();

        return response()->json([
            'data' => $available,
        ]);
    }

    /**
     * Store a new facet configuration.
     */
    public function store(StoreSearchFacetRequest $request): SearchFacetResource
    {
        $facet = SearchFacet::query()->create($request->validated());

        return new SearchFacetResource($facet);
    }

    /**
     * Update an existing facet (robots settings only).
     */
    public function update(UpdateSearchFacetRequest $request, SearchFacet $facet): SearchFacetResource
    {
        $facet->update($request->validated());

        return new SearchFacetResource($facet);
    }

    /**
     * Delete a facet configuration and reorder remaining facets.
     */
    public function destroy(SearchFacet $facet): JsonResponse
    {
        DB::transaction(function () use ($facet) {
            $facet->delete();

            // Reorder remaining facets to fill the gap
            SearchFacet::query()
                ->orderByPosition()
                ->get()
                ->each(fn (SearchFacet $f, int $index) => $f->update(['position' => $index + 1]));
        });

        return response()->json(['success' => true]);
    }

    /**
     * Reorder facets by updating their positions.
     */
    public function reorder(ReorderSearchFacetsRequest $request): JsonResponse
    {
        DB::transaction(function () use ($request) {
            // First, set all positions to temporary high values to avoid unique constraint conflicts
            foreach ($request->input('facets') as $index => $facetData) {
                SearchFacet::where('id', $facetData['id'])
                    ->update(['position' => 100 + $index]);
            }

            // Then set the correct positions
            foreach ($request->input('facets') as $facetData) {
                SearchFacet::where('id', $facetData['id'])
                    ->update(['position' => $facetData['position']]);
            }
        });

        return response()->json([
            'success' => true,
            'data' => SearchFacetResource::collection(
                SearchFacet::query()->orderByPosition()->get()
            ),
        ]);
    }

    /**
     * Get human-readable name for a filter type.
     */
    public static function getFilterName(string $filterType): string
    {
        $translated = __('filter::filter.facet_names.' . $filterType);

        if ($translated === 'filter::filter.facet_names.' . $filterType) {
            return ucfirst(str_replace('_', ' ', $filterType));
        }

        return $translated;
    }
}
