/* ============================================================
   teacher.jsx — 교사 화면 T1~T3
   ============================================================ */

/* QR 코드 — qrcode-generator(로컬 번들)로 data URL 생성 후 img 렌더 */
function QRCanvas({ text, size }) {
  const px = size || 120;
  let dataUrl = "";
  try {
    const qr = window.qrcode(0, "M"); // type 0 = 자동 크기, M = 오류복원 중간
    qr.addData(String(text));
    qr.make();
    dataUrl = qr.createDataURL(5, 8); // cellSize 5px, margin 8px
  } catch (e) {}
  return dataUrl
    ? <img src={dataUrl} width={px} height={px} alt="입장 QR"
        style={{ borderRadius: 8, imageRendering: "pixelated", display: "block" }} />
    : <div style={{ width: px, height: px, background: "var(--paper-2)", borderRadius: 8 }} />;
}

/* 모둠별 PIN + QR 카드 */
function GroupPinCard({ group, pin, baseUrl }) {
  const url = `${baseUrl}?pin=${pin}`;
  return (
    <div className="pin-card">
      <div className="pin-card-top">
        <span className="pin-dot" style={{ background: group.color }}>{group.number}</span>
        <span className="pin-card-label">{group.label}</span>
      </div>
      <QRCanvas text={url} size={110} />
      <div className="pin-number">{pin}</div>
    </div>
  );
}

/* 스테이션 고정 순서 (P1~P5) + 대시보드용 짧은 이름
   JSON stationId 기준: P1=구로, P2=문래, P3=가리봉, P4=항동, P5=경성방직 */
const STATION_ORDER = [
  { id: "guro", no: 1, short: "구로공단" },
  { id: "munrae", no: 2, short: "문래동" },
  { id: "garibong", no: 3, short: "가리봉동" },
  { id: "hangdong", no: 4, short: "항동철길" },
  { id: "kyungbang", no: 5, short: "경성방직" },
];

/* ===================== 교사 내 학급 목록 ===================== */
function TList({ ctx }) {
  const [busy, setBusy] = useState(true);
  const [err, setErr] = useState("");

  useEffect(() => {
    let alive = true;
    (async () => {
      try { await ctx.loadMySessions(); }
      catch (e) { if (alive) setErr("목록을 불러오지 못했어요. 다시 로그인해 주세요."); }
      finally { if (alive) setBusy(false); }
    })();
    return () => { alive = false; };
  }, []);

  const list = ctx.mySessionsList || [];
  const fmtDate = (ts) => {
    try {
      const d = new Date(ts);
      return `${d.getMonth() + 1}/${d.getDate()} ${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
    } catch (e) { return ""; }
  };
  const statusLabel = { active: "진행 중", presenting: "발표 중", closed: "마감" };

  return (
    <div className="t-shell">
      <div className="tlist-wrap">
        <header className="tlist-head">
          <div>
            <div className="tc-kicker">교사 · 내 학급</div>
            <h1 className="tlist-title">내가 만든 학급</h1>
          </div>
          <button className="btn btn-primary" onClick={() => ctx.go("T1")}>+ 새 학급 만들기</button>
        </header>

        {busy ? (
          <p className="tlist-empty">불러오는 중…</p>
        ) : err ? (
          <p className="inline-err">⚠ {err}</p>
        ) : list.length === 0 ? (
          <div className="tlist-empty fade-up">
            <p>아직 만든 학급이 없어요.</p>
            <button className="btn btn-primary" style={{ marginTop: 12 }} onClick={() => ctx.go("T1")}>첫 학급 만들기 →</button>
          </div>
        ) : (
          <div className="tlist-grid fade-up">
            {list.map((s) => (
              <button key={s.code} className="tlist-card" onClick={() => ctx.openClass(s.code)}>
                <div className="tlist-card-top">
                  <span className="tlist-card-name">{s.className}</span>
                  <span className={`tlist-badge ${s.status}`}>{statusLabel[s.status] || s.status}</span>
                </div>
                <div className="tlist-card-code">{s.code}</div>
                <div className="tlist-card-meta">{s.groupCount}모둠 · 필수 {s.requiredCount}곳 · {fmtDate(s.createdAt)}</div>
              </button>
            ))}
          </div>
        )}

        <div className="tlist-foot">
          {ctx.auth.profile ? <span className="tlist-who">👤 {ctx.auth.profile.name || ctx.auth.profile.email}</span> : null}
          <button className="link" onClick={() => ctx.go("home")}>← 처음으로</button>
        </div>
      </div>
    </div>
  );
}

/* ===================== T0 도입 (대비 발문) ===================== */
function TIntro({ ctx }) {
  const I = window.INTRO;
  return (
    <div className="t-shell t-intro">
      <div className="intro-inner">
        <div className="intro-kicker">통합사회 · 마을 탐구 미션 · 도입</div>
        <h1 className="intro-q">{I.question}</h1>
        <p className="intro-sub">{I.sub}</p>
        <div className="intro-compare">
          <figure className={`intro-photo ${I.left.tone}`}>
            <img src={I.left.src} alt={I.left.label} loading="lazy" />
            <figcaption><span className="ic-dot" />{I.left.label}</figcaption>
          </figure>
          <div className="intro-vs">VS</div>
          <figure className={`intro-photo ${I.right.tone}`}>
            <img src={I.right.src} alt={I.right.label} loading="lazy" />
            <figcaption><span className="ic-dot" />{I.right.label}</figcaption>
          </figure>
        </div>
        <p className="intro-note">두 사진은 모두 <b>문래동 한 동네</b>의 모습입니다. 같은 곳이 왜 이렇게 다를까요?</p>

        {/* 학습 목표 — 교사가 수업 시작 시 함께 제시 */}
        <div className="intro-goals">
          <div className="intro-goals-title">🎯 오늘의 학습 목표</div>
          <ul>
            <li>도시 공간이 <b>어떻게, 왜</b> 변하는지 설명할 수 있다</li>
            <li>변화 속에서 <b>누가 이득을 얻고 누가 밀려나는지</b> 생각해본다</li>
            <li>개발과 보존 사이에서 <b>근거를 들어</b> 내 입장을 말할 수 있다</li>
          </ul>
        </div>

        <div className="intro-actions">
          <button className="btn btn-primary btn-lg" onClick={() => ctx.go(ctx.session ? "T2" : "T1")}>수업 시작하기 →</button>
        </div>
      </div>
    </div>
  );
}

/* ===================== T1 세션 생성 ===================== */
function T1Create({ ctx }) {
  const [className, setClassName] = useState(ctx.session ? ctx.session.className : "");
  const [n, setN] = useState(ctx.session ? ctx.session.groupCount : 6);
  const [required, setRequired] = useState(ctx.session ? (ctx.session.requiredCount || 5) : 5);
  const [phase, setPhase] = useState(ctx.session ? "done" : "form"); // form | loading | done
  const [error, setError] = useState("");

  const create = async () => {
    setPhase("loading"); setError("");
    try {
      await ctx.createSession(className.trim() || "우리 반", n, required);
      setPhase("done");
    } catch (e) {
      setError("세션을 만들지 못했어요. 서버 연결을 확인해 주세요.");
      setPhase("form");
    }
  };

  return (
    <div className="t-shell">
      <div className="t-create">
        <div className="tc-kicker">교사 · 세션 만들기</div>
        <h1 className="tc-title">우리 마을, 얼마나 알고 있나요?</h1>
        <p className="tc-desc">수업 세션을 만들면 학생들이 입장할 코드가 발급돼요.</p>

        {phase !== "done" ? (
          <div className="tc-form fade-up">
            <label className="field-label">수업명 / 학급</label>
            <input className="t-input" value={className} placeholder="예: 1학년 4반 통합사회"
              onChange={(e) => setClassName(e.target.value)} disabled={phase === "loading"} />

            <label className="field-label" style={{ marginTop: 22 }}>모둠 수</label>
            <div className="stepper">
              <button onClick={() => setN(Math.max(2, n - 1))} disabled={phase === "loading"}>−</button>
              <div className="stepper-val"><b>{n}</b><span>모둠</span></div>
              <button onClick={() => setN(Math.min(10, n + 1))} disabled={phase === "loading"}>+</button>
            </div>
            <p className="tc-note">2~10모둠 · 색과 라벨은 자동으로 나뉘어요</p>

            <label className="field-label" style={{ marginTop: 22 }}>필수 미션 수 <span style={{ fontWeight: 600, color: "var(--slate-2)" }}>(의견 작성을 여는 조건)</span></label>
            <div className="stepper">
              <button onClick={() => setRequired(Math.max(3, required - 1))} disabled={phase === "loading"}>−</button>
              <div className="stepper-val"><b>{required}</b><span>곳</span></div>
              <button onClick={() => setRequired(Math.min(5, required + 1))} disabled={phase === "loading"}>+</button>
            </div>
            <p className="tc-note">5곳 중 {required}곳을 완료하면 의견 작성 가능 · 40분 1차시면 3곳 권장</p>

            {error ? <p className="inline-err">⚠ {error}</p> : null}
            <button className="btn btn-primary btn-block btn-lg" style={{ marginTop: 26 }} onClick={create}
              disabled={phase === "loading"}>
              {phase === "loading" ? "세션 만드는 중…" : "세션 만들기"}
            </button>
          </div>
        ) : (
          <div className="tc-done fade-up">
            <div className="code-card">
              <div className="code-card-label">세션 코드</div>
              <div className="code-big">{ctx.session.code}</div>
              <div className="code-card-sub">{ctx.session.className} · {ctx.session.groupCount}모둠 · 필수 {ctx.session.requiredCount || 5}곳</div>
            </div>

            {/* 모둠별 PIN + QR */}
            <div className="pin-section">
              <div className="pin-section-head">
                <span>모둠별 PIN · QR 코드</span>
                <button className="btn btn-ghost btn-sm" onClick={() => window.print()}>🖨 인쇄</button>
              </div>
              <div className="pin-grid">
                {window.makeGroups(ctx.session.groupCount).map((g) => {
                  const pin = (ctx.session.groupPins || {})[g.id] || "----";
                  const baseUrl = window.location.origin;
                  return <GroupPinCard key={g.id} group={g} pin={pin} baseUrl={baseUrl} />;
                })}
              </div>
              <p className="pin-hint">학생들에게 모둠별 QR 또는 PIN 4자리를 전달하세요.</p>
              <p className="pin-hint" style={{ marginTop: 8 }}>
                탈출 미션 배정: 1·2모둠→A형, 3·4모둠→B형, 5·6모둠→C형
              </p>
            </div>

            <div className="tc-actions">
              <button className="btn btn-ghost" onClick={() => setPhase("form")}>다시 설정</button>
              <button className="btn btn-primary" onClick={() => ctx.go("T2")}>대시보드로 →</button>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

/* ===================== T2 대시보드 ===================== */
function T2Dashboard({ ctx }) {
  const required = ctx.requiredCount || 5;
  const totalDone = ctx.groups.filter((g) => ctx.getGroupDone(g.id) >= required).length;
  const opinions = ctx.groups.filter((g) => ctx.getOpinion(g.id)).length;

  return (
    <div className="t-shell t-dash">
      <header className="t-bar">
        <div className="t-bar-left">
          <div className="t-bar-kicker">교사 대시보드 · 진행 모니터</div>
          <div className="t-bar-title">{ctx.session.className}</div>
        </div>
        <div className="t-bar-code">
          <span>학생 입장 코드</span>
          <b>{ctx.session.code}</b>
        </div>
      </header>

      <div className="dash-stats">
        <div className="dstat"><b>{ctx.groups.length}</b><span>전체 모둠</span></div>
        <div className="dstat"><b>{totalDone}</b><span>필수 완료 ({required}/5)</span></div>
        <div className="dstat"><b>{opinions}</b><span>의견 제출</span></div>
      </div>

      <div className="dash-grid">
        {ctx.groups.map((g) => {
          const done = ctx.getGroupDone(g.id);
          const op = ctx.getOpinion(g.id);
          const mine = g.id === ctx.myGroupId;
          return (
            <div key={g.id} className={`gcard ${done >= required ? "complete" : ""}`}>
              <div className="gcard-top">
                <span className="gcard-dot" style={{ background: g.color }}>{g.number}</span>
                <span className="gcard-name">
                  {g.label}{mine ? " (내 화면)" : ""}
                  <span className="escape-variant-badge">
                    {((ctx.session.groupVariants || {})[g.id] || "A")}형
                  </span>
                </span>
                {op ? <span className="gcard-badge done">의견 제출 ✓</span>
                    : done >= required ? <span className="gcard-badge ready">의견 작성중</span>
                    : <span className="gcard-badge wait">탐험중</span>}
              </div>
              <div className="gcard-members">
                {ctx.getParticipants(g.id).map((n) => (
                  <span key={n} className="gcard-member">👤 {n}</span>
                ))}
                {ctx.getParticipants(g.id).length === 0 && (
                  <span className="gcard-member empty">대기 중</span>
                )}
              </div>
              <Gauge done={done} total={5} />
              {/* 5곳 미션 완료 현황 — P1~P5 고정 순서, 탈출한 곳은 🔓 강조 */}
              <div className="gcard-stations">
                {STATION_ORDER.map((st) => {
                  const escaped = ctx.getEscapeStatus(g.id, st.id);
                  return (
                    <span key={st.id} className={`station-chip ${escaped ? "done" : ""}`}>
                      <span className="sc-no">{escaped ? "🔓" : st.no}</span>
                      <span className="sc-name">{st.short}</span>
                    </span>
                  );
                })}
              </div>
            </div>
          );
        })}
      </div>

      <div className="t-footer">
        <p className="t-foot-note">학생들이 5곳을 모두 탐험하고 의견을 제출하면 발표를 시작하세요.</p>
        <button className="btn btn-accent t5 btn-lg" onClick={() => { ctx.setStatus("presenting"); ctx.go("T3"); }}>
          발표 모드 전환 →
        </button>
      </div>
    </div>
  );
}

/* ===================== T3 발표 · 전체보기 ===================== */
function T3Present({ ctx }) {
  const [sel, setSel] = useState(window.PINS[0].id);
  const pin = window.PINS.find((p) => p.id === sel);

  // 투표 핀 집계 (모둠별 색)
  const votePins = {};
  ctx.groups.forEach((g) => {
    const op = ctx.getOpinion(g.id);
    if (op) (votePins[op.votePinId] = votePins[op.votePinId] || []).push(g);
  });

  // 선택 핀 Q1 유형 분포
  const dist = {};
  window.TYPES.forEach((t) => (dist[t.id] = 0));
  let answered = 0;
  ctx.groups.forEach((g) => {
    const r = ctx.getResponse(g.id, sel);
    if (r && r.q1) { dist[r.q1]++; answered++; }
  });

  // 선택 핀 Q2 응답 모음
  const q2list = ctx.groups.map((g) => ({ g, r: ctx.getResponse(g.id, sel) })).filter((x) => x.r);

  return (
    <div className="t-shell t-present">
      <header className="t-bar present-bar">
        <div className="t-bar-left">
          <div className="t-bar-kicker">발표 · 전체보기 (프로젝션)</div>
          <div className="t-bar-title">{ctx.session.className} — 우리 마을 변신 지도</div>
        </div>
        <div className="present-actions">
          <button className="btn btn-ghost" onClick={() => ctx.go("T2")}>← 대시보드</button>
          <button className="btn btn-primary" onClick={() => { if (confirm("세션을 마감할까요?")) { ctx.setStatus("closed"); ctx.go("home"); } }}>세션 마감</button>
        </div>
      </header>

      <div className="present-main">
        {/* 좌: 전체 지도 + 투표 핀 */}
        <div className="present-map-col">
          <div className="present-map map-wrap">
            <BaseMap />
            {window.PINS.map((p) => (
              <button key={p.id} className={`present-pin ${sel === p.id ? "on" : ""}`}
                style={{ left: `${p.x}%`, top: `${p.y}%` }} onClick={() => setSel(p.id)}>
                <span className="pp-head" style={{ background: `var(--${window.typeById(p.typeId).cls})` }}>
                  <span>{window.typeById(p.typeId).id}</span>
                </span>
                <span className="pp-label">{p.name}</span>
                {/* 이 핀에 모인 투표 (모둠색 점) */}
                {(votePins[p.id] || []).length ? (
                  <span className="pp-votes">
                    {(votePins[p.id] || []).map((g) => <i key={g.id} style={{ background: g.color }} />)}
                  </span>
                ) : null}
              </button>
            ))}
            <SchoolMarker />
            <span className="map-mock-tag">투표 핀: 모둠이 가장 지키고 싶은 곳 (모둠 색)</span>
          </div>
          <div className="vote-legend">
            <span className="vl-title">🛡 가장 지키고 싶은 곳 투표</span>
            <div className="vl-rows">
              {window.PINS.map((p) => {
                const c = (votePins[p.id] || []).length;
                return c ? (
                  <div key={p.id} className="vl-row">
                    <span className="vl-name">{p.name}</span>
                    <span className="vl-bar"><i style={{ width: `${c / ctx.groups.length * 100}%`, background: `var(--${window.typeById(p.typeId).cls})` }} /></span>
                    <b>{c}</b>
                  </div>
                ) : null;
              })}
            </div>
          </div>
        </div>

        {/* 우: 선택 핀 분석 */}
        <div className="present-detail scroll-dark">
          <div className="pd-head">
            <span className="region-tag" style={{ color: `var(--${window.typeById(pin.typeId).cls})` }}>{pin.region}</span>
            <h2>{pin.name}</h2>
            <TypeBadge typeId={pin.typeId} size="lg" />
          </div>

          <div className="pd-section">
            <div className="pd-q">Q1 · 변동유형 분포 <span>({answered}/{ctx.groups.length} 모둠 응답)</span></div>
            <div className="dist-chart">
              {window.TYPES.map((t) => {
                const c = dist[t.id];
                const pct = answered ? Math.round(c / answered * 100) : 0;
                const isAns = t.id === pin.typeId;
                return (
                  <div key={t.id} className={`dist-row ${t.cls}`}>
                    <span className="dist-label"><span className="dist-no">{t.id}</span>{t.label}{isAns ? " ✓" : ""}</span>
                    <span className="dist-bar"><i style={{ width: `${pct}%`, background: "var(--c)" }} /></span>
                    <b className="dist-n">{c}</b>
                  </div>
                );
              })}
            </div>
            <p className="pd-correct">정답: <TypeBadge typeId={pin.typeId} /></p>
          </div>

          <div className="pd-section">
            <div className="pd-q">Q2 · 모둠별 응답 모아보기</div>
            <div className="q2-collect">
              {q2list.length ? q2list.map(({ g, r }) => (
                <div key={g.id} className="q2-item">
                  <span className="q2-g" style={{ background: g.color }}>{g.number}</span>
                  <span className="q2-ans">{renderQ2Answer(pin, r.q2)}</span>
                </div>
              )) : <p className="empty-note">아직 응답이 없어요.</p>}
            </div>
          </div>
        </div>
      </div>

      {/* 하단: 모둠 의견 카드 갤러리 */}
      <div className="opinion-gallery">
        <div className="og-title">💬 모둠 의견 — 가장 바람직한 변신 + 근거</div>
        <div className="og-scroll scroll-dark">
          {ctx.groups.map((g) => {
            const op = ctx.getOpinion(g.id);
            if (!op) return (
              <div key={g.id} className="og-card empty">
                <span className="og-g" style={{ background: g.color }}>{g.number}</span>
                <span className="og-pending">작성 대기중…</span>
              </div>
            );
            const bp = window.PINS.find((p) => p.id === op.bestPinId);
            return (
              <div key={g.id} className="og-card">
                <div className="og-card-top">
                  <span className="og-g" style={{ background: g.color }}>{g.number}</span>
                  <TypeBadge typeId={bp.typeId} />
                </div>
                <div className="og-best">{bp.name}</div>
                <p className="og-reason">“{op.reason}”</p>
                <p className="og-common"><b>공통점</b> {op.commonality}</p>
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
}

/* Q2 응답을 사람이 읽을 문장으로 */
function renderQ2Answer(pin, v) {
  if (!v) return "—";
  switch (pin.q2.type) {
    case "multi": { const arr = Array.isArray(v) ? v : []; return arr.map((i) => pin.q2.options[i]).join(", ") || "—"; }
    case "blank2": return `1970s: ${v.a || "—"} / 2020s: ${v.b || "—"}`;
    case "toggle": {
      const o = pin.q2.options.find((x) => x.key === v.choice);
      return `${o ? o.title : "—"} — ${v.reason || ""}`;
    }
    case "slider": return `${pin.q2.labels[v.val]} — ${v.reason || ""}`;
    case "short": return v.text || "—";
    default: return "—";
  }
}

Object.assign(window, { TList, TIntro, T1Create, T2Dashboard, T3Present, renderQ2Answer });
