/* ============================================================
   pincard.jsx — S3 핀 카드 (문제 모달)
   Q1 변동유형 5택 + Q2 핀별 5종 변주 + 해설/교과 토글
   ============================================================ */

/* 장소 사진 — 실제 사진(단일/변신 비교) 또는 실루엣 플레이스홀더 */
function PhotoPlaceholder({ pin }) {
  const t = window.typeById(pin.typeId);

  if (pin.photos && pin.photos.length >= 2) {
    const [a, b] = pin.photos;
    return (
      <div className={`photoreal split ${t.cls}`}>
        <figure className="ph-half">
          <img src={a.src} alt={a.tag || pin.name} loading="lazy" />
          {a.tag ? <figcaption className="ph-tag">{a.tag}</figcaption> : null}
        </figure>
        <span className="ph-arrow" aria-hidden="true">→</span>
        <figure className="ph-half">
          <img src={b.src} alt={b.tag || pin.name} loading="lazy" />
          {b.tag ? <figcaption className="ph-tag">{b.tag}</figcaption> : null}
        </figure>
      </div>
    );
  }

  if (pin.photos && pin.photos.length === 1) {
    return (
      <div className={`photoreal ${t.cls}`}>
        <img src={pin.photos[0].src} alt={pin.name} loading="lazy" />
      </div>
    );
  }

  return (
    <div className={`photoph ${t.cls}`}>
      <svg viewBox="0 0 320 150" preserveAspectRatio="xMidYMid slice" width="100%" height="100%">
        <rect width="320" height="150" fill="var(--c)" opacity="0.16" />
        <rect width="320" height="150" fill="var(--c-soft)" />
        {/* 산업유산 실루엣: 굴뚝·톱니지붕 공장 + 새 건물 */}
        <g fill="var(--c)" opacity="0.5">
          <rect x="18" y="92" width="46" height="48" />
          <rect x="28" y="60" width="9" height="36" />
          <path d="M70 140 V96 L86 88 V96 L102 88 V96 L118 88 V140 Z" />
          <rect x="150" y="74" width="40" height="66" rx="2" />
          <rect x="200" y="58" width="30" height="82" rx="2" />
          <rect x="240" y="86" width="58" height="54" rx="2" />
        </g>
        <g fill="var(--c)" opacity="0.85">
          <rect x="206" y="66" width="5" height="5" /><rect x="216" y="66" width="5" height="5" />
          <rect x="206" y="78" width="5" height="5" /><rect x="216" y="78" width="5" height="5" />
          <rect x="206" y="90" width="5" height="5" /><rect x="216" y="90" width="5" height="5" />
          <rect x="158" y="84" width="6" height="6" /><rect x="170" y="84" width="6" height="6" />
          <rect x="158" y="98" width="6" height="6" /><rect x="170" y="98" width="6" height="6" />
        </g>
        <line x1="0" y1="140" x2="320" y2="140" stroke="var(--c)" strokeWidth="2" opacity="0.6" />
      </svg>
      <span className="photoph-tag">장소 사진 (예시 자리)</span>
    </div>
  );
}

/* ---------- Q2 변주 컴포넌트 5종 ---------- */
function Q2Multi({ q2, value, onChange, locked }) {
  const sel = value || [];
  const toggle = (i) => {
    if (locked) return;
    onChange((prev) => {
      const s = prev || [];
      return s.includes(i) ? s.filter((x) => x !== i) : [...s, i];
    });
  };
  return (
    <div className="opt-list">
      {q2.options.map((opt, i) => (
        <button key={i} className={`checkrow ${sel.includes(i) ? "on" : ""}`} onClick={() => toggle(i)} disabled={locked}>
          <span className="checkbox">{sel.includes(i) ? "✓" : ""}</span>
          {opt}
        </button>
      ))}
    </div>
  );
}

function Q2Blank2({ q2, value, onChange, locked }) {
  const v = value || { a: "", b: "" };
  return (
    <div className="blank-list">
      {q2.blanks.map((b, i) => {
        const k = i === 0 ? "a" : "b";
        return (
          <div key={i} className="blank-row">
            <label>{b.label}</label>
            <input type="text" value={v[k] || ""} placeholder={b.placeholder} disabled={locked}
              onChange={(e) => onChange({ ...v, [k]: e.target.value })} />
          </div>
        );
      })}
    </div>
  );
}

function Q2Toggle({ q2, value, onChange, locked }) {
  const v = value || { choice: null, reason: "" };
  return (
    <div>
      <div className="toggle-cards">
        {q2.options.map((opt) => (
          <button key={opt.key} className={`tcard ${v.choice === opt.key ? "on" : ""}`}
            onClick={() => !locked && onChange({ ...v, choice: opt.key })} disabled={locked}>
            <b>{opt.title}</b>
            <span>{opt.desc}</span>
          </button>
        ))}
      </div>
      <label className="mini-label">{q2.reasonLabel}</label>
      <textarea className="ta" rows="2" value={v.reason || ""} placeholder={q2.reasonPlaceholder} disabled={locked}
        onChange={(e) => onChange({ ...v, reason: e.target.value })} />
    </div>
  );
}

function Q2Slider({ q2, value, onChange, locked }) {
  const v = value || { val: 2, reason: "" };
  return (
    <div>
      <div className="slider-ends"><span>{q2.left}</span><span>{q2.right}</span></div>
      <input type="range" className="slider" min="0" max="4" step="1" value={v.val} disabled={locked}
        onChange={(e) => onChange({ ...v, val: +e.target.value })} />
      <div className="slider-now">{q2.labels[v.val]}</div>
      <label className="mini-label">{q2.reasonLabel}</label>
      <textarea className="ta" rows="2" value={v.reason || ""} placeholder={q2.reasonPlaceholder} disabled={locked}
        onChange={(e) => onChange({ ...v, reason: e.target.value })} />
    </div>
  );
}

function Q2Short({ q2, value, onChange, locked }) {
  return (
    <textarea className="ta" rows="3" value={(value && value.text) || ""} placeholder={q2.placeholder} disabled={locked}
      onChange={(e) => onChange({ text: e.target.value })} />
  );
}

function Q2Field({ pin, value, onChange, locked }) {
  const q2 = pin.q2;
  const P = { q2, value, onChange, locked };
  if (q2.type === "multi") return <Q2Multi {...P} />;
  if (q2.type === "blank2") return <Q2Blank2 {...P} />;
  if (q2.type === "toggle") return <Q2Toggle {...P} />;
  if (q2.type === "slider") return <Q2Slider {...P} />;
  return <Q2Short {...P} />;
}

function q2Valid(pin, v) {
  if (!v) return false;
  switch (pin.q2.type) {
    case "multi": return v.length > 0;
    case "blank2": return (v.a || "").trim() && (v.b || "").trim();
    case "toggle": return !!v.choice;
    case "slider": return v.val != null;
    case "short": return (v.text || "").trim().length > 0;
    default: return false;
  }
}

/* ---------- 낱말 퍼즐 (핀별 단어 조합) ---------- */
function shuffleTiles(chars) {
  let tiles = chars.map((ch, i) => ({ ch, id: i }));
  for (let pass = 0; pass < 8; pass++) {
    for (let i = tiles.length - 1; i > 0; i--) {
      const j = Math.floor(Math.random() * (i + 1));
      [tiles[i], tiles[j]] = [tiles[j], tiles[i]];
    }
    if (tiles.some((t, i) => t.id !== i)) break; // 우연히 정답 순서면 다시 섞기
  }
  return tiles;
}

function WordPuzzle({ puzzle, tone, solved, onSolve }) {
  const chars = React.useMemo(() => puzzle.answer.split(""), [puzzle.answer]);
  const [tiles] = useState(() => shuffleTiles(chars));
  const [placed, setPlaced] = useState([]); // 슬롯에 놓인 tile id 순서
  const [shake, setShake] = useState(false);
  const done = solved;

  const place = (id) => {
    if (done) return;
    setPlaced((prev) => {
      if (prev.includes(id) || prev.length >= chars.length) return prev;
      const next = [...prev, id];
      if (next.length === chars.length) {
        const word = next.map((tid) => tiles.find((t) => t.id === tid).ch).join("");
        if (word === puzzle.answer) setTimeout(onSolve, 0);
        else { setShake(true); setTimeout(() => { setShake(false); setPlaced([]); }, 550); }
      }
      return next;
    });
  };
  const pop = (idx) => { if (!done) setPlaced(placed.slice(0, idx)); };

  return (
    <div className={`puzzle ${tone} ${done ? "solved" : ""}`}>
      <div className="puzzle-head">
        <span className="puzzle-icon">🧩</span>
        <b>낱말 퍼즐</b>
        <span className="puzzle-sub">{done ? "완성!" : "글자를 순서대로 눌러 핵심 낱말을 맞춰요"}</span>
      </div>

      <div className={`puzzle-slots ${shake ? "shake" : ""}`}>
        {chars.map((_, i) => {
          const tid = placed[i];
          const ch = tid != null ? tiles.find((t) => t.id === tid).ch : null;
          return (
            <button key={i} className={`pslot ${ch ? "filled" : ""} ${done ? "ok" : ""}`}
              onClick={() => ch != null && pop(i)} disabled={done || ch == null}>
              {ch || ""}
            </button>
          );
        })}
      </div>

      {!done ? (
        <>
          <div className="puzzle-tray">
            {tiles.map((t) => (
              <button key={t.id} className={`ptile ${placed.includes(t.id) ? "used" : ""}`}
                onClick={() => place(t.id)} disabled={placed.includes(t.id)}>
                {t.ch}
              </button>
            ))}
          </div>
          <p className="puzzle-hint">힌트 · {puzzle.hint}</p>
        </>
      ) : (
        <p className="puzzle-reveal fade-up">✨ {puzzle.reveal}</p>
      )}
    </div>
  );
}

/* ---------- 탈출 미션 ---------- */
// 정답 판정은 서버가 전담 — 클라이언트는 입력만 전달하고 결과를 받아 표시
function EscapeMission({ pin, variantKey, escaped, onEscape }) {
  const variant = pin.escapeVariants && pin.escapeVariants[variantKey];
  const [input, setInput] = useState("");
  const [busy, setBusy] = useState(false);
  const [tried, setTried] = useState(false);   // 오답 표시용
  const [correct, setCorrect] = useState(escaped);
  const [showHint, setShowHint] = useState(false);

  if (!variant) return null;

  const handleCheck = async () => {
    if (!input.trim() || busy) return;
    setBusy(true);
    setTried(false);
    // 서버가 판정 — onEscape는 { correct: bool }를 resolve하는 Promise를 반환
    const result = await onEscape(input.trim());
    setBusy(false);
    if (result && result.correct) {
      setCorrect(true);
    } else {
      setTried(true);   // 오답
    }
  };

  if (correct) {
    return (
      <div className="escape-section escaped fade-up">
        <div className="escape-header">
          <span className="escape-icon">🔓</span>
          <span className="escape-title">탈출 완료!</span>
        </div>
        <p className="escape-success-msg">이 스테이션의 잠금이 해제됐어요.</p>
        {pin.deepen ? (
          <div className="deepen-box">
            <div className="deepen-title">생각해보기 · 모둠 토론</div>
            <p className="deepen-q">{pin.deepen}</p>
          </div>
        ) : null}
      </div>
    );
  }

  return (
    <div className="escape-section">
      <div className="escape-header">
        <span className="escape-icon">🔒</span>
        <span className="escape-title">탈출 미션</span>
        <span className="escape-badge">{variantKey}형</span>
      </div>
      <p className="escape-question">{variant.question}</p>
      {showHint && <p className="escape-hint">💡 {variant.hint}</p>}
      <button className="escape-hint-btn" onClick={() => setShowHint(!showHint)}>
        {showHint ? "힌트 숨기기" : "💡 힌트 보기"}
      </button>
      <div className="escape-input-row">
        <input
          className="escape-input"
          type={variant.answerType === "number" ? "number" : "text"}
          inputMode={variant.answerType === "number" ? "numeric" : "text"}
          value={input}
          placeholder={variant.answerType === "number" ? "숫자 입력" : "정답 입력"}
          onChange={(e) => { setInput(e.target.value); setTried(false); }}
          onKeyDown={(e) => e.key === "Enter" && handleCheck()}
          disabled={busy}
        />
        <button
          className={`btn ${input.trim() && !busy ? "btn-primary" : "btn-disabled"}`}
          onClick={handleCheck}
          disabled={!input.trim() || busy}
        >
          {busy ? "확인 중…" : "확인"}
        </button>
      </div>
      {tried && (
        <p className="escape-wrong">❌ 다시 조사해 보세요</p>
      )}
    </div>
  );
}

/* ---------- 핀 카드 모달 ---------- */
function PinCard({ pin, existing, onSubmit, onClose, escapeVariant, escaped, onEscape }) {
  const t = window.typeById(pin.typeId);
  const [q1, setQ1] = useState(existing ? existing.q1 : null);
  const [q2, setQ2] = useState(existing ? existing.q2 : null);
  const [puzzleSolved, setPuzzleSolved] = useState(existing ? !!existing.puzzleSolved : false);
  const [submitted, setSubmitted] = useState(!!existing);
  const bodyRef = useRef(null);

  const canSubmit = q1 != null && q2Valid(pin, q2);
  const correct = q1 === pin.typeId;

  const submit = () => {
    if (!canSubmit) return;
    setSubmitted(true);
    onSubmit({ q1, q2, puzzleSolved });
  };

  return (
    <div className="sheet-overlay" onClick={onClose}>
      <div className={`sheet ${t.cls}`} onClick={(e) => e.stopPropagation()} ref={bodyRef}>
        <div className="sheet-grip" />
        <button className="sheet-x" onClick={onClose} aria-label="닫기">✕</button>

        <div className="sheet-scroll scroll-dark">
          <PhotoPlaceholder pin={pin} />
          <div className="sheet-src"><Source>{pin.source}</Source></div>

          <div className="sheet-pad">
            {/* 제목 */}
            <div className="sheet-title">
              <span className="region-tag">{pin.region}</span>
              <h2>{pin.name}</h2>
              <p className="tagline">{pin.tagline}</p>
            </div>

            {/* 배경 */}
            <p className="bg-text">{pin.background}</p>

            {/* 낱말 퍼즐 — 이곳의 핵심 낱말 맞추기 */}
            {pin.puzzle ? (
              <WordPuzzle puzzle={pin.puzzle} tone={t.cls} solved={puzzleSolved}
                onSolve={() => setPuzzleSolved(true)} />
            ) : null}

            {/* Q1 */}
            <div className="qblock">
              <div className="q-head"><span className="q-no">Q1</span> 이곳의 변신은 어떤 유형일까요?</div>
              <div className="type-choices">
                {window.TYPES.map((tt) => {
                  const on = q1 === tt.id;
                  const showRight = submitted && tt.id === pin.typeId;
                  const showWrong = submitted && on && tt.id !== pin.typeId;
                  return (
                    <button key={tt.id}
                      className={`type-choice ${tt.cls} ${on ? "on" : ""} ${showRight ? "right" : ""} ${showWrong ? "wrong" : ""}`}
                      onClick={() => !submitted && setQ1(tt.id)} disabled={submitted}>
                      <span className="tc-no">{tt.id}</span>
                      <span className="tc-label">{tt.label}</span>
                      {showRight ? <span className="tc-mark">정답</span> : null}
                      {showWrong ? <span className="tc-mark wrongmark">내 선택</span> : null}
                    </button>
                  );
                })}
              </div>
            </div>

            {/* Q2 */}
            <div className="qblock">
              <div className="q-head"><span className="q-no">Q2</span> {pin.q2.prompt}</div>
              <Q2Field pin={pin} value={q2} onChange={setQ2} locked={submitted} />
            </div>

            {/* 제출 / 해설 */}
            {!submitted ? (
              <button className={`btn btn-block btn-lg ${canSubmit ? "btn-accent" : "btn-disabled"}`}
                onClick={submit} disabled={!canSubmit}>제출하기</button>
            ) : (
              <div className="explain-block fade-up">
                <div className={`verdict ${correct ? "ok" : "no"}`}>
                  <span className="v-icon">{correct ? "✓" : "↻"}</span>
                  <div>
                    <b>{correct ? "맞았어요!" : "다시 살펴봐요"}</b>
                    <span> 이곳은 <TypeBadge typeId={pin.typeId} /> 사례예요.</span>
                  </div>
                </div>
                <Toggle icon="💡" title="정답 · 유형 해설" defaultOpen={true} accent={true}>
                  <p style={{ marginBottom: 10 }}>{pin.q1Explain}</p>
                  <p style={{ paddingTop: 10, borderTop: "1px dashed var(--line)" }}>
                    <b style={{ color: "var(--c-ink)" }}>Q2 ·</b> {pin.q2.explain}
                  </p>
                  {pin.q2ExtraImage ? (
                    <figure className="explain-photo">
                      <img src={pin.q2ExtraImage.src} alt={pin.q2ExtraImage.caption} loading="lazy" />
                      <figcaption>{pin.q2ExtraImage.caption}</figcaption>
                    </figure>
                  ) : null}
                </Toggle>
              </div>
            )}

            {/* 탈출 미션 — Q1·Q2 제출 완료 후에만 표시 */}
            {submitted && (
              <EscapeMission
                pin={pin}
                variantKey={escapeVariant || "A"}
                escaped={escaped}
                onEscape={(answer) => onEscape && onEscape(answer)}
              />
            )}

            {/* 교과 연결 */}
            <Toggle icon="📚" title="교과 연결" defaultOpen={false}>
              <span className="subj-code">{pin.subject.code}</span>
              <p style={{ marginTop: 6 }}>{pin.subject.text}</p>
            </Toggle>

            <button className="btn btn-ghost btn-block" style={{ marginTop: 4 }} onClick={onClose}>
              {submitted ? "닫고 지도로 돌아가기" : "닫기"}
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { PinCard, PhotoPlaceholder, WordPuzzle });
