import { useEffect, useMemo, useState } from 'preact/hooks';
import {
  MindforgeApiService,
  type FlashcardCard,
  type FlashcardLibrarySummary,
} from '../services/MindforgeApiService';
import { Button } from './Button';
import {
  FlashcardStudySession,
  type FlashcardStudySessionLibraryMeta,
} from './FlashcardStudySession';
import './FlashcardReviewComponent.css';

function groupLibrariesBySubject(libraries: FlashcardLibrarySummary[]) {
  const grouped: Record<string, FlashcardLibrarySummary[]> = {};
  libraries.forEach((library) => {
    const subject = library.subject || 'Geral';
    if (!grouped[subject]) {
      grouped[subject] = [];
    }
    grouped[subject].push(library);
  });

  return Object.entries(grouped).sort(([a], [b]) => a.localeCompare(b));
}

function difficultyLabel(difficulty: string) {
  return difficulty === 'Medium' ? 'Médio' : 'Fácil';
}

function shuffleCards(cards: FlashcardCard[]) {
  const shuffled = [...cards];
  for (let i = shuffled.length - 1; i > 0; i--) {
    const randomIndex = Math.floor(Math.random() * (i + 1));
    [shuffled[i], shuffled[randomIndex]] = [shuffled[randomIndex], shuffled[i]];
  }
  return shuffled;
}

export function FlashcardReviewComponent() {
  const [libraries, setLibraries] = useState<FlashcardLibrarySummary[]>([]);
  const [selectedLibraryIds, setSelectedLibraryIds] = useState<number[]>([]);
  const [loadingLibraries, setLoadingLibraries] = useState(true);
  const [loadingSession, setLoadingSession] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [sessionCards, setSessionCards] = useState<FlashcardCard[]>([]);

  useEffect(() => {
    let cancelled = false;

    async function loadLibraries() {
      setLoadingLibraries(true);
      setError(null);

      try {
        const result = await MindforgeApiService.getFlashcardLibraries();
        if (!cancelled) {
          setLibraries(result);
        }
      } catch (err: any) {
        if (!cancelled) {
          setError(err?.message || 'Falha ao carregar bibliotecas de flashcards.');
        }
      } finally {
        if (!cancelled) {
          setLoadingLibraries(false);
        }
      }
    }

    loadLibraries();
    return () => {
      cancelled = true;
    };
  }, []);

  const groupedLibraries = useMemo(() => groupLibrariesBySubject(libraries), [libraries]);

  const libraryMetaById = useMemo(() => {
    return new Map<number, FlashcardStudySessionLibraryMeta>(
      libraries.map((library) => [
        library.id,
        {
          fileName: library.fileName,
          subject: library.subject || 'Geral',
          difficultyLabel: difficultyLabel(library.difficulty),
        },
      ]),
    );
  }, [libraries]);

  const toggleLibrary = (libraryId: number) => {
    if (selectedLibraryIds.includes(libraryId)) {
      setSelectedLibraryIds(selectedLibraryIds.filter((id) => id !== libraryId));
      return;
    }
    setSelectedLibraryIds([...selectedLibraryIds, libraryId]);
  };

  const startReviewSession = async () => {
    if (selectedLibraryIds.length === 0) {
      setError('Selecione ao menos uma biblioteca para iniciar a revisão.');
      return;
    }

    setLoadingSession(true);
    setError(null);
    setSessionCards([]);

    try {
      const response = await MindforgeApiService.createFlashcardReviewSession({
        libraryIds: selectedLibraryIds,
      });
      const shuffledCards = shuffleCards(response.cards);

      if (shuffledCards.length === 0) {
        setError('As bibliotecas selecionadas não possuem cartões para revisar.');
        return;
      }

      setSessionCards(shuffledCards);
    } catch (err: any) {
      setError(err?.message || 'Falha ao iniciar sessão de revisão.');
    } finally {
      setLoadingSession(false);
    }
  };

  const endSession = () => {
    setSessionCards([]);
  };

  const recordReviewAnswer = async (card: FlashcardCard, correct: boolean) => {
    setError(null);
    await MindforgeApiService.recordFlashcardReviewAnswer({
      cardId: card.id,
      correct,
    });
  };

  return (
    <div className="review-container">
      <h2 className="review-title">Revisão de Flashcards</h2>
      <p className="review-subtitle">Escolha as bibliotecas para estudar e inicie uma sessão de revisão.</p>

      {error && <div className="review-error">{error}</div>}

      {sessionCards.length === 0 && (
        <div className="review-select-panel">
          {loadingLibraries && <p className="review-state">Carregando bibliotecas...</p>}
          {!loadingLibraries && libraries.length === 0 && (
            <p className="review-state">Nenhuma biblioteca encontrada. Gere flashcards para começar.</p>
          )}

          {!loadingLibraries && libraries.length > 0 && (
            <div className="review-subjects">
              {groupedLibraries.map(([subject, subjectLibraries]) => (
                <section key={subject} className="review-subject-section">
                  <h3>{subject}</h3>
                  <div className="review-library-list">
                    {subjectLibraries.map((library) => (
                      <label key={library.id} className="review-library-item">
                        <input
                          type="checkbox"
                          checked={selectedLibraryIds.includes(library.id)}
                          onChange={() => toggleLibrary(library.id)}
                        />
                        <div className="review-library-texts">
                          <strong>{library.fileName}</strong>
                          <span>
                            {library.cardCount} cartões - {difficultyLabel(library.difficulty)}
                          </span>
                        </div>
                      </label>
                    ))}
                  </div>
                </section>
              ))}
            </div>
          )}

          <div className="review-actions">
            <Button variant="primary" onClick={startReviewSession} disabled={loadingSession || selectedLibraryIds.length === 0}>
              {loadingSession ? 'Iniciando...' : 'Iniciar Revisão'}
            </Button>
          </div>
        </div>
      )}

      {sessionCards.length > 0 && (
        <FlashcardStudySession
          cards={sessionCards}
          libraryMetaById={libraryMetaById}
          onAnswer={recordReviewAnswer}
          onEnd={endSession}
        />
      )}
    </div>
  );
}
