// 영어문법학습 — 메인 화면들
// Home / ChapterDetail / Quiz / Completion / GrammarRef

const { useEffect, useState, useMemo, useRef, useCallback } = React;

// ============================================================
// 홈 화면 — 챕터 리스트
// ============================================================
function HomeScreen({ chapters, progress, onOpenChapter, onOpenGrammar }) {
  const totalChapters = chapters.length;
  const completed = Object.values(progress).filter(p => p?.completed).length;

  // 챕터를 종류별로 그룹화
  const groups = useMemo(() => {
    const result = [];
    let current = null;
    chapters.forEach((ch, idx) => {
      if (!current) {
        current = { title: "기초", items: [] };
        result.push(current);
      }
      current.items.push({ chapter: ch, index: idx });

      // mega review 후에는 새 그룹 시작
      if (ch.kind === "mega") {
        current = null;
      }
    });
    return result;
  }, [chapters]);

  const groupLabels = ["현재시제 기초", "과거·미래시제 확장", "전체 마스터"];

  return (
    <div className="fade-in" style={{ paddingTop: 8 }}>
      <div style={{ padding: "12px 4px 22px" }}>
        <div style={{
          fontSize: 13,
          fontWeight: 700,
          letterSpacing: "0.08em",
          textTransform: "uppercase",
          color: "var(--text-muted)",
          marginBottom: 6
        }}>
          중학교 영문법 · 동사 시제
        </div>
        <h1 style={{
          margin: 0,
          fontSize: 28,
          fontWeight: 800,
          letterSpacing: "-0.03em",
          color: "var(--text)"
        }}>
          오늘은 어떤 문법을 공부할까요?
        </h1>
        <p style={{
          margin: "10px 0 0",
          color: "var(--text-soft)",
          fontSize: 14,
          lineHeight: 1.6
        }}>
          한국어 문장을 보고 영어로 빈칸을 채우세요. 챕터마다 5~10개 문제,
          5개 연속 맞히면 미리 마칠 수 있어요.
        </p>
        <div style={{
          marginTop: 14,
          fontSize: 13,
          color: "var(--text-muted)"
        }}>
          진행도 · <b style={{ color: "var(--text)" }}>{completed}</b> / {totalChapters} 챕터 완료
        </div>
      </div>

      {groups.map((group, gi) => {
        const label = groupLabels[gi] || `섹션 ${gi + 1}`;
        return (
          <div key={gi}>
            <div className="section-title">{label}</div>
            <div className="chapter-grid">
              {group.items.map(({ chapter, index }) => (
                <ChapterCard
                  key={chapter.id}
                  chapter={chapter}
                  index={index}
                  progress={progress[chapter.id]}
                  onClick={() => onOpenChapter(chapter.id)}
                />
              ))}
            </div>
          </div>
        );
      })}

      <div className="section-title">문법 정리 모드</div>
      <button className="card" onClick={onOpenGrammar} style={{
        cursor: "pointer", textAlign: "left", width: "100%",
        padding: 20, display: "flex", alignItems: "center", gap: 16,
        background: "var(--bg-elevated)"
      }}>
        <div className="chapter-card-icon" style={{ background: "var(--brand-faint)" }}>
          <Icon name="book" size={22} />
        </div>
        <div style={{ flex: 1 }}>
          <div className="chapter-card-title">문법 모아보기</div>
          <div className="chapter-card-meta">
            모든 챕터의 문법 설명을 퀴즈 없이 한꺼번에 읽기
          </div>
        </div>
        <Icon name="arrow-right" size={18} />
      </button>
    </div>
  );
}

// ============================================================
// 챕터 상세 — 시작하기 / 문법 보기 / 미리 보기
// ============================================================
function ChapterDetailScreen({ chapter, progress, onBack, onStart, onStudy, chapterIndex }) {
  if (!chapter) return null;
  const isReview = chapter.kind === "review";
  const isMega = chapter.kind === "mega";

  let kicker = `CHAPTER ${chapterIndex + 1}`;
  if (isReview) kicker = "✦ 통합 정리";
  if (isMega) kicker = "✦✦ 대왕 통합 정리";

  return (
    <div className="fade-in">
      <div style={{ padding: "8px 0" }}>
        <button className="btn btn-soft btn-sm" onClick={onBack}>
          <Icon name="arrow-left" size={14} /> 챕터 목록
        </button>
      </div>
      <div style={{
        padding: "28px 4px 20px",
        textAlign: "left"
      }}>
        <div style={{
          fontSize: 12, fontWeight: 800, letterSpacing: "0.1em",
          textTransform: "uppercase",
          color: isMega ? "#8B6A30" : isReview ? "#B58A3F" : "var(--text-muted)",
          marginBottom: 8
        }}>{kicker}</div>
        <h1 style={{
          margin: 0,
          fontSize: 32,
          fontWeight: 800,
          letterSpacing: "-0.03em"
        }}>{chapter.title}</h1>
        {chapter.blurb && (
          <p style={{
            color: "var(--text-soft)",
            fontSize: 16,
            marginTop: 8
          }}>{chapter.blurb}</p>
        )}
        <div style={{
          marginTop: 14,
          color: "var(--text-muted)",
          fontSize: 13
        }}>
          {chapter.questions?.length || 0}문제 ·
          {progress?.completed ? " ✓ 완료" : " 미완료"}
          {progress?.total > 0 && (
            <> · 최고 점수 <b style={{ color: "var(--text)" }}>{progress.score}/{progress.total}</b></>
          )}
        </div>
      </div>

      <div className="grammar-block" dangerouslySetInnerHTML={{ __html: chapter.summary || "" }} />

      <div style={{ display: "flex", flexDirection: "column", gap: 12, marginTop: 22 }}>
        <button className="btn btn-primary btn-lg btn-block" onClick={onStart}>
          {progress?.completed ? "다시 풀어보기" : "퀴즈 시작하기"} →
        </button>
        <button className="btn btn-ghost btn-block" onClick={onStudy}>
          <Icon name="book" size={16} /> 문법만 정리해서 보기
        </button>
      </div>
    </div>
  );
}

// ============================================================
// 퀴즈 화면
// ============================================================
function QuizScreen({ chapter, onExit, onComplete, chapterIndex }) {
  const original = chapter.questions || [];

  // 큐: 원본 + (잘못 맞춘 것들이 append)
  const [queue, setQueue] = useState(() => [...original.map(q => ({ q, isRetry: false }))]);
  const [cursor, setCursor] = useState(0);

  // 슬롯에 채워넣은 단어 인덱스(word bank 내 인덱스)
  const [selectedIndices, setSelectedIndices] = useState([]);
  const [answered, setAnswered] = useState(false);
  const [isCorrect, setIsCorrect] = useState(false);

  // 통계
  const [firstTryCorrectIds, setFirstTryCorrectIds] = useState(new Set()); // 첫 시도에 맞춘 문제 id
  const [seenFirstTime, setSeenFirstTime] = useState(new Set());           // 첫 시도 종료된 문제 id
  const [streak, setStreak] = useState(0);
  const [maxStreak, setMaxStreak] = useState(0);

  // word bank: 정답 단어 + distractors를 섞은 배열
  // cursor가 바뀔 때마다 재생성
  const current = queue[cursor];

  // 정답 + distractor 셔플 — 메모이즈 (현재 큐 위치 기준)
  const wordBank = useMemo(() => {
    if (!current) return [];
    const ans = current.q.answer || [];
    const dis = current.q.distractors || [];
    const pool = [...ans, ...dis];
    // 시드 셔플
    let seed = (cursor + 1) * 9301 + 49297;
    const rand = () => {
      seed = (seed * 9301 + 49297) % 233280;
      return seed / 233280;
    };
    const arr = pool.slice();
    for (let i = arr.length - 1; i > 0; i--) {
      const j = Math.floor(rand() * (i + 1));
      [arr[i], arr[j]] = [arr[j], arr[i]];
    }
    return arr;
  }, [cursor, current?.q.id]);

  // 큐 변화로 cursor가 길이를 초과하지 않게 보장
  useEffect(() => {
    // 새 문제로 이동할 때 입력 상태 초기화
    setSelectedIndices([]);
    setAnswered(false);
    setIsCorrect(false);
  }, [cursor, current?.q.id]);

  if (!current) {
    // 큐가 비어있음 → 완료
    return null;
  }

  const totalOriginal = original.length;
  const firstTryDone = seenFirstTime.size;
  const correctCount = firstTryCorrectIds.size;

  // 진행도: 첫 시도 진행도(원본 기준) — 사용자에게 더 직관적
  // 단, 재시도 중일 때는 같은 값을 유지하다가, 큐 끝나면 더 채워질 수 있도록
  // 표시상은 (현재 큐 인덱스 / 큐 길이)로 계산
  const progressMax = queue.length;
  const progressValue = cursor + (answered ? 1 : 0);

  // 미리 마치기 조건:
  //   - 첫 5문제를 첫 시도에 모두 맞춤
  //   - 아직 5번째 문제까지만 진행 (cursor < 5 시점에 마지막 정답)
  //   - retry queue 비어있음
  const canEarlyFinish = (() => {
    if (firstTryDone < 5) return false;
    if (correctCount < 5) return false;
    // 모든 본 문제가 맞아야 함
    if (correctCount !== firstTryDone) return false;
    // 아직 원본 다 안 끝났을 때만 의미 있음
    if (firstTryDone >= totalOriginal) return false;
    // 현재 문제가 첫 5문제 안에 있어야 함 (5번째 정답 직후)
    return firstTryDone >= 5;
  })();

  function selectWord(bankIdx) {
    if (answered) return;
    if (selectedIndices.includes(bankIdx)) return;
    setSelectedIndices([...selectedIndices, bankIdx]);
  }

  function removeWordFromSlot(slotPos) {
    if (answered) return;
    const next = selectedIndices.slice();
    next.splice(slotPos, 1);
    setSelectedIndices(next);
  }

  function checkAnswer() {
    const userWords = selectedIndices.map(i => wordBank[i]);
    const ans = current.q.answer || [];
    const correct = userWords.length === ans.length &&
      userWords.every((w, i) => w.toLowerCase() === ans[i].toLowerCase());

    setIsCorrect(correct);
    setAnswered(true);

    if (!current.isRetry) {
      // 첫 시도 통계 업데이트
      const newSeen = new Set(seenFirstTime);
      newSeen.add(current.q.id);
      setSeenFirstTime(newSeen);

      if (correct) {
        const newCorrect = new Set(firstTryCorrectIds);
        newCorrect.add(current.q.id);
        setFirstTryCorrectIds(newCorrect);

        const ns = streak + 1;
        setStreak(ns);
        setMaxStreak(Math.max(maxStreak, ns));
      } else {
        setStreak(0);
        // 큐 끝에 다시 추가
        setQueue([...queue, { q: current.q, isRetry: true }]);
      }
    } else {
      // 재시도 — 통계에 영향 없음, streak도 변동 없음
      if (!correct) {
        // 재시도도 틀리면 또 큐에 추가
        setQueue([...queue, { q: current.q, isRetry: true }]);
      }
    }
  }

  function nextQuestion() {
    // 다음 큐 항목으로
    const nextCursor = cursor + 1;
    if (nextCursor >= queue.length) {
      // 모두 끝남
      onComplete({
        score: firstTryCorrectIds.size,
        total: totalOriginal,
        maxStreak: maxStreak,
        attempted: queue.length
      });
    } else {
      setCursor(nextCursor);
    }
  }

  function earlyFinish() {
    onComplete({
      score: firstTryCorrectIds.size,
      total: 5,  // 미리 마치기는 5/5
      maxStreak,
      attempted: cursor + 1,
      early: true
    });
  }

  // 정답 확인용 텍스트
  const correctAnswerText = (current.q.answer || []).join(" ");
  const renderSentence = () => {
    const prefix = current.q.prefix || [];
    const suffix = current.q.suffix || [];
    const slotClass = "sentence-blank" +
      (selectedIndices.length > 0 ? " has-tokens" : "") +
      (answered ? (isCorrect ? " correct" : " wrong") : "");

    return (
      <div className="sentence-builder">
        {prefix.map((w, i) => <span className="sentence-word" key={"p" + i}>{w}</span>)}
        <span className={slotClass}>
          {selectedIndices.length === 0 ? (
            <span style={{ color: "var(--text-faint)", fontSize: 14, fontFamily: "var(--font-eng)", fontStyle: "italic" }}>
              ?
            </span>
          ) : (
            selectedIndices.map((bankIdx, pos) => (
              <span
                key={pos}
                className="token-in-slot"
                onClick={() => removeWordFromSlot(pos)}
                title={answered ? "" : "탭하여 취소"}
              >
                {wordBank[bankIdx]}
              </span>
            ))
          )}
        </span>
        {suffix.map((w, i) => <span className="sentence-word" key={"s" + i}>{w}</span>)}
      </div>
    );
  };

  return (
    <div className="quiz-screen fade-in">
      <div className="quiz-header">
        <button className="quiz-close" onClick={onExit} title="나가기">
          <Icon name="x" size={18} />
        </button>
        <ProgressBar value={progressValue} max={progressMax} />
        {streak >= 2 && (
          <div className="streak-badge">
            <Icon name="flame" size={14} /> {streak} 연속
          </div>
        )}
      </div>

      <div className="quiz-prompt">
        <div className="quiz-prompt-label">한국어 문장</div>
        <div className="quiz-prompt-text">{current.q.ko}</div>
        {current.isRetry && (
          <div className="quiz-hint" style={{ marginTop: 12 }}>
            ↻ 다시 한 번 — 이번엔 맞춰보세요
          </div>
        )}
      </div>

      {renderSentence()}

      <div className="word-bank">
        {wordBank.map((w, i) => {
          const used = selectedIndices.includes(i);
          return (
            <button
              key={i}
              className={"word-card" + (used ? " used" : "")}
              onClick={() => selectWord(i)}
              disabled={used || answered}
            >
              <span className="word-card-inner">{w}</span>
            </button>
          );
        })}
      </div>

      {answered && (
        <div className={"result-panel " + (isCorrect ? "correct" : "wrong")}>
          <div className="result-headline">
            <span className="result-headline-icon">
              <Icon name={isCorrect ? "check" : "x"} size={14} />
            </span>
            {isCorrect ? "정답입니다!" : "다시 한 번 볼게요"}
          </div>
          {!isCorrect && (
            <div className="result-correct-answer">
              <span className="result-correct-answer-label">정답</span>
              {correctAnswerText}
            </div>
          )}
          {current.q.explanation && (
            <div className="explanation">
              <div className="explanation-title">문법 설명</div>
              <div dangerouslySetInnerHTML={{ __html: current.q.explanation }} />
            </div>
          )}
        </div>
      )}

      <div className="quiz-spacer" />

      <div className="quiz-footer">
        {!answered ? (
          <>
            {canEarlyFinish && (
              <button
                className="btn btn-soft"
                onClick={earlyFinish}
                title="5문제 모두 정답 — 미리 마치기"
              >
                <Icon name="sparkles" size={14} /> 미리 마치기 (5/5)
              </button>
            )}
            <button
              className="btn btn-primary btn-block"
              onClick={checkAnswer}
              disabled={selectedIndices.length === 0}
            >
              확인
            </button>
          </>
        ) : (
          <button
            className={"btn btn-block " + (isCorrect ? "btn-correct" : "btn-wrong")}
            onClick={nextQuestion}
          >
            계속하기 →
          </button>
        )}
      </div>
    </div>
  );
}

// ============================================================
// 완료 화면
// ============================================================
function CompletionScreen({ chapter, result, onBackHome, onRetry }) {
  const [showConfetti, setShowConfetti] = useState(false);
  useEffect(() => {
    const t = setTimeout(() => setShowConfetti(true), 250);
    return () => clearTimeout(t);
  }, []);

  const pct = result.total > 0 ? Math.round((result.score / result.total) * 100) : 0;
  let praise = "잘했어요!";
  if (pct === 100) praise = "완벽해요! 🎉";
  else if (pct >= 80) praise = "정말 잘했어요!";
  else if (pct >= 60) praise = "한 번 더 풀어볼까요?";
  else praise = "괜찮아요, 차근차근!";

  return (
    <div className="completion-screen fade-in">
      <Confetti trigger={showConfetti} />
      <div className="completion-medal">
        <Icon name="trophy" size={56} />
      </div>
      <div>
        <div className="completion-title">{praise}</div>
        <div className="completion-subtitle" style={{ marginTop: 10 }}>
          『{chapter.title}』
          {result.early ? " 챕터를 미리 마쳤어요." : " 챕터를 완료했어요."}
        </div>
      </div>
      <div className="score-display">
        <div className="score-cell accent">
          <div className="score-cell-label">정답</div>
          <div className="score-cell-value">{result.score}/{result.total}</div>
        </div>
        <div className="score-cell">
          <div className="score-cell-label">최대 콤보</div>
          <div className="score-cell-value">🔥 {result.maxStreak}</div>
        </div>
      </div>
      <div style={{ display: "flex", gap: 10, marginTop: 16, width: "100%", maxWidth: 360 }}>
        <button className="btn btn-soft btn-block" onClick={onRetry}>다시 풀기</button>
        <button className="btn btn-primary btn-block" onClick={onBackHome}>홈으로</button>
      </div>
    </div>
  );
}

// ============================================================
// 전체 문법 정리 화면 (모아보기)
// ============================================================
function GrammarRefScreen({ chapters, onBack }) {
  const [activeId, setActiveId] = useState(chapters[0]?.id);
  const active = chapters.find(c => c.id === activeId) || chapters[0];

  return (
    <div className="fade-in">
      <div style={{ padding: "8px 0 20px" }}>
        <button className="btn btn-soft btn-sm" onClick={onBack}>
          <Icon name="arrow-left" size={14} /> 홈으로
        </button>
      </div>
      <h1 style={{ fontSize: 28, fontWeight: 800, letterSpacing: "-0.03em", margin: "0 0 8px" }}>
        문법 모아보기
      </h1>
      <p style={{ color: "var(--text-soft)", margin: "0 0 22px", fontSize: 14 }}>
        궁금한 챕터의 문법만 골라 읽을 수 있어요. 퀴즈 없이 정리만!
      </p>

      <div style={{
        display: "flex", gap: 8, overflowX: "auto",
        paddingBottom: 8, marginBottom: 16,
        scrollbarWidth: "thin"
      }}>
        {chapters.map((ch) => {
          const isActive = ch.id === active?.id;
          return (
            <button
              key={ch.id}
              onClick={() => setActiveId(ch.id)}
              className={isActive ? "btn btn-primary btn-sm" : "btn btn-soft btn-sm"}
              style={{ whiteSpace: "nowrap", flexShrink: 0 }}
            >
              {ch.kind === "review" && "✦ "}
              {ch.kind === "mega" && "✦✦ "}
              {ch.title}
            </button>
          );
        })}
      </div>

      {active && (
        <>
          <div style={{
            fontSize: 13, fontWeight: 700, letterSpacing: "0.08em",
            textTransform: "uppercase", color: "var(--text-muted)", marginBottom: 8
          }}>
            {active.kind === "mega" ? "✦✦ 대왕 정리" : active.kind === "review" ? "✦ 통합 정리" : "기초"}
          </div>
          <h2 style={{ margin: "0 0 14px", fontSize: 22, letterSpacing: "-0.02em" }}>
            {active.title}
          </h2>
          <div className="grammar-block" dangerouslySetInnerHTML={{ __html: active.summary || "" }} />
        </>
      )}
    </div>
  );
}

Object.assign(window, {
  HomeScreen, ChapterDetailScreen, QuizScreen, CompletionScreen, GrammarRefScreen
});
