// 이 파일이 하는 일: 코스 퀴즈 페이지 — 문항을 풀고 제출하면 서버가 채점해
// 점수·정답·해설을 보여준다. 다시 풀기도 가능하다.
//
// 학습 포인트: 정답은 이 페이지에 "없다". 서버가 문항을 줄 때 정답을 빼고 주고(QuizController의
// QuestionResponse), 제출한 뒤에야 채점 결과에 정답·해설이 실려 온다.
// 개발자도구 Network 탭으로 직접 확인해 보세요 — 배운 것을 검증하는 최고의 실습!
import { useEffect, useState } from 'react';
import { Link, useParams, Navigate } from 'react-router-dom';
import client from '../api/client';
import { ALL_COURSES } from '../courseCatalog';

export default function QuizPage() {
  // 주소의 :slug 로 어느 코스의 퀴즈인지 알아낸다. (라우팅은 App.jsx 참고)
  const { slug } = useParams();
  const course = ALL_COURSES.find((c) => c.slug === slug);

  const [questions, setQuestions] = useState([]);
  const [answers, setAnswers] = useState({}); // {문항id: 고른 보기 번호}
  const [result, setResult] = useState(null); // 채점 결과 (제출 전엔 null)
  const [loading, setLoading] = useState(true);
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState('');

  useEffect(() => {
    let cancelled = false;
    setLoading(true);
    client
      .get(`/quiz/${slug}`)
      .then((res) => {
        if (!cancelled) setQuestions(res.data);
      })
      .catch(() => {
        if (!cancelled) setError('퀴즈를 불러오지 못했어요.');
      })
      .finally(() => {
        if (!cancelled) setLoading(false);
      });
    return () => {
      cancelled = true;
    };
  }, [slug]);

  // 존재하지 않는 코스 주소면 학습 센터로
  if (!course) {
    return <Navigate to="/learn" replace />;
  }

  function choose(questionId, optionIndex) {
    if (result) return; // 채점 후엔 답을 바꿀 수 없다
    setAnswers((prev) => ({ ...prev, [questionId]: optionIndex }));
  }

  async function submit() {
    const unanswered = questions.length - Object.keys(answers).length;
    if (unanswered > 0 && !window.confirm(`안 푼 문제가 ${unanswered}개 있어요. 그래도 제출할까요?`)) {
      return;
    }
    setSubmitting(true);
    setError('');
    try {
      const res = await client.post(`/quiz/${slug}/submit`, { answers });
      setResult(res.data);
      window.scrollTo({ top: 0, behavior: 'smooth' });
    } catch {
      setError('제출 중 문제가 생겼어요. 다시 시도해 주세요.');
    } finally {
      setSubmitting(false);
    }
  }

  function retry() {
    setAnswers({});
    setResult(null);
    window.scrollTo({ top: 0 });
  }

  // 채점 결과를 문항 id로 바로 찾을 수 있게 Map으로
  const gradedById = new Map((result?.results ?? []).map((g) => [g.questionId, g]));
  const percent =
    result && result.total > 0 ? Math.round((result.score / result.total) * 100) : 0;

  return (
    <div>
      <div className="hero compact">
        <div className="eyebrow">Quiz</div>
        <h1>
          {course.icon} {course.title} — 확인 퀴즈
        </h1>
        {result ? (
          <>
            <p>
              {result.score === result.total
                ? '만점! 이 코스를 완전히 소화했어요 🎉 아래에서 코스 완료를 눌러주세요.'
                : result.score >= Math.ceil(result.total * 0.6)
                  ? '좋아요! 틀린 문제의 해설을 읽고 다시 도전해 보세요.'
                  : '괜찮아요, 원래 처음엔 그래요. 코스를 한 번 더 읽고 다시 풀어봐요.'}
            </p>
            <div className="chip-row" style={{ alignItems: 'center' }}>
              <div className="stat">
                <span className="stat-num">{result.score} / {result.total}</span>
                <span className="stat-label">{percent}점</span>
              </div>
            </div>
          </>
        ) : (
          <p>
            코스에서 배운 내용 {questions.length}문항이에요. 다 풀고 제출하면 바로 채점됩니다.
            몇 번이든 다시 풀 수 있어요.
          </p>
        )}
      </div>

      {loading ? (
        <p className="empty">문제를 불러오는 중...</p>
      ) : questions.length === 0 ? (
        <div className="card">
          <p className="empty">이 코스에는 아직 퀴즈가 없어요.</p>
        </div>
      ) : (
        <>
          {questions.map((question, qi) => {
            const graded = gradedById.get(question.id);
            return (
              <div key={question.id} className="card" style={{ marginTop: 14 }}>
                <div style={{ fontWeight: 700, marginBottom: 10 }}>
                  <span style={{ color: 'var(--primary)', marginRight: 8 }}>Q{qi + 1}.</span>
                  {question.question}
                </div>
                <div style={{ display: 'grid', gap: 8 }}>
                  {question.options.map((option, oi) => {
                    const chosen = answers[question.id] === oi;
                    // 채점 후: 정답은 청록, 내가 고른 오답은 장미색으로 표시
                    let extra = {};
                    if (graded) {
                      if (oi === graded.correctIndex) {
                        extra = {
                          borderColor: 'var(--teal)',
                          background: 'color-mix(in srgb, var(--teal) 9%, transparent)',
                          fontWeight: 700,
                        };
                      } else if (chosen && !graded.correct) {
                        extra = {
                          borderColor: 'var(--rose)',
                          background: 'color-mix(in srgb, var(--rose) 8%, transparent)',
                        };
                      }
                    } else if (chosen) {
                      extra = { borderColor: 'var(--primary)', background: 'var(--primary-soft)' };
                    }
                    return (
                      // 학습 포인트: label로 감싸서 텍스트를 눌러도 라디오가 선택된다(접근성).
                      <label
                        key={oi}
                        style={{
                          display: 'flex',
                          gap: 10,
                          alignItems: 'flex-start',
                          padding: '10px 14px',
                          border: '1px solid var(--line)',
                          borderRadius: 10,
                          cursor: result ? 'default' : 'pointer',
                          ...extra,
                        }}
                      >
                        <input
                          type="radio"
                          name={`q-${question.id}`}
                          checked={chosen}
                          onChange={() => choose(question.id, oi)}
                          disabled={!!result}
                          style={{ marginTop: 4, accentColor: 'var(--primary)' }}
                        />
                        <span>{option}</span>
                      </label>
                    );
                  })}
                </div>
                {graded && (
                  <div className={graded.correct ? 'tip' : 'warn'} style={{ marginTop: 10 }}>
                    <b>{graded.correct ? '정답!' : '아쉬워요'}</b> {graded.explanation}
                  </div>
                )}
              </div>
            );
          })}

          {error && <p className="error-text" style={{ marginTop: 12 }}>{error}</p>}

          <div className="course-complete-bar" style={{ marginTop: 20 }}>
            <Link to={`/learn/${slug}`} className="btn btn-ghost">
              ← 코스로
            </Link>
            <span className="course-complete-label">
              {result
                ? `채점 완료 — ${result.score}/${result.total}`
                : `${Object.keys(answers).length} / ${questions.length} 풀었어요`}
            </span>
            {result ? (
              <button className="btn" onClick={retry}>다시 풀기</button>
            ) : (
              <button className="btn btn-primary" onClick={submit} disabled={submitting}>
                {submitting ? '채점 중...' : '제출하고 채점받기'}
              </button>
            )}
          </div>
        </>
      )}
    </div>
  );
}
