<?php

namespace App\Http\Controllers;

use App\Models\Card;
use App\Models\Course;
use App\Services\QuizService;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use Illuminate\View\View;

class StudyController extends Controller
{
    private const MODES = ['flashcards', 'qcm', 'open', 'infinite'];

    public function play(Request $request, Course $course, string $scope, string $mode, QuizService $quiz): View
    {
        abort_unless(in_array($mode, self::MODES, true), 404);

        $course->load('chapters');
        $chapter = null;

        if ($scope === 'all') {
            $cards = Card::query()
                ->whereIn('chapter_id', $course->chapters->pluck('id'))
                ->with('chapter')
                ->orderBy('chapter_id')
                ->orderBy('position')
                ->get();
            $cards = $this->dedupe($cards);
            $scopeName = 'Cours complet';
        } else {
            $chapter = $course->chapters->firstWhere('slug', $scope);
            abort_unless($chapter, 404);
            $cards = $chapter->cards()->with('chapter')->get();
            $scopeName = $chapter->name;
        }

        abort_if($cards->isEmpty(), 404);

        $deck = $cards->map(fn (Card $card) => [
            'id' => $card->id,
            'term' => $card->term,
            'definition' => $card->definition,
            'example' => $card->example,
            'section' => $card->chapter?->name,
            'chapter_id' => $card->chapter_id,
        ])->values();

        $questions = $mode === 'qcm' ? $quiz->generateQcm($cards, 20) : [];

        return view("study.{$mode}", [
            'course' => $course,
            'chapter' => $chapter,
            'scope' => $scope,
            'scopeName' => $scopeName,
            'mode' => $mode,
            'deck' => $deck,
            'questions' => $questions,
            'cardCount' => $deck->count(),
        ]);
    }

    /**
     * Remove cards whose term repeats (case/accent-insensitive) across chapters
     * so a full-course deck never shows the same concept twice.
     *
     * @param  Collection<int, Card>  $cards
     * @return Collection<int, Card>
     */
    private function dedupe(Collection $cards): Collection
    {
        $seen = [];

        return $cards->filter(function (Card $card) use (&$seen) {
            $key = $this->normalize($card->term);
            if (isset($seen[$key])) {
                return false;
            }
            $seen[$key] = true;

            return true;
        })->values();
    }

    private function normalize(string $term): string
    {
        $ascii = Str::ascii($term);

        return preg_replace('/[^a-z0-9]/', '', strtolower($ascii)) ?? '';
    }
}
