<?php

namespace Functional\Exercises\Http\Controllers;

use Functional\Exercises\Http\Resources\ExerciseListResource;
use Functional\Exercises\Http\Resources\ExerciseResource;
use Functional\Exercises\Models\Exercise;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;

/**
 * Catalogue d'exercices : lecture seule et public, aucun scoping par utilisateur.
 */
class ExercisesController
{
    private const DEFAULT_LOCALE = 'fr';

    private const DEFAULT_PER_PAGE = 20;

    /** GET /api/exercises — liste filtrable (search/body_part/equipment/target/category) et paginée. */
    public function index(Request $request): AnonymousResourceCollection
    {
        $exercises = Exercise::query()
            ->search($request->query('search'))
            ->when($request->query('body_part'), fn ($query, $bodyPart) => $query->where('body_part', $bodyPart))
            ->when($request->query('equipment'), function ($query, $equipment) {
                // Accepte une valeur unique ou une liste séparée par des virgules ("dumbbell,barbell")
                // → filtre "mon matériel" (plusieurs équipements possédés).
                $values = array_values(array_filter(is_array($equipment) ? $equipment : explode(',', (string) $equipment)));
                $query->whereIn('equipment', $values);
            })
            ->when($request->query('target'), fn ($query, $target) => $query->where('target', $target))
            ->when($request->query('category'), fn ($query, $category) => $query->where('category', $category))
            ->orderBy('name')
            ->paginate((int) $request->query('per_page', self::DEFAULT_PER_PAGE));

        ExerciseListResource::$locale = $this->resolveLocale($request);

        return ExerciseListResource::collection($exercises);
    }

    /** GET /api/exercises/{exercise} — détail avec instructions dans la locale demandée. */
    public function show(Request $request, Exercise $exercise): ExerciseResource
    {
        return new ExerciseResource($exercise, $this->resolveLocale($request));
    }

    /**
     * GET /api/exercises/facets — valeurs distinctes pour les filtres.
     * Chaque valeur = { value: anglais (canonique, envoyé au filtre), label: traduit }.
     */
    public function facets(Request $request): JsonResponse
    {
        $locale = $this->resolveLocale($request);

        $facet = fn (string $column) => Exercise::query()
            ->whereNotNull($column)->distinct()->orderBy($column)->pluck($column)
            ->map(fn ($v) => ['value' => $v, 'label' => Exercise::localizeTerm($v, $locale)])
            ->values();

        return response()->json([
            'body_parts' => $facet('body_part'),
            'equipments' => $facet('equipment'),
            'targets' => $facet('target'),
            'categories' => $facet('category'),
        ]);
    }

    /** Résout la locale demandée : paramètre `locale`, sinon header Accept-Language, sinon 'fr'. */
    private function resolveLocale(Request $request): string
    {
        $locale = $request->query('locale');

        if ($locale) {
            return (string) $locale;
        }

        $acceptLanguage = $request->header('Accept-Language');

        if (! $acceptLanguage) {
            return self::DEFAULT_LOCALE;
        }

        // Le header peut lister plusieurs langues pondérées ("fr-FR,fr;q=0.9,en;q=0.8") : on ne garde que la première.
        $firstLanguage = strtok($acceptLanguage, ',');
        $languageTag = strtok($firstLanguage, ';');

        return $languageTag !== false ? $languageTag : self::DEFAULT_LOCALE;
    }
}
