// Roster — 名單（五類人員 + 房間分配表 + 在營時間 8 格）
(() => {
const { Panel, Tabs, Badge, Avatar, RoleBadge, Button, Input, Select } = window.WCATalentGameDesignSystem_377d00;
const { heroSrc } = window.WCA_UTIL;
const { Modal, FormRow, ModalActions, EditPencil } = window.WCA_UI;
const SLOTS = window.PRESENCE_SLOTS;

const GROUPS = [
  { id: "staff", label: "工作人員" },
  { id: "mentors", label: "導師" },
  { id: "lecturers", label: "講師" },
  { id: "students", label: "學員" },
  { id: "guests", label: "來賓" },
];
const GROUP_LABEL = Object.fromEntries(GROUPS.map((g) => [g.id, g.label]));

// 在營時間 8 格：8/14 早午晚 · 8/15 早午晚 · 8/16 早午
function PresenceGrid({ presence, onToggle, size = 15, readOnly = false }) {
  const bits = (presence || "00000000").split("");
  const days = [{ day: "8/14", idx: [0, 1, 2] }, { day: "8/15", idx: [3, 4, 5] }, { day: "8/16", idx: [6, 7] }];
  return (
    <div style={{ display: "flex", gap: 10 }}>
      {days.map((d) => (
        <div key={d.day} style={{ textAlign: "center" }}>
          <div style={{ fontFamily: "var(--font-pixel)", fontSize: 7, color: "var(--text-muted)", marginBottom: 4, letterSpacing: ".05em" }}>{d.day}</div>
          <div style={{ display: "flex", gap: 3 }}>
            {d.idx.map((i) => {
              const on = bits[i] === "1";
              return (
                <span key={i} title={SLOTS[i].day + " " + SLOTS[i].part}
                  onClick={() => !readOnly && onToggle && onToggle(i)}
                  style={{
                    width: size, height: size, borderRadius: 3, cursor: readOnly ? "default" : "pointer",
                    display: "flex", alignItems: "center", justifyContent: "center",
                    fontSize: size * 0.55, lineHeight: 1, color: on ? "var(--navy-950)" : "var(--text-muted)",
                    background: on ? "var(--grad-gold)" : "var(--navy-900)",
                    border: `1px solid ${on ? "var(--gold-400)" : "var(--border-default)"}`,
                    boxShadow: on ? "var(--glow-gold-sm)" : "inset 0 1px 2px rgba(0,0,0,.5)",
                    transition: "all var(--dur-fast)", userSelect: "none",
                  }}>{SLOTS[i].part}</span>
              );
            })}
          </div>
        </div>
      ))}
    </div>
  );
}

function PersonModal({ person, category, onClose, refresh }) {
  const [f, setF] = React.useState(person || {
    category, name: "", role_title: "", ring: "gold", assigned: "", avatar: "", room: "", presence: "00000000",
  });
  const set = (k) => (e) => setF({ ...f, [k]: e.target.value });
  const togglePresence = (i) => {
    const bits = (f.presence || "00000000").split("");
    bits[i] = bits[i] === "1" ? "0" : "1";
    setF({ ...f, presence: bits.join("") });
  };
  const save = async () => {
    if (!f.name.trim()) return alert("請填姓名");
    const body = { category: f.category, name: f.name.trim(), role_title: f.role_title, ring: f.ring, assigned: f.assigned, avatar: f.avatar, room: f.room.trim(), presence: f.presence };
    if (person) await api("PUT", "/api/roster/" + person.id, body);
    else await api("POST", "/api/roster", body);
    await refresh(); onClose();
  };
  const del = person ? async () => { await api("DELETE", "/api/roster/" + person.id); await refresh(); onClose(); } : null;
  return (
    <Modal title={person ? "編輯成員" : "新增成員"} onClose={onClose} width={560}>
      <FormRow cols="1fr 1.4fr">
        <Select label="類別" value={f.category} onChange={set("category")} options={GROUPS.map((g) => ({ value: g.id, label: g.label }))} />
        <Input label="姓名" value={f.name} onChange={set("name")} />
      </FormRow>
      <FormRow cols="1fr 1fr">
        <Input label="職稱／小隊" value={f.role_title} onChange={set("role_title")} placeholder="例：美宣組長 / 第一小隊" />
        <Input label="房間" value={f.room} onChange={set("room")} placeholder="例：A101（留空＝未分配）" />
      </FormRow>
      <FormRow cols="1fr 1fr 1fr">
        <Select label="頭像環" value={f.ring} onChange={set("ring")}
          options={[{ value: "gold", label: "金 · 一般" }, { value: "ceo", label: "CEO 金" }, { value: "cpo", label: "CPO 藍" }, { value: "cbo", label: "CBO 綠" }]} />
        <Select label="角色適配（學員）" value={f.assigned} onChange={set("assigned")}
          options={[{ value: "", label: "—" }, { value: "ceo", label: "CEO 願景領航" }, { value: "cpo", label: "CPO 產品創新" }, { value: "cbo", label: "CBO 商業拓展" }]} />
        <Select label="英雄頭像" value={f.avatar} onChange={set("avatar")}
          options={[{ value: "", label: "文字縮寫" }, { value: "drc", label: "Dr.C" }, { value: "drg", label: "Dr.G" }, { value: "kenshikai", label: "犬齒俠" }, { value: "inunosuke", label: "犬之助" }]} />
      </FormRow>
      <div style={{ marginBottom: 16 }}>
        <div style={{ fontFamily: "var(--font-serif)", fontSize: 13, color: "var(--text-gold)", letterSpacing: ".06em", marginBottom: 8 }}>在營時間</div>
        <PresenceGrid presence={f.presence} onToggle={togglePresence} size={22} />
      </div>
      <ModalActions onSave={save} onCancel={onClose} onDelete={del} />
    </Modal>
  );
}

function PersonRow({ p, canEdit, onEdit, onPresence }) {
  const src = p.avatar ? heroSrc(p.avatar) : null;
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 14, padding: "12px 14px", background: "var(--navy-850)", border: "1px solid var(--border-default)", borderRadius: "var(--radius-md)" }}>
      <Avatar src={src} name={p.name} initials={p.name[0]} pixel={!!src} ring={p.ring} size={46} />
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ display: "flex", alignItems: "baseline", gap: 8 }}>
          <span style={{ fontFamily: "var(--font-serif)", fontWeight: 700, color: "var(--text-primary)", fontSize: 15.5 }}>{p.name}</span>
          {p.room && <span style={{ fontFamily: "var(--font-pixel)", fontSize: 7.5, color: "var(--tooth-cyan)" }}>⌂ {p.room}</span>}
        </div>
        <div style={{ fontSize: 12.5, color: "var(--text-muted)" }}>{p.role_title}</div>
      </div>
      <PresenceGrid presence={p.presence} onToggle={(i) => onPresence(p, i)} />
      {p.assigned && <RoleBadge role={p.assigned} size={40} showLabel={false} />}
      {canEdit && <EditPencil onClick={() => onEdit(p)} />}
    </div>
  );
}

// 房間分配表：按房間分組
function RoomBoard({ roster, canEdit, onEdit }) {
  const withRoom = roster.filter((p) => p.room);
  const noRoom = roster.filter((p) => !p.room && ["staff", "mentors", "students"].includes(p.category));
  const rooms = [...new Set(withRoom.map((p) => p.room))].sort();
  return (
    <div style={{ padding: 18 }}>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(240px, 1fr))", gap: 14 }}>
        {rooms.map((room) => {
          const people = withRoom.filter((p) => p.room === room);
          return (
            <div key={room} style={{ background: "var(--navy-850)", border: "1px solid var(--border-default)", borderRadius: "var(--radius-md)", padding: 14 }}>
              <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 10, paddingBottom: 8, borderBottom: "1px solid var(--divider)" }}>
                <span style={{ fontFamily: "var(--font-display)", fontWeight: 900, fontSize: 18, color: "var(--text-gold)" }}>⌂ {room}</span>
                <Badge tone="gold" size="sm" style={{ marginLeft: "auto" }}>{people.length} 人</Badge>
              </div>
              <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
                {people.map((p) => (
                  <div key={p.id} style={{ display: "flex", alignItems: "center", gap: 10 }}>
                    <Avatar src={p.avatar ? heroSrc(p.avatar) : null} name={p.name} initials={p.name[0]} pixel={!!p.avatar} ring={p.ring} size={30} />
                    <span style={{ fontSize: 14, color: "var(--text-primary)", fontFamily: "var(--font-serif)" }}>{p.name}</span>
                    <span style={{ fontSize: 11, color: "var(--text-muted)" }}>{GROUP_LABEL[p.category]}</span>
                    {canEdit && <EditPencil style={{ marginLeft: "auto" }} onClick={() => onEdit(p)} />}
                  </div>
                ))}
              </div>
            </div>
          );
        })}
      </div>
      {noRoom.length > 0 && (
        <div style={{ marginTop: 18, padding: 14, background: "rgba(138,47,36,.12)", border: "1px solid rgba(138,47,36,.4)", borderRadius: "var(--radius-md)" }}>
          <div style={{ fontFamily: "var(--font-serif)", fontSize: 14, color: "var(--ember-500)", marginBottom: 8 }}>⚑ 尚未分配房間（{noRoom.length} 人）</div>
          <div style={{ display: "flex", flexWrap: "wrap", gap: 8 }}>
            {noRoom.map((p) => (
              <span key={p.id} onClick={() => canEdit && onEdit(p)} style={{ fontSize: 13, padding: "4px 12px", borderRadius: "var(--radius-pill)", background: "var(--navy-900)", border: "1px solid var(--border-default)", color: "var(--text-secondary)", cursor: canEdit ? "pointer" : "default" }}>
                {p.name} · {GROUP_LABEL[p.category]}
              </span>
            ))}
          </div>
        </div>
      )}
    </div>
  );
}

function Roster({ data, refresh, canEdit }) {
  const [tab, setTab] = React.useState("staff");
  const [q, setQ] = React.useState("");
  const [modal, setModal] = React.useState(null); // { person } | { new: true }

  const items = [
    ...GROUPS.map((g) => ({ id: g.id, label: g.label, badge: data.roster.filter((p) => p.category === g.id).length })),
    { id: "rooms", label: "房間分配", badge: [...new Set(data.roster.filter((p) => p.room).map((p) => p.room))].length },
  ];

  const onPresence = async (p, i) => {
    const bits = (p.presence || "00000000").split("");
    bits[i] = bits[i] === "1" ? "0" : "1";
    await api("PATCH", "/api/roster/" + p.id + "/presence", { presence: bits.join("") });
    await refresh();
  };

  const list = data.roster
    .filter((p) => p.category === tab)
    .filter((p) => !q || p.name.includes(q) || p.role_title.includes(q) || p.room.includes(q));

  return (
    <Panel header="名單管理 · Roster" inset="0">
      <div style={{ padding: "14px 18px 0" }}>
        <div style={{ display: "flex", justifyContent: "space-between", gap: 16, alignItems: "center", flexWrap: "wrap" }}>
          <Tabs value={tab} onChange={setTab} items={items} />
          <div style={{ display: "flex", gap: 10, alignItems: "center" }}>
            <div style={{ width: 200 }}>
              <Input size="sm" placeholder="搜尋成員…" iconLeft={<span>⌕</span>} value={q} onChange={(e) => setQ(e.target.value)} />
            </div>
            {canEdit && <Button size="sm" onClick={() => setModal({ new: true })}>＋ 新增</Button>}
          </div>
        </div>
        <div style={{ marginTop: 10, fontSize: 11.5, color: "var(--text-muted)" }}>
          在營時間：點格子切換 早／午／晚 出席（8/14 – 8/16 共 8 格）
        </div>
      </div>
      {tab === "rooms" ? (
        <RoomBoard roster={data.roster} canEdit={canEdit} onEdit={(p) => setModal({ person: p })} />
      ) : (
        <div style={{ padding: 18, display: "grid", gridTemplateColumns: "1fr", gap: 12 }}>
          {list.map((p) => (
            <PersonRow key={p.id} p={p} canEdit={canEdit} onEdit={(person) => setModal({ person })} onPresence={onPresence} />
          ))}
          {!list.length && <div style={{ color: "var(--text-muted)", fontSize: 13.5 }}>沒有符合的成員。</div>}
        </div>
      )}
      {modal && (
        <PersonModal person={modal.person} category={tab === "rooms" ? "staff" : tab} onClose={() => setModal(null)} refresh={refresh} />
      )}
    </Panel>
  );
}
window.Roster = Roster;
})();
