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

export interface FlashcardStudySessionLibraryMeta {
  fileName?: string;
  subject?: string;
  subSubject?: string;
  difficultyLabel?: string;
  statusLabel?: string;
  statusIcon?: string;
  statusClassName?: string;
  footerDetails?: string[];
}

interface FlashcardStudySessionProps {
  cards: FlashcardCard[];
  libraryMetaById: Map<number, FlashcardStudySessionLibraryMeta>;
  onAnswer: (card: FlashcardCard, correct: boolean) => Promise<void>;
  onEnd: () => void;
}

interface ConfettiParticle {
  x: number;
  y: number;
  vx: number;
  vy: number;
  color: string;
  size: number;
  life: number;
  maxLife: number;
  rotation: number;
  rotationSpeed: number;
}

function fireConfetti(canvas: HTMLCanvasElement) {
  const ctx = canvas.getContext('2d');
  if (!ctx) return;
  const c = ctx;

  const w = canvas.width = window.innerWidth;
  const h = canvas.height = window.innerHeight;

  const colors = ['#4f8f5a', '#3f7cac', '#c79539', '#7e65a8', '#f2dfb3', '#b75b4d'];
  const particles: ConfettiParticle[] = [];

  for (let i = 0; i < 120; i++) {
    particles.push({
      x: Math.random() * w,
      y: -20 - Math.random() * h * 0.5,
      vx: (Math.random() - 0.5) * 6,
      vy: Math.random() * 5 + 2,
      color: colors[Math.floor(Math.random() * colors.length)],
      size: Math.random() * 8 + 4,
      life: 0,
      maxLife: 80 + Math.random() * 60,
      rotation: Math.random() * Math.PI * 2,
      rotationSpeed: (Math.random() - 0.5) * 0.3,
    });
  }

  let animating = true;

  function animate() {
    if (!animating) return;
    c.clearRect(0, 0, w, h);

    let alive = 0;
    for (const particle of particles) {
      particle.life++;
      if (particle.life >= particle.maxLife) continue;
      alive++;
      particle.x += particle.vx;
      particle.y += particle.vy;
      particle.vy += 0.08;
      particle.vx *= 0.995;
      particle.rotation += particle.rotationSpeed;
      const alpha = 1 - particle.life / particle.maxLife;
      c.save();
      c.globalAlpha = alpha;
      c.translate(particle.x, particle.y);
      c.rotate(particle.rotation);
      c.fillStyle = particle.color;
      c.fillRect(-particle.size / 2, -particle.size / 4, particle.size, particle.size / 2);
      c.restore();
    }

    if (alive > 0) {
      requestAnimationFrame(animate);
    } else {
      c.clearRect(0, 0, w, h);
      animating = false;
    }
  }

  requestAnimationFrame(animate);
}

function resetTimeout(timeoutRef: { current: number | null }) {
  if (timeoutRef.current !== null) {
    window.clearTimeout(timeoutRef.current);
    timeoutRef.current = null;
  }
}

function formatFooter(meta: FlashcardStudySessionLibraryMeta | undefined) {
  const main = [meta?.fileName, meta?.subSubject].filter(Boolean).join(' - ');
  return main || 'Arquivo';
}

export function FlashcardStudySession({ cards, libraryMetaById, onAnswer, onEnd }: FlashcardStudySessionProps) {
  const [currentIndex, setCurrentIndex] = useState(0);
  const [showAnswer, setShowAnswer] = useState(false);
  const [submittingAnswer, setSubmittingAnswer] = useState(false);
  const [cardExiting, setCardExiting] = useState(false);
  const [stampState, setStampState] = useState<'correct' | 'wrong' | null>(null);
  const [flipped, setFlipped] = useState(false);
  const [sessionAnswers, setSessionAnswers] = useState<Record<number, boolean>>({});
  const [submissionError, setSubmissionError] = useState<string | null>(null);

  const confettiRef = useRef<HTMLCanvasElement>(null);
  const stampTimerRef = useRef<number | null>(null);
  const advanceTimerRef = useRef<number | null>(null);

  const currentCard = cards[currentIndex];
  const currentMeta = currentCard ? libraryMetaById.get(currentCard.libraryId) : undefined;
  const correctCount = Object.values(sessionAnswers).filter(Boolean).length;
  const remainingCount = cards.length - currentIndex;
  const progressPercent = cards.length > 0
    ? ((currentIndex + 1) / cards.length) * 100
    : 0;

  useEffect(() => {
    setCurrentIndex(0);
    setShowAnswer(false);
    setSubmittingAnswer(false);
    setCardExiting(false);
    setStampState(null);
    setFlipped(false);
    setSessionAnswers({});
    setSubmissionError(null);
  }, [cards]);

  useEffect(() => {
    return () => {
      resetTimeout(stampTimerRef);
      resetTimeout(advanceTimerRef);
    };
  }, []);

  useEffect(() => {
    if (showAnswer && flipped) return;
    if (!showAnswer && !flipped) return;
    setFlipped(showAnswer);
  }, [showAnswer, flipped]);

  useEffect(() => {
    function handleKeyDown(e: KeyboardEvent) {
      if (cards.length === 0 || !currentCard) return;
      if (e.target instanceof HTMLInputElement || e.target instanceof HTMLSelectElement || e.target instanceof HTMLTextAreaElement) return;

      if (e.code === 'Space' || e.code === 'Enter') {
        e.preventDefault();
        if (!showAnswer) {
          setShowAnswer(true);
        }
      } else if (e.code === 'KeyC' && showAnswer && !submittingAnswer) {
        e.preventDefault();
        void registerReviewAnswer(true);
      } else if (e.code === 'KeyW' && showAnswer && !submittingAnswer) {
        e.preventDefault();
        void registerReviewAnswer(false);
      }
    }

    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, [cards.length, showAnswer, submittingAnswer, currentCard]);

  const goToPrevious = () => {
    if (currentIndex === 0 || submittingAnswer) return;
    setCurrentIndex(currentIndex - 1);
    setShowAnswer(false);
    setFlipped(false);
    setStampState(null);
    setCardExiting(false);
    setSubmissionError(null);
  };

  const advanceCard = () => {
    if (currentIndex >= cards.length - 1) {
      onEnd();
      return;
    }

    setCurrentIndex(currentIndex + 1);
    setShowAnswer(false);
    setFlipped(false);
    setStampState(null);
    setCardExiting(false);
    setSubmittingAnswer(false);
    setSubmissionError(null);
  };

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

    resetTimeout(stampTimerRef);
    resetTimeout(advanceTimerRef);
    setSubmittingAnswer(true);
    setSubmissionError(null);

    try {
      await onAnswer(currentCard, correct);

      setStampState(correct ? 'correct' : 'wrong');

      if (correct && confettiRef.current) {
        fireConfetti(confettiRef.current);
      }

      setSessionAnswers((currentAnswers) => ({
        ...currentAnswers,
        [currentCard.id]: correct,
      }));

      stampTimerRef.current = window.setTimeout(() => {
        setCardExiting(true);
        stampTimerRef.current = null;
      }, 90);

      advanceTimerRef.current = window.setTimeout(() => {
        advanceCard();
        advanceTimerRef.current = null;
      }, 760);
    } catch (err: any) {
      resetTimeout(stampTimerRef);
      resetTimeout(advanceTimerRef);
      setSubmissionError(err?.message || 'Falha ao registrar resposta da revisão.');
      setSubmittingAnswer(false);
      setCardExiting(false);
      setStampState(null);
    }
  };

  if (!currentCard) {
    return (
      <div class="study-session-end">
        <h3>Sessão concluída!</h3>
        <p>Todos os cartões foram revisados.</p>
        <div class="study-session-end-actions">
          <Button variant="primary" onClick={onEnd}>Voltar à seleção</Button>
        </div>
      </div>
    );
  }

  return (
    <div class="flashcard-study">
      <canvas ref={confettiRef} class="study-confetti-canvas" />
      {submissionError && <div className="study-error">{submissionError}</div>}

      <div class="study-content-grid">
        <div class="study-panel">
          <div class="study-session-header">
            <div class="study-session-title">
              <h3>Sessão de Revisão</h3>
              <p>{currentIndex + 1} de {cards.length} cartões</p>
            </div>
            <div class="study-score-pill">
              <b>{correctCount}</b>
              <span>Corretos</span>
            </div>
          </div>

          <div class="study-stage">
            <div
              class={`study-flashcard${flipped ? ' is-flipped' : ''}${cardExiting ? ' is-reviewed' : ''}`}
              onClick={() => { if (!showAnswer && !submittingAnswer) setShowAnswer(true); }}
              tabIndex={0}
              role="button"
              aria-label={showAnswer ? 'Flashcard revelado' : 'Clique ou pressione Espaço para revelar'}
            >
              <div class="study-card-face">
                <div class="study-card-meta">
                  <span class="study-tag">{currentMeta?.subject || 'Geral'}</span>
                  <span>{currentMeta?.difficultyLabel || currentMeta?.statusLabel || 'Revisão'}</span>
                </div>
                <div class="study-card-question">
                  {currentCard.front}
                </div>
                <div class="study-card-footer">
                  <span>{formatFooter(currentMeta)}</span>
                  <span class="study-spacebar">Espaço</span>
                </div>
              </div>

              <div class="study-card-face study-card-back">
                {stampState && (
                  <div class={`study-stamp ${stampState} show`}>
                    {stampState === 'correct' ? 'Correto' : 'Incorreto'}
                  </div>
                )}
                <div class="study-card-meta">
                  <span class="study-tag">Resposta</span>
                  {currentMeta?.statusLabel ? (
                    <span class={`study-status-badge ${currentMeta.statusClassName || ''}`}>
                      {currentMeta.statusIcon && <span class="study-status-icon">{currentMeta.statusIcon}</span>}
                      {currentMeta.statusLabel}
                    </span>
                  ) : (
                    <span>{currentMeta?.difficultyLabel || 'Revisão'}</span>
                  )}
                </div>
                <div class="study-card-answer">
                  <div class="study-back-question">
                    <span>Pergunta</span>
                    <p>{currentCard.front}</p>
                  </div>
                  <div class="study-back-answer">
                    <span>Resposta</span>
                    <p>{currentCard.back}</p>
                  </div>
                  {currentMeta?.footerDetails && currentMeta.footerDetails.length > 0 && (
                    <div class="study-card-details">
                      {currentMeta.footerDetails.map((detail) => (
                        <span key={detail}>{detail}</span>
                      ))}
                    </div>
                  )}
                </div>
                <div class="study-card-footer">
                  <span>{formatFooter(currentMeta)}</span>
                  <span class="study-spacebar">C / W</span>
                </div>
              </div>
            </div>
          </div>

          <div class={`study-controls${showAnswer ? ' ready' : ''}`}>
            <button
              class="study-review-button correct"
              onClick={() => void registerReviewAnswer(true)}
              disabled={!showAnswer || submittingAnswer}
            >
              Correto
            </button>
            <button
              class="study-review-button wrong"
              onClick={() => void registerReviewAnswer(false)}
              disabled={!showAnswer || submittingAnswer}
            >
              Incorreto
            </button>
          </div>

          <div class="study-nav-row">
            <Button variant="secondary" onClick={goToPrevious} disabled={currentIndex === 0 || submittingAnswer}>
              Anterior
            </Button>
            <Button variant="secondary" onClick={onEnd}>
              Encerrar Sessão
            </Button>
          </div>
        </div>

        <div class="study-side-panel">
          <div class="study-panel-card">
            <h3>Progresso</h3>
            <div class="study-stat-grid">
              <div class="study-stat">
                <b>{currentIndex + 1}/{cards.length}</b>
                <span>Atual</span>
              </div>
              <div class="study-stat">
                <b>{correctCount}</b>
                <span>Corretos</span>
              </div>
            </div>
            <div class="study-track">
              <span style={{ width: `${progressPercent}%` }} />
            </div>
          </div>

          <div class="study-panel-card">
            <h3>Fila</h3>
            <div class="study-queue">
              {cards.slice(currentIndex, currentIndex + 5).map((card, index) => {
                const meta = libraryMetaById.get(card.libraryId);
                return (
                  <div key={card.id} class="study-queue-item">
                    <span class="study-queue-number">{currentIndex + index + 1}</span>
                    <strong>{card.front.substring(0, 40)}{card.front.length > 40 ? '...' : ''}</strong>
                    <span>{meta?.subject || ''}</span>
                  </div>
                );
              })}
              {remainingCount > 5 && (
                <div class="study-queue-more">
                  +{remainingCount - 5} restantes
                </div>
              )}
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}
