// App shell — WCA junior 牙科領袖營 · 戰情控制台
(() => {
const { Badge, Button, Input } = window.WCATalentGameDesignSystem_377d00;
const { Modal, FormRow, ModalActions } = window.WCA_UI;
const { userRoleLabel, rank } = window.WCA_UTIL;

const NAV = [
  { id: "dashboard", label: "戰情總覽", glyph: "◆" },
  { id: "roster", label: "名單", glyph: "⚑" },
  { id: "flow", label: "活動流程", glyph: "☷" },
  { id: "merch", label: "文宣清單", glyph: "✦" },
  { id: "contacts", label: "聯絡窗口", glyph: "☎" },
];
const ADMIN_NAV = { id: "admin", label: "帳號管理", glyph: "⛨" };
const TITLES = {
  dashboard: ["戰情總覽", "Talent Game · Hackathon · Lecture 作戰儀表板"],
  roster: ["名單管理", "工作人員 · 導師 · 講師 · 學員 · 來賓 · 房間分配"],
  flow: ["活動流程", "簡易流程 · 詳細流程 · 器材道具"],
  merch: ["文宣清單", "輸出品製作與攜帶查核"],
  contacts: ["聯絡窗口", "場地 · 接駁 · 住宿 · 醫護"],
  admin: ["帳號管理", "Admin · Leader · Member 權限"],
};

function PasswordModal({ onClose }) {
  const [cur, setCur] = React.useState("");
  const [nxt, setNxt] = React.useState("");
  const save = async () => {
    await api("PUT", "/api/me/password", { current: cur, next: nxt });
    alert("密碼已更新");
    onClose();
  };
  return (
    <Modal title="修改密碼" onClose={onClose} width={400}>
      <FormRow cols="1fr"><Input label="目前密碼" type="password" value={cur} onChange={(e) => setCur(e.target.value)} /></FormRow>
      <FormRow cols="1fr"><Input label="新密碼（至少 6 碼）" type="password" value={nxt} onChange={(e) => setNxt(e.target.value)} /></FormRow>
      <ModalActions onSave={save} onCancel={onClose} />
    </Modal>
  );
}

function Sidebar({ view, setView, me }) {
  const [pwOpen, setPwOpen] = React.useState(false);
  const nav = me.role === "admin" ? [...NAV, ADMIN_NAV] : NAV;
  return (
    <aside style={{ width: 232, flexShrink: 0, background: "var(--navy-900)", borderRight: "1px solid var(--border-default)", display: "flex", flexDirection: "column", padding: "22px 16px", minHeight: "100vh", position: "sticky", top: 0, alignSelf: "flex-start", height: "100vh", overflowY: "auto" }}>
      <div style={{ textAlign: "center", paddingBottom: 16, borderBottom: "1px solid var(--divider)", marginBottom: 16 }}>
        <img src="/assets/brand/wca-logo.png" alt="WCA · White Coat Accelerator" style={{ width: 176, height: "auto", display: "block", margin: "0 auto", borderRadius: "var(--radius-md)", boxShadow: "0 0 22px rgba(212,175,55,.18)" }} />
        <div style={{ fontSize: 11, color: "var(--text-muted)", marginTop: 10, letterSpacing: ".14em" }}>牙 科 領 袖 營</div>
      </div>
      <nav style={{ display: "flex", flexDirection: "column", gap: 4 }}>
        {nav.map((n) => {
          const active = n.id === view;
          return (
            <button key={n.id} onClick={() => setView(n.id)} style={{
              display: "flex", alignItems: "center", gap: 12, padding: "11px 14px", cursor: "pointer",
              fontFamily: "var(--font-serif)", fontSize: 15, letterSpacing: ".06em", textAlign: "left",
              color: active ? "var(--navy-950)" : "var(--text-secondary)",
              background: active ? "var(--grad-gold)" : "transparent",
              border: active ? "1px solid var(--gold-300)" : "1px solid transparent",
              borderRadius: "var(--radius-sm)", boxShadow: active ? "var(--glow-gold-sm)" : "none",
              fontWeight: active ? 700 : 500, transition: "all var(--dur-med)",
            }}>
              <span style={{ width: 18, textAlign: "center", opacity: active ? 1 : .7 }}>{n.glyph}</span>
              {n.label}
            </button>
          );
        })}
      </nav>
      <div style={{ marginTop: "auto", paddingTop: 16, borderTop: "1px solid var(--divider)" }}>
        <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 12 }}>
          <span style={{ width: 38, height: 38, borderRadius: "50%", background: "var(--grad-gold)", color: "var(--navy-950)", display: "flex", alignItems: "center", justifyContent: "center", fontFamily: "var(--font-serif)", fontWeight: 900, fontSize: 16, border: "2px solid var(--gold-500)" }}>
            {(me.display_name || me.username)[0]}
          </span>
          <div style={{ lineHeight: 1.3, minWidth: 0 }}>
            <div style={{ fontSize: 13, color: "var(--text-primary)", fontFamily: "var(--font-serif)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{me.display_name || me.username}</div>
            <div style={{ fontSize: 10.5, color: "var(--text-muted)" }}>{userRoleLabel[me.role]}</div>
          </div>
        </div>
        <div style={{ display: "flex", gap: 8 }}>
          <Button variant="ghost" size="sm" style={{ flex: 1 }} onClick={() => setPwOpen(true)}>密碼</Button>
          <Button variant="ghost" size="sm" style={{ flex: 1 }} onClick={async () => { await api("POST", "/api/logout"); location.href = "/login.html"; }}>登出</Button>
        </div>
      </div>
      {pwOpen && <PasswordModal onClose={() => setPwOpen(false)} />}
    </aside>
  );
}

function countdown(meta) {
  if (!meta.event_start) return "";
  const start = new Date(meta.event_start + "T00:00:00+08:00");
  const days = Math.ceil((start - Date.now()) / 86400000);
  if (days > 0) return "倒數 T-" + days;
  if (days > -3) return "作戰進行中";
  return "已結營";
}

function Topbar({ view, meta }) {
  const [t, sub] = TITLES[view];
  return (
    <header style={{ display: "flex", alignItems: "center", gap: 16, padding: "18px 28px", borderBottom: "1px solid var(--border-default)", background: "linear-gradient(180deg,var(--navy-850),transparent)" }}>
      <div>
        <h1 style={{ margin: 0, fontFamily: "var(--font-serif)", fontWeight: 900, fontSize: 26, letterSpacing: ".08em", background: "var(--grad-gold-text)", WebkitBackgroundClip: "text", backgroundClip: "text", color: "transparent" }}>{t}</h1>
        <div style={{ fontSize: 12.5, color: "var(--text-muted)", marginTop: 2 }}>{sub}</div>
      </div>
      <div style={{ marginLeft: "auto", display: "flex", alignItems: "center", gap: 20 }}>
        <div style={{ textAlign: "right" }}>
          <div style={{ fontSize: 13, color: "var(--text-gold)", fontFamily: "var(--font-serif)" }}>{meta.event_date}</div>
          <div style={{ fontSize: 11.5, color: "var(--text-muted)" }}>{meta.event_venue}</div>
        </div>
        <Badge tone="ember" dot>{countdown(meta)}</Badge>
      </div>
    </header>
  );
}

function App() {
  const [me, setMe] = React.useState(null);
  const [data, setData] = React.useState(null);
  const initial = location.hash.slice(1);
  const [view, setViewRaw] = React.useState(TITLES[initial] ? initial : "dashboard");
  const setView = (v) => { location.hash = v; setViewRaw(v); };

  const refresh = React.useCallback(async () => {
    setData(await api("GET", "/api/data"));
  }, []);

  React.useEffect(() => {
    (async () => {
      try {
        const res = await fetch("/api/me");
        if (res.status === 401) { location.href = "/login.html"; return; }
        setMe(await res.json());
        await refresh();
      } catch (e) { console.error(e); }
    })();
  }, [refresh]);

  if (!me || !data) {
    return (
      <div style={{ minHeight: "100vh", display: "flex", alignItems: "center", justifyContent: "center", background: "var(--grad-night)" }}>
        <div style={{ fontFamily: "var(--font-serif)", color: "var(--text-gold)", fontSize: 18, letterSpacing: ".2em" }}>召 喚 中 …</div>
      </div>
    );
  }

  const canEdit = rank[me.role] >= rank.leader;
  const Views = { dashboard: window.Dashboard, roster: window.Roster, flow: window.FlowSchedule, merch: window.MerchChecklist, contacts: window.Contacts, admin: window.AdminUsers };
  const Current = Views[view] || window.Dashboard;
  return (
    <div style={{ display: "flex", minHeight: "100vh", background: "var(--grad-night)" }}>
      <Sidebar view={view} setView={setView} me={me} />
      <div style={{ flex: 1, minWidth: 0, display: "flex", flexDirection: "column" }}>
        <Topbar view={view} meta={data.meta} />
        <main style={{ flex: 1, padding: "26px 28px 40px", overflow: "auto" }}>
          <Current data={data} refresh={refresh} me={me} canEdit={canEdit} />
        </main>
      </div>
    </div>
  );
}
window.App = App;
})();
