/* ==================================================================
   Admin Cockpit → Hostel  (overview + student-wise reports)
   ------------------------------------------------------------------
   Two screens in one file because they share a vocabulary: occupancy,
   outpasses, infirmary, discipline.

   Reads /admin/cockpit/hostel and /admin/cockpit/hostel/report. The
   hostel subsystem exists in the backend (rooms, gate, outpasses, health
   logs) but was never surfaced in the admin panel — this is that surface.
   ================================================================== */

/* ---------- Overview ---------- */

const HostelScreen = ({ setScreen }) => {
  const CX = window.CX;
  const state = CX.useCockpitData("/admin/cockpit/hostel", { pollMs: 60000 });
  const d = state.data;

  const openReport = (type) => {
    window.KX.HOSTEL_REPORT_CONTEXT = { type };
    setScreen("hostel-report");
  };

  const outcomePill = (h) => {
    const s = (h.status || "").toLowerCase();
    if (s === "open")        return <span className="cx-pill tint amber">Open</span>;
    if (s === "observation") return <span className="cx-pill tint blue">Observation</span>;
    if (s === "closed" || s === "resolved") return <span className="cx-pill tint green">Closed</span>;
    return <span className="cx-pill tint grey">{CX.title(h.status || "—")}</span>;
  };

  return (
    <div className="cx-page">
      <CX.PageHead
        eyebrow="Adarshabani Hostel"
        title="Hostel"
        actions={
          <button className="cx-btn-dark" onClick={() => openReport("leave")}>
            <CX.Icon name="download" size={16}/> Outpass register
          </button>
        }
      />

      <CX.Screen state={state}>
        {d && (
          <>
            <div className="cx-grid cols-3" style={{ gridTemplateColumns: "repeat(3,1fr)", marginBottom: 20 }}>
              <CX.StatCard
                icon="building" color="var(--green-solid)" label="Boarders Inside"
                value={CX.num(d.occupancy.inside)}
                suffix={`/ ${CX.num(d.occupancy.allocated)} allocated`}
                onAction={() => openReport("attendance")}
                actionLabel="Open attendance report"
                footNote={
                  `${d.occupancy.rooms} rooms · ${CX.num(d.occupancy.beds)} beds` +
                  (d.occupancy.unallocated ? ` · ${CX.num(d.occupancy.unallocated)} boarders without a bed` : "")
                }
                action={<span className="cx-pill">Gate live</span>}
              />
              <CX.StatCard
                icon="clock" color="var(--blue-solid)" label="Active Outpasses"
                value={CX.num(d.outpasses.outNow)}
                delta={d.outpasses.overdue ? `${d.outpasses.overdue} overdue` : null}
                deltaTone="warn"
                onAction={() => openReport("leave")}
                actionLabel="Open leave report"
                footNote={
                  `${d.outpasses.awaiting} awaiting warden approval · ` +
                  `${d.outpasses.approved} approved, not yet out`
                }
                action={<span className="cx-pill">Review</span>}
              />
              <CX.StatCard
                icon="heart" color="var(--pink-solid)" label="Infirmary"
                value={CX.num(d.health.active)}
                delta={d.health.today ? `${d.health.today} visit${d.health.today === 1 ? "" : "s"} today` : null}
                deltaTone="flat"
                onAction={() => openReport("health")}
                actionLabel="Open health report"
                footNote={`${d.health.onMedication} boarder(s) on recorded medication`}
                action={<span className="cx-pill">Log</span>}
              />
            </div>

            <div className="cx-grid split" style={{ gridTemplateColumns: "1.1fr 1fr 1fr" }}>
              {/* ---- Outpasses out / due ---- */}
              <CX.Card>
                <div className="cx-card-head">
                  <div className="cx-card-title">Out &amp; Due Back</div>
                  <span className="cx-pill">{d.outpasses.list.length} on register</span>
                </div>
                {d.outpasses.list.length === 0 ? (
                  <CX.Empty icon="clock" title="Nobody is out"
                            hint="Outpasses raised at the gate appear here."/>
                ) : d.outpasses.list.map((o, i) => {
                  const overdue = o.status === "out" && o.expected_return_at
                    && new Date(o.expected_return_at) < new Date();
                  return (
                    <div key={i} className="cx-row">
                      <CX.Avatar name={o.student_name} size="sm"/>
                      <div style={{ flex: 1, minWidth: 0 }}>
                        <div className="cx-row-title" style={{ whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
                          {o.student_name}
                          <span style={{ color: "var(--ink-3)", fontWeight: 500 }}>
                            {o.class_level ? ` · ${o.class_level}${o.section || ""}` : ""}
                          </span>
                        </div>
                        <div className="cx-row-sub">
                          {[CX.title(o.kind), o.reason, o.destination].filter(Boolean).join(" · ")}
                        </div>
                      </div>
                      <div style={{ textAlign: "right", flexShrink: 0 }}>
                        {overdue
                          ? <span className="cx-pill tint red">Overdue</span>
                          : o.status === "out"
                            ? <span className="cx-pill tint amber">Out</span>
                            : <span className="cx-pill tint blue">{CX.title(o.status)}</span>}
                        <div style={{ fontSize: 11.5, color: "var(--ink-3)", marginTop: 4 }}>
                          {o.expected_return_at ? `due ${CX.date(o.expected_return_at)} ${CX.time(o.expected_return_at)}` : "no return time"}
                        </div>
                      </div>
                    </div>
                  );
                })}
                <div className="cx-card-foot">
                  <span style={{ fontSize: 13, color: "var(--ink-3)" }}>
                    {d.outpasses.returnedToday} returned today · {d.outpasses.lateReturns} late on record
                  </span>
                  <button className="cx-pill" onClick={() => openReport("leave")}>Register</button>
                </div>
              </CX.Card>

              {/* ---- Health ---- */}
              <CX.Card>
                <div className="cx-card-head">
                  <div className="cx-card-title">Health Records</div>
                  {d.health.today > 0
                    ? <span className="cx-pill tint red">{d.health.today} today</span>
                    : <span className="cx-pill grey tint">None today</span>}
                </div>
                {d.health.list.length === 0 ? (
                  <CX.Empty icon="heart" title="No infirmary visits logged"
                            hint="Entries made by the warden appear here."/>
                ) : d.health.list.map((h, i) => (
                  <div key={i} className="cx-row">
                    <CX.Avatar name={h.student_name} size="sm"/>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div className="cx-row-title">
                        {h.student_name}
                        <span style={{ color: "var(--ink-3)", fontWeight: 500 }}>
                          {h.class_level ? ` · ${h.class_level}${h.section || ""}` : ""}
                        </span>
                      </div>
                      <div className="cx-row-sub" style={{ whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
                        {[
                          h.symptom_notes,
                          CX.temp(h.temperature_c),
                          h.medication,
                        ].filter(Boolean).join(" · ") || CX.date(h.visited_at)}
                      </div>
                    </div>
                    {outcomePill(h)}
                  </div>
                ))}
                <div className="cx-card-foot">
                  <span style={{ fontSize: 13, color: "var(--ink-3)" }}>
                    {d.visitors.inside} visitor(s) inside · {d.visitors.today} signed in today
                  </span>
                  <button className="cx-pill" onClick={() => openReport("health")}>Full log</button>
                </div>
              </CX.Card>

              {/* ---- Discipline ---- */}
              <CX.Card>
                <div className="cx-card-head">
                  <div className="cx-card-title">Discipline</div>
                  {d.discipline.open > 0
                    ? <span className="cx-pill tint amber">{d.discipline.open} open</span>
                    : <span className="cx-pill tint green">All clear</span>}
                </div>
                {d.discipline.list.length === 0 ? (
                  <CX.Empty icon="shield" title="No incidents recorded"
                            hint="Complaints raised by staff appear here."/>
                ) : d.discipline.list.map((c) => {
                  const resolved = ["resolved", "closed"].includes(c.status);
                  const color = resolved ? "var(--green-solid)"
                    : c.status === "investigating" ? "var(--amber-solid)" : "var(--red-solid)";
                  return (
                    <div key={c.id} style={{
                      display: "flex", gap: 12, padding: "12px 0",
                      borderBottom: "1px solid var(--line-soft)",
                    }}>
                      <span className="cx-dot" style={{ background: color, boxShadow: `0 0 0 4px ${color}22` }}/>
                      <div style={{ flex: 1, minWidth: 0 }}>
                        <div style={{ fontSize: 14, fontWeight: 600, color: "var(--ink-0)" }}>
                          {CX.title(c.status)}{c.students ? ` · ${c.students}` : ""}
                        </div>
                        <div className="cx-row-sub" style={{ display: "-webkit-box", WebkitLineClamp: 2, WebkitBoxOrient: "vertical", overflow: "hidden" }}>
                          {c.about || "(no description)"}
                        </div>
                      </div>
                      <span style={{ fontSize: 12, color: "var(--ink-3)", whiteSpace: "nowrap" }}>
                        {CX.relTime(c.created_at)}
                      </span>
                    </div>
                  );
                })}
                <div className="cx-card-foot">
                  <span style={{ fontSize: 13, color: "var(--ink-3)" }}>
                    {d.discipline.total} incident{d.discipline.total === 1 ? "" : "s"} on record
                  </span>
                </div>
              </CX.Card>
            </div>
          </>
        )}
      </CX.Screen>
    </div>
  );
};

/* ---------- Student-wise reports ---------- */

const HostelReportScreen = ({ setScreen }) => {
  const CX = window.CX;
  // Honour the tile that sent us here, then forget it, so a later visit from
  // the sub-nav opens the default tab rather than the last drill-down.
  const [type, setType] = useState(() => {
    const t = window.KX.HOSTEL_REPORT_CONTEXT?.type;
    delete window.KX.HOSTEL_REPORT_CONTEXT;
    return t || "attendance";
  });
  const [period, setPeriod] = useState("daily");
  const state = CX.useCockpitData(`/admin/cockpit/hostel/report?type=${type}&period=${period}`);
  const d = state.data;

  const TITLES = {
    attendance: "Attendance Report",
    leave: "Leave & Outpass Report",
    health: "Health Report",
  };
  const PERIOD_TITLE = {
    daily: "Today", monthly: "Last 30 days", periodic: "This term",
  };

  const exportCsv = () => {
    if (!d) return;
    const head = ["Boarder", "Class", ...d.headers];
    const body = (d.rows || []).map((r) => {
      const who = [r.name, `${r.class_level || ""}${r.section || ""}`];
      if (type === "attendance") {
        return [...who, r.out_status === "out" ? "Out" : "Inside",
                `${r.outpass_count} outpass(es)`, r.room_no || "—"];
      }
      if (type === "leave") {
        return [...who, `${CX.date(r.expected_out_at)} → ${CX.date(r.expected_return_at)}`,
                r.reason || "—", CX.title(r.status)];
      }
      return [...who, r.symptom_notes || "—", r.medication || r.action_taken || "—",
              CX.title(r.outcome || r.status || "—")];
    });
    CX.exportCsv(`hostel-${type}-${period}.csv`, [head, ...body]);
  };

  const cellsFor = (r) => {
    if (type === "attendance") {
      const overdue = r.out_status === "out" && r.due_back && new Date(r.due_back) < new Date();
      return {
        c1: r.out_status === "out"
          ? `Out · due ${CX.date(r.due_back)} ${CX.time(r.due_back)}`
          : "Inside",
        c2: `${r.outpass_count} outpass${r.outpass_count === 1 ? "" : "es"} on record`,
        c3: r.room_no ? `Room ${r.room_no}` : "No room allocated",
        pill: overdue ? <span className="cx-pill tint red">Overdue</span>
            : r.out_status === "out" ? <span className="cx-pill tint amber">On outpass</span>
            : <span className="cx-pill tint green">Inside</span>,
      };
    }
    if (type === "leave") {
      return {
        c1: `${CX.date(r.expected_out_at)} → ${CX.date(r.expected_return_at)}`,
        c2: r.reason || CX.title(r.kind) || "—",
        c3: r.destination || "—",
        pill: r.returned_late ? <span className="cx-pill tint red">Late</span>
            : r.status === "requested" ? <span className="cx-pill tint amber">Pending</span>
            : r.status === "returned" ? <span className="cx-pill tint grey">Returned</span>
            : <span className="cx-pill tint green">{CX.title(r.status)}</span>,
      };
    }
    return {
      c1: [r.symptom_notes, CX.temp(r.temperature_c)].filter(Boolean).join(" · ") || "—",
      c2: r.medication || r.action_taken || "—",
      c3: r.referred_to ? `Referred · ${r.referred_to}` : CX.date(r.visited_at),
      pill: r.status === "open" ? <span className="cx-pill tint amber">Open</span>
          : r.status === "observation" ? <span className="cx-pill tint blue">Observation</span>
          : <span className="cx-pill tint green">{CX.title(r.status || "closed")}</span>,
    };
  };

  return (
    <div className="cx-page">
      <CX.PageHead
        eyebrow="Hostel reports · student-wise"
        title={TITLES[type]}
        onBack={() => setScreen("hostel")}
        actions={
          <button className="cx-btn-dark" onClick={exportCsv} disabled={!d?.rows?.length}>
            <CX.Icon name="download" size={16}/> Export CSV
          </button>
        }
      />

      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12, marginBottom: 20, flexWrap: "wrap" }}>
        <CX.Seg value={type} onChange={setType} options={[
          { value: "attendance", label: "Attendance" },
          { value: "leave", label: "Leave & Outpass" },
          { value: "health", label: "Health" },
        ]}/>
        <CX.Seg value={period} onChange={setPeriod} options={[
          { value: "daily", label: "Daily" },
          { value: "monthly", label: "Monthly" },
          { value: "periodic", label: "Periodic" },
        ]}/>
      </div>

      <CX.Screen state={state} skeleton={<CX.Skeleton rows={4} height={90}/>}>
        {d && (
          <>
            <div className="cx-grid cols-4" style={{ gridTemplateColumns: "repeat(4,1fr)", marginBottom: 20 }}>
              {d.chips.map((c, i) => (
                <div key={i} className="cx-card tight">
                  <div style={{ fontSize: 13, color: "var(--ink-3)", marginBottom: 6 }}>{c.label}</div>
                  <div style={{ display: "flex", alignItems: "baseline", gap: 8 }}>
                    <span className="cx-stat-value sm">{c.big}</span>
                    <span style={{ fontSize: 12.5, fontWeight: 600, color: "var(--ink-3)" }}>{c.sub}</span>
                  </div>
                </div>
              ))}
            </div>

            <CX.Card>
              <div className="cx-card-head" style={{ marginBottom: 4 }}>
                <div className="cx-card-title">{PERIOD_TITLE[period]}</div>
                <span className="cx-pill">{d.rows.length} row{d.rows.length === 1 ? "" : "s"}</span>
              </div>

              <div style={{ overflowX: "auto" }}>
                <div style={{ minWidth: 780 }}>
                  <div style={{
                    display: "flex", gap: 16, padding: "10px 0",
                    borderBottom: "1px solid var(--line-soft)",
                    fontSize: 11.5, fontWeight: 600, color: "var(--ink-3)", letterSpacing: "0.6px",
                  }}>
                    <div style={{ width: 42, flexShrink: 0 }}/>
                    <div style={{ width: 180, flexShrink: 0 }}>BOARDER</div>
                    <div style={{ flex: 1 }}>{d.headers[0]}</div>
                    <div style={{ flex: 1 }}>{d.headers[1]}</div>
                    <div style={{ flex: 1 }}>{d.headers[2]}</div>
                    <div style={{ width: 104, textAlign: "center", flexShrink: 0 }}>STATUS</div>
                  </div>

                  {d.rows.length === 0 && (
                    <CX.Empty icon="file" title="Nothing recorded for this period"
                              hint="Try a wider period, or check the gate log."/>
                  )}

                  {d.rows.map((r, i) => {
                    const c = cellsFor(r);
                    return (
                      <div key={i} style={{
                        display: "flex", alignItems: "center", gap: 16,
                        padding: "12px 0", borderBottom: "1px solid var(--line-soft)",
                      }}>
                        <CX.Avatar name={r.name} size="lg"/>
                        <div style={{ width: 180, flexShrink: 0, minWidth: 0 }}>
                          <div className="cx-row-title">{r.name}</div>
                          <div className="cx-row-sub">
                            {[`${r.class_level || "—"}${r.section || ""}`, r.roll_no].filter(Boolean).join(" · ")}
                          </div>
                        </div>
                        <div style={{ flex: 1, fontSize: 13.5, fontWeight: 500, color: "var(--ink-0)", minWidth: 0 }}>{c.c1}</div>
                        <div style={{ flex: 1, fontSize: 13.5, color: "var(--ink-1)", minWidth: 0 }}>{c.c2}</div>
                        <div style={{ flex: 1, fontSize: 13.5, color: "var(--ink-2)", minWidth: 0 }}>{c.c3}</div>
                        <div style={{ width: 104, display: "flex", justifyContent: "center", flexShrink: 0 }}>{c.pill}</div>
                      </div>
                    );
                  })}
                </div>
              </div>

              <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", paddingTop: 14 }}>
                <span style={{ fontSize: 13, color: "var(--ink-3)" }}>
                  Rows are capped at 40 — export the CSV for the full register.
                </span>
              </div>
            </CX.Card>
          </>
        )}
      </CX.Screen>
    </div>
  );
};

window.CockpitHostel = HostelScreen;
window.CockpitHostelReport = HostelReportScreen;
