/* ============================================================
   student.jsx — 학생 화면 S1~S5 (16:9 레이아웃)
   S1: 좌=다크 브랜드 패널, 우=PIN/이름 폼
   S2: 헤더 + 좌=지도, 우=미션 사이드바
   ============================================================ */

/* ===================== S1 입장 (16:9 분할) ===================== */
function S1Enter({ ctx }) {
  const urlPin = (() => {
    try { return new URLSearchParams(window.location.search).get("pin") || ""; } catch (e) { return ""; }
  })();

  const [phase, setPhase] = useState(urlPin ? "verifying" : "pin");
  const [pin, setPin] = useState(urlPin);
  const [pinInfo, setPinInfo] = useState(null);
  const [name, setName] = useState("");
  const [error, setError] = useState("");
  const [busy, setBusy] = useState(false);

  useEffect(() => {
    if (urlPin) verifyPin(urlPin);
  }, []);

  const verifyPin = async (p) => {
    const trimmed = (p || pin).trim();
    if (trimmed.length !== 4) { setError("4자리 PIN을 입력해 주세요."); setPhase("pin"); return; }
    setBusy(true); setError("");
    try {
      const info = await window.API.verifyPin(trimmed);
      setPinInfo(info);
      setPhase(info.participants.length >= 2 ? "full" : "name");
    } catch (e) {
      if (e.status === 409) setError("마감된 수업이에요. 선생님께 문의해 주세요.");
      else if (e.status === 404) setError("PIN을 확인해 주세요. 해당 모둠을 찾을 수 없어요.");
      else setError("연결에 실패했어요. 잠시 후 다시 시도해 주세요.");
      setPhase("pin");
    } finally { setBusy(false); }
  };

  const joinNamed = async (joinName) => {
    const n = (joinName || name).trim();
    if (!n) { setError("이름을 입력해 주세요."); return; }
    setBusy(true); setError("");
    try {
      await ctx.joinByPin(pin.trim(), n);
    } catch (e) {
      if (e.status === 409) setError("이미 2명이 입장했어요. 이름을 눌러 재입장하세요.");
      else if (e.status === 404) setError("세션이 만료됐어요. PIN을 다시 확인해 주세요.");
      else setError("입장에 실패했어요. 다시 시도해 주세요.");
      setBusy(false);
    }
  };

  const resetPin = () => { setPhase("pin"); setPinInfo(null); setError(""); setName(""); };

  return (
    <div className="split" style={{ flex: 1, minHeight: "100dvh" }}>

      {/* 왼쪽: 다크 브랜드 패널 */}
      <div className="split-left-dark">
        <div className="s1-kicker">통합사회 · 마을 탐구 미션</div>
        <h1 className="s1-title">우리 마을,<br />얼마나<br /><span className="hl">알고 있나요?</span></h1>
        <p className="s1-sub">우리 동네 다섯 곳의 변신 비밀,<br />단서를 모아 잠긴 미션을 풀어 봐요.</p>
        <div className="s1-map-mini">
          <BaseMap />
          {window.PINS.map((p) => <PinMarker key={p.id} pin={p} done={false} onClick={() => {}} />)}
          <SchoolMarker />
        </div>
      </div>

      {/* 오른쪽: 폼 패널 */}
      <div className="split-form">
        <div className="split-form-card">

          {/* PIN 입력 */}
          {phase === "pin" && (
            <div className="fade-up">
              <p style={{ fontSize: 13, fontWeight: 800, color: "var(--slate)", marginBottom: 28 }}>
                선생님께 받은 <b style={{ color: "var(--ink)" }}>모둠 PIN</b>을 입력하면 바로 시작할 수 있어요.
              </p>
              <label className="field-label">🔑 모둠 PIN</label>
              <input
                className="code-input" value={pin} maxLength={4} placeholder="0000" inputMode="numeric"
                onChange={(e) => { setPin(e.target.value.replace(/\D/g, "")); setError(""); }}
                onKeyDown={(e) => e.key === "Enter" && verifyPin()}
              />
              {error ? <p className="inline-err">⚠ {error}</p> : null}
              <p className="code-hint">숫자 4자리를 입력하고 확인을 누르세요.</p>
              <button
                className={`btn btn-block btn-lg ${pin.length === 4 && !busy ? "btn-primary" : "btn-disabled"}`}
                style={{ marginTop: 20 }} onClick={() => verifyPin()} disabled={busy || pin.length !== 4}
              >
                {busy ? "확인 중…" : "확인"}
              </button>
              <button className="link" style={{ display: "block", marginTop: 18, textAlign: "center" }}
                onClick={() => ctx.go("home")}>← 처음으로</button>
            </div>
          )}

          {/* PIN 검증 중 */}
          {phase === "verifying" && (
            <div style={{ textAlign: "center", padding: "48px 0", color: "var(--slate)" }}>PIN 확인 중…</div>
          )}

          {/* 이름 입력 */}
          {(phase === "name" || phase === "full") && pinInfo && (
            <div className="fade-up">
              <div className="verified-row">
                <span className="ok-pill">✓ {pinInfo.className} · {pinInfo.groupId}모둠</span>
              </div>
              <p style={{ fontSize: 14, color: "var(--slate)", marginBottom: 20, lineHeight: 1.6 }}>
                대표참여자는 <b style={{ color: "var(--ink)" }}>최대 2명</b>까지 입장할 수 있어요.<br />
                이미 입장한 팀원의 이름을 누르면 재입장합니다.
              </p>

              <label className="field-label">대표참여자 ({pinInfo.participants.length}/2)</label>

              {pinInfo.participants.length > 0 && (
                <div className="participant-list">
                  {pinInfo.participants.map((n) => (
                    <button key={n} className="participant-btn" onClick={() => joinNamed(n)} disabled={busy}>
                      <span className="participant-icon">👤</span>
                      <span className="participant-name">{n}</span>
                      <span className="rejoin-tag">재입장</span>
                    </button>
                  ))}
                </div>
              )}

              {phase === "name" && (
                <>
                  <input
                    className="t-input" value={name} placeholder="이름 입력 후 임무 수락" maxLength={10}
                    style={{ marginTop: pinInfo.participants.length > 0 ? 12 : 0 }}
                    onChange={(e) => { setName(e.target.value); setError(""); }}
                    onKeyDown={(e) => e.key === "Enter" && joinNamed()}
                  />
                  {error ? <p className="inline-err">⚠ {error}</p> : null}
                  <button
                    className={`btn btn-block btn-lg ${name.trim() && !busy ? "btn-primary" : "btn-disabled"}`}
                    style={{ marginTop: 14 }} onClick={() => joinNamed()} disabled={!name.trim() || busy}
                  >
                    {busy ? "입장 중…" : "임무 수락 →"}
                  </button>
                </>
              )}

              {phase === "full" && (
                <>
                  {error ? <p className="inline-err">⚠ {error}</p> : null}
                  <p className="code-hint" style={{ marginTop: 16 }}>
                    이미 2명이 입장했어요. 내 이름을 눌러 재입장하세요.
                  </p>
                </>
              )}

              <button className="link" style={{ display: "block", marginTop: 16, textAlign: "center" }}
                onClick={resetPin}>← PIN 다시 입력</button>
            </div>
          )}

        </div>
      </div>
    </div>
  );
}

/* ===================== S2 미션 (16:9 — 헤더 + 지도/사이드바) ===================== */
function S2Explore({ ctx }) {
  const [openPin, setOpenPin] = useState(null);
  const group = ctx.groups.find((g) => g.id === ctx.myGroupId);
  const done = ctx.getGroupDone(ctx.myGroupId);
  const required = ctx.requiredCount || 5;
  const allDone = done >= required;

  return (
    <div className="s2-screen">

      {/* 상단 헤더 */}
      <header className="s2-header">
        <div className="s2-header-info">
          <span className="s2-kicker">마을 탐구 미션</span>
          <span className="s2-title">우리 마을 변신 지도</span>
        </div>
        <div className="s2-header-gauge">
          <Gauge done={done} total={5} />
        </div>
        {ctx.myName && (
          <span style={{ fontSize: 13, color: "var(--slate)", fontWeight: 600 }}>👤 {ctx.myName}</span>
        )}
        <GroupChip group={group} big={false} />
      </header>

      {/* 바디: 지도 + 사이드바 */}
      <div className="s2-body">

        {/* 왼쪽: 인터랙티브 지도 */}
        <div className="s2-map-col">
          <BaseMap />
          {window.PINS.map((pin) => (
            <PinMarker key={pin.id} pin={pin}
              done={!!ctx.getResponse(ctx.myGroupId, pin.id)}
              onClick={() => setOpenPin(pin)} />
          ))}
          <SchoolMarker />
          {/* 범례 */}
          <div className="s2-legend">
            <span className="s2-legend-title">변동유형</span>
            {window.TYPES.map((t) => (
              <span key={t.id} className={`s2-leg ${t.cls}`}>
                <i />{t.roman} {t.label}
              </span>
            ))}
          </div>
        </div>

        {/* 오른쪽: 미션 사이드바 */}
        <div className="s2-sidebar">
          <div className="mission-panel">
            <div className="mission-panel-head">
              <span className="mission-panel-title">미션 목록</span>
              <span className="mission-panel-count">
                {done}<span> / 5 완료</span>
              </span>
            </div>

            <div className="mission-list">
              {window.PINS.map((pin) => {
                const t = window.typeById(pin.typeId);
                const isDone = !!ctx.getResponse(ctx.myGroupId, pin.id);
                return (
                  <div
                    key={pin.id}
                    className={`mission-item ${t.cls}${isDone ? " done-item" : ""}`}
                    onClick={() => setOpenPin(pin)}
                  >
                    <div className="mission-icon">{pin.number || pin.id.slice(-1)}</div>
                    <div className="mission-item-content">
                      <div className="mission-item-name">{pin.name}</div>
                      <div className="mission-item-region" style={{ color: `var(--${t.cls.replace("t","t") + "-ink"}, var(--slate))` }}>
                        <TypeBadge typeId={pin.typeId} />
                      </div>
                    </div>
                    <div className={`mission-check ${
                      ctx.getEscapeStatus(ctx.myGroupId, pin.id) ? "done" :
                      ctx.getResponse(ctx.myGroupId, pin.id) ? "partial" :
                      "pending"
                    }`}>
                      {ctx.getEscapeStatus(ctx.myGroupId, pin.id) ? "🔓" :
                       ctx.getResponse(ctx.myGroupId, pin.id) ? "🔒" : "○"}
                    </div>
                  </div>
                );
              })}
            </div>

            <div className="mission-panel-footer">
              {!allDone ? (
                <>
                  <p className="s2-hint"><b>{Math.max(0, required - done)}곳</b> 미션을 더 완료하면 의견을 작성할 수 있어요.</p>
                  <button className="btn btn-block btn-disabled" disabled>
                    🔒 모둠 의견 작성 ({done}/{required})
                  </button>
                </>
              ) : (
                <>
                  <p className="s2-hint s2-hint-done">🎉 필수 미션 완료! 모둠 의견을 작성해 봐요.</p>
                  <button className="btn btn-accent btn-block t2" style={{ fontSize: 16 }}
                    onClick={() => ctx.go("S4")}>
                    모둠 의견 작성 →
                  </button>
                </>
              )}
            </div>
          </div>
        </div>
      </div>

      {/* 핀 카드 모달 */}
      {openPin ? (
        <PinCard
          pin={openPin}
          existing={ctx.getResponse(ctx.myGroupId, openPin.id)}
          escapeVariant={ctx.getVariant(ctx.myGroupId)}
          escaped={ctx.getEscapeStatus(ctx.myGroupId, openPin.id)}
          onSubmit={(val) => { ctx.saveResponse(ctx.myGroupId, openPin.id, val); setOpenPin(null); }}
          onEscape={(answer) =>
            ctx.submitEscape(ctx.myGroupId, openPin.id, answer)
          }
          onClose={() => setOpenPin(null)}
        />
      ) : null}
    </div>
  );
}

/* ===================== S4 모둠 의견 카드 (16:9 확장) ===================== */
function S4Opinion({ ctx }) {
  const group = ctx.groups.find((g) => g.id === ctx.myGroupId);
  const existing = ctx.getOpinion(ctx.myGroupId);
  const [best, setBest] = useState(existing ? existing.bestPinId : null);
  const [reason, setReason] = useState(existing ? existing.reason : "");
  const [common, setCommon] = useState(existing ? existing.commonality : "");
  const [vote, setVote] = useState(existing ? existing.votePinId : null);

  const canSubmit = best && reason.trim() && common.trim() && vote;
  const submit = () => {
    if (!canSubmit) return;
    ctx.saveOpinion(ctx.myGroupId, { bestPinId: best, reason, commonality: common, votePinId: vote });
    ctx.go("S5");
  };

  return (
    <div style={{ flex: 1, display: "flex", flexDirection: "column", overflow: "hidden" }}>
      <header className="s4-top">
        <button className="back-btn" onClick={() => ctx.go("S2")}>← 미션 지도</button>
        <GroupChip group={group} />
        {ctx.myName && <span style={{ fontSize: 13, color: "var(--slate)" }}>👤 {ctx.myName}</span>}
      </header>
      <div className="s4-scroll scroll-dark" style={{ maxWidth: 860, margin: "0 auto", width: "100%", padding: "24px 32px 40px" }}>
        <div className="s4-hero">
          <h2>다섯 미션을 모두 완료했어요!</h2>
          <p>탐험한 곳들을 비교하며 우리 모둠의 생각을 모아 봐요.</p>
        </div>

        <div className="s4-block">
          <div className="s4-q"><span className="s4-no">1</span> 가장 바람직한 변신은 어디였나요?</div>
          <div className="bestpin-list">
            {window.PINS.map((pin) => {
              const t = window.typeById(pin.typeId);
              return (
                <button key={pin.id} className={`bestpin ${t.cls} ${best === pin.id ? "on" : ""}`} onClick={() => setBest(pin.id)}>
                  <span className="bp-dot" />
                  <span className="bp-name">{pin.name}</span>
                  <TypeBadge typeId={pin.typeId} />
                </button>
              );
            })}
          </div>
        </div>

        <div className="s4-block">
          <div className="s4-q"><span className="s4-no">2</span> 그렇게 생각한 근거는?</div>
          <textarea className="ta" rows="3" value={reason} placeholder="자료에서 본 내용을 바탕으로 2~3줄 적어 보세요"
            onChange={(e) => setReason(e.target.value)} />
        </div>

        <div className="s4-block">
          <div className="s4-q"><span className="s4-no">3</span> 다섯 곳의 공통점을 한 줄로</div>
          {/* 비교표 — 공통점 도출을 돕는 참고 자료 */}
          <div className="compare-table">
            <div className="compare-row compare-head">
              <span className="ct-place">장소</span>
              <span className="ct-type">변동유형</span>
              <span className="ct-change">한 줄 변화</span>
            </div>
            {window.PINS.map((pin) => (
              <div key={pin.id} className="compare-row">
                <span className="ct-place">{pin.name}</span>
                <span className="ct-type"><TypeBadge typeId={pin.typeId} /></span>
                <span className="ct-change">{pin.tagline}</span>
              </div>
            ))}
          </div>
          <input className="oneline" value={common} placeholder="예: 낡은 산업 공간이 새로운 쓰임을 찾았다"
            onChange={(e) => setCommon(e.target.value)} />
        </div>

        <div className="s4-block">
          <div className="s4-q"><span className="s4-no">4</span> 우리 모둠이 <b>꼭 남기고 싶은 가치</b>가 가장 잘 드러나는 곳에 투표해요</div>
          <div className="vote-map map-wrap" style={{ height: 260 }}>
            <BaseMap />
            {window.PINS.map((pin) => (
              <button key={pin.id} className="vote-target" style={{ left: `${pin.x}%`, top: `${pin.y}%` }}
                onClick={() => setVote(pin.id)}>
                {vote === pin.id
                  ? <span className="vpin" style={{ background: group.color, width: 24, height: 24, transform: "translate(-50%,-50%) scale(1)" }} />
                  : <span className="vote-ghost">{window.typeById(pin.typeId).id}</span>}
              </button>
            ))}
            <SchoolMarker compact={true} />
            <span className="map-mock-tag">탐험한 핀 중 1곳을 눌러요</span>
          </div>
          {vote ? <p className="vote-pick">📍 선택: <b>{window.PINS.find((p) => p.id === vote).name}</b></p> : null}
        </div>

        <button className={`btn btn-block btn-lg ${canSubmit ? "btn-primary" : "btn-disabled"}`}
          style={{ margin: "4px 0 8px" }} onClick={submit} disabled={!canSubmit}>의견 제출하기</button>
      </div>
    </div>
  );
}

/* ===================== S5 제출 완료 / 대기 ===================== */
function S5Done({ ctx }) {
  const group = ctx.groups.find((g) => g.id === ctx.myGroupId);
  const presenting = ctx.session && ctx.session.status === "presenting";

  return (
    <div className="s5-wrap">
      <div className="s5-card fade-up" style={{ maxWidth: 520 }}>
        <div className="s5-check">✓</div>
        <h2>미션 완료!</h2>
        <GroupChip group={group} big={true} />
        {ctx.myName && <p style={{ fontSize: 14, color: "var(--slate)" }}>👤 {ctx.myName}</p>}
        <p className="s5-msg">우리 모둠의 탐험과 의견이 잘 모였어요.<br />
          {presenting ? "선생님 발표 화면에서 전체 결과를 볼 수 있어요." : "선생님이 발표를 시작하면 전체 결과를 볼 수 있어요."}
        </p>
        {presenting ? (
          <div className="s5-preview fade-up" style={{ width: "100%" }}>
            <div className="s5-preview-head">📊 전체 결과 미리보기</div>
            <ResultMiniMap ctx={ctx} />
          </div>
        ) : (
          <div className="s5-wait">
            <span className="dotpulse" /><span className="dotpulse" /><span className="dotpulse" />
            <span style={{ marginLeft: 8 }}>발표를 기다리는 중…</span>
          </div>
        )}
      </div>
      <button className="link s5-review" onClick={() => ctx.go("S2")}>← 미션 지도 다시 보기 / 답 수정</button>
    </div>
  );
}

/* S5 발표모드용 미니 결과맵 */
function ResultMiniMap({ ctx }) {
  const votes = {};
  ctx.groups.forEach((g) => {
    const op = ctx.getOpinion(g.id);
    if (op) (votes[op.votePinId] = votes[op.votePinId] || []).push(g);
  });
  return (
    <div className="map-wrap" style={{ height: 200, borderRadius: 14 }}>
      <BaseMap />
      {window.PINS.map((pin) => {
        const vs = votes[pin.id] || [];
        return (
          <div key={pin.id} className="vote-target" style={{ left: `${pin.x}%`, top: `${pin.y}%`, pointerEvents: "none" }}>
            {vs.length ? <span className="vcount">{vs.length}</span> :
              <span className="vpin" style={{ background: "var(--line-2)", width: 9, height: 9 }} />}
          </div>
        );
      })}
    </div>
  );
}

Object.assign(window, { S1Enter, S2Explore, S4Opinion, S5Done, ResultMiniMap });
