import { useEffect, useMemo, useState } from 'preact/hooks';
import {
  MindforgeApiService,
  type FlashcardCard,
  type FlashcardLibrarySummary,
} from '../services/MindforgeApiService';
import { Button } from './Button';
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 === 'Hard' ? 'Dificil' : 'Facil';
}

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[]>([]);
  const [currentIndex, setCurrentIndex] = useState(0);
  const [showAnswer, setShowAnswer] = useState(false);
  const [submittingAnswer, setSubmittingAnswer] = useState(false);

  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 libraryById = useMemo(() => {
    return new Map(libraries.map((library) => [library.id, library]));
  }, [libraries]);

  const currentCard = sessionCards[currentIndex];
  const progressPercent = sessionCards.length > 0
    ? ((currentIndex + 1) / sessionCards.length) * 100
    : 0;

  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 revisao.');
      return;
    }

    setLoadingSession(true);
    setError(null);

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

      setSessionCards(shuffleCards(response.cards));
      setCurrentIndex(0);
      setShowAnswer(false);
    } catch (err: any) {
      setError(err?.message || 'Falha ao iniciar sessao de revisao.');
    } finally {
      setLoadingSession(false);
    }
  };

  const endSession = () => {
    setSessionCards([]);
    setCurrentIndex(0);
    setShowAnswer(false);
    setSubmittingAnswer(false);
  };

  const goToPrevious = () => {
    if (currentIndex === 0) {
      return;
    }
    setCurrentIndex(currentIndex - 1);
    setShowAnswer(false);
  };

  const registerReviewAnswer = async (correct: boolean) => {
    if (!currentCard) {
      return;
    }

    setSubmittingAnswer(true);
    setError(null);

    try {
      await MindforgeApiService.recordFlashcardReviewAnswer({
        cardId: currentCard.id,
        correct,
      });

      if (currentIndex >= sessionCards.length - 1) {
        endSession();
        return;
      }

      setCurrentIndex(currentIndex + 1);
      setShowAnswer(false);
    } catch (err: any) {
      setError(err?.message || 'Falha ao registrar resposta da revisao.');
    } finally {
      setSubmittingAnswer(false);
    }
  };

  return (
    <div className="review-container">
      <h2 className="title review-title">Revisao Flashcards</h2>
      <p className="subtitle">Escolha as bibliotecas para estudar e inicie uma sessao de revisao.</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 comecar.</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} cards - {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 Revisao'}
            </Button>
          </div>
        </div>
      )}

      {sessionCards.length > 0 && currentCard && (
        <div className="review-session-panel">
          <div className="review-progress">
            <span>{currentIndex + 1} / {sessionCards.length}</span>
            <div className="review-progress-bar">
              <div className="review-progress-fill" style={{ width: `${progressPercent}%` }} />
            </div>
          </div>

          <article className="review-card">
            <header>
              <small>
                {libraryById.get(currentCard.libraryId)?.fileName || 'Arquivo'} -
                {' '}
                {libraryById.get(currentCard.libraryId)?.subject || 'Geral'}
              </small>
            </header>
            <h3>Frente</h3>
            <p>{currentCard.front}</p>
            {showAnswer && (
              <>
                <h3>Verso</h3>
                <p>{currentCard.back}</p>
              </>
            )}
          </article>

          <div className="review-session-actions">
            <Button variant="secondary" onClick={goToPrevious} disabled={currentIndex === 0 || submittingAnswer}>
              Anterior
            </Button>

            {!showAnswer && (
              <Button variant="primary" onClick={() => setShowAnswer(true)}>
                Revelar Resposta
              </Button>
            )}

            {showAnswer && (
              <>
                <Button variant="primary" onClick={() => registerReviewAnswer(true)} disabled={submittingAnswer}>
                  Acertei
                </Button>
                <Button variant="secondary" onClick={() => registerReviewAnswer(false)} disabled={submittingAnswer}>
                  Errei
                </Button>
              </>
            )}

            <Button variant="secondary" onClick={endSession}>
              Encerrar Sessao
            </Button>
          </div>
        </div>
      )}
    </div>
  );
}
