/* ==================================================================
   Admin Cockpit → Holidays
   ------------------------------------------------------------------
   Announcing a holiday does two irreversible-feeling things at once, so
   this screen is built around saying what they are BEFORE the button is
   pressed, and showing what actually happened afterwards:

     1. An approved outpass per boarder, waiting at the gate. On this
        school that is ~329 rows. The guard taps Out as each child
        leaves, so the gate board keeps describing who is really here.
     2. The attendance machinery is told the school is shut: no check-in
        nudge, no absence digest to admins, no 07:00 boarder auto-mark,
        and the staff heat-map stops counting the day as a working day.
        That last one is what makes a holiday not a leave.

   Check-in is NOT blocked. Wardens and office staff work through a
   break and their day should still be recorded.

   Nothing here is a silent bulk action: Announce shows the exact pass
   count and waits for a second press, and Cancel says how many passes
   it will withdraw. Everything else in this file is a list.
   ================================================================== */

const HolidaysScreen = ({ setScreen }) => {
  const CX = window.CX;
  const Api = window.KXApi;

  const [list, setList] = useState(null);
  const [preview, setPreview] = useState(null);
  const [err, setErr] = useState(null);
  const [busy, setBusy] = useState(false);
  const [done, setDone] = useState(null);

  const todayIso = (() => {
    // Local parts, not toISOString(): before 05:30 IST that returns yesterday.
    const d = new Date();
    return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
  })();

  const [form, setForm] = useState({
    name: "", start_date: todayIso, end_date: todayIso, notes: "",
    generate_outpasses: true, pause_staff_attendance: true, pause_student_automark: true,
  });
  const [confirming, setConfirming] = useState(false);

  const load = async () => {
    try {
      const [h, p] = await Promise.all([
        Api.get("/admin/holidays?limit=24"),
        Api.get("/admin/holidays/preview"),
      ]);
      setList(h.holidays); setPreview(p); setErr(null);
    } catch (e) { setErr(e.message || "Couldn't load holidays"); }
  };
  useEffect(() => { load(); }, []);

  const set = (k) => (e) => {
    const v = e.target.type === "checkbox" ? e.target.checked : e.target.value;
    setForm((f) => {
      const next = { ...f, [k]: v };
      // A range that ends before it starts is a typo, not a choice.
      if (k === "start_date" && next.end_date < v) next.end_date = v;
      return next;
    });
    setConfirming(false);
  };

  const announce = async () => {
    setBusy(true); setErr(null);
    try {
      const r = await Api.post("/admin/holidays", form);
      setDone(r);
      setConfirming(false);
      setForm((f) => ({ ...f, name: "", notes: "" }));
      await load();
    } catch (e) { setErr(e.message || "Couldn't announce the holiday"); }
    finally { setBusy(false); }
  };

  const cancel = async (h) => {
    const waiting = h.passes_waiting;
    const msg = waiting
      ? `Call off ${h.name}? ${waiting} unused pass(es) will be withdrawn. Passes already used at the gate stay as they are.`
      : `Call off ${h.name}?`;
    if (!window.confirm(msg)) return;
    setBusy(true); setErr(null);
    try {
      await Api.post(`/admin/holidays/${h.id}/cancel`, {});
      setDone(null);
      await load();
    } catch (e) { setErr(e.message || "Couldn't cancel the holiday"); }
    finally { setBusy(false); }
  };

  const days = (() => {
    const a = new Date(`${form.start_date}T00:00:00Z`), b = new Date(`${form.end_date}T00:00:00Z`);
    const n = Math.round((b - a) / 86400000) + 1;
    return Number.isFinite(n) && n > 0 ? n : 0;
  })();
  const ready = form.name.trim() && form.start_date && form.end_date && days > 0 && !busy;

  return (
    <div className="cx-page">
      <CX.PageHead
        eyebrow="Academics"
        title="Holidays"
      />

      {err && <div className="cx-note" style={{ background: "var(--red-bg)", color: "var(--red-solid)" }}>{err}</div>}

      {done && (
        <div className="cx-note" style={{ background: "var(--green-bg)", color: "var(--green-solid)" }}>
          <strong>{done.holiday.name}</strong> announced ·{" "}
          {done.passes_created} pass{done.passes_created === 1 ? "" : "es"} created
          {done.skipped_existing && done.skipped_existing.length > 0 && (
            <> · {done.skipped_existing.length} boarder(s) already held a pass and were left alone:{" "}
              {done.skipped_existing.map((s) => `${s.name} (${s.pass_no})`).join(", ")}</>
          )}
        </div>
      )}

      {/* ── Announce ─────────────────────────────────────────────── */}
      <CX.Card>
        <div className="cx-card-head"><div className="cx-card-title">Announce a holiday</div></div>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(190px, 1fr))", gap: 12, marginBottom: 12 }}>
          <label style={{ display: "grid", gap: 6 }}>
            <span className="muted">Name</span>
            <input className="input" value={form.name} onChange={set("name")} placeholder="Durga Puja break" maxLength={120}/>
          </label>
          <label style={{ display: "grid", gap: 6 }}>
            <span className="muted">First day</span>
            <input className="input" type="date" value={form.start_date} onChange={set("start_date")}/>
          </label>
          <label style={{ display: "grid", gap: 6 }}>
            <span className="muted">Last day</span>
            <input className="input" type="date" value={form.end_date} min={form.start_date} onChange={set("end_date")}/>
          </label>
          <label style={{ display: "grid", gap: 6, gridColumn: "1 / -1" }}>
            <span className="muted">Notes (optional)</span>
            <input className="input" value={form.notes} onChange={set("notes")} placeholder="Hostel reopens on the evening of the last day" maxLength={1000}/>
          </label>
        </div>

        <div style={{ display: "grid", gap: 8, fontSize: 13, marginBottom: 12 }}>
          <label><input type="checkbox" checked={form.generate_outpasses} onChange={set("generate_outpasses")}/>
            {" "}Generate an outpass for every boarder</label>
          <label><input type="checkbox" checked={form.pause_staff_attendance} onChange={set("pause_staff_attendance")}/>
            {" "}Pause staff attendance (no nudges, not counted as leave)</label>
          <label><input type="checkbox" checked={form.pause_student_automark} onChange={set("pause_student_automark")}/>
            {" "}Stop the boarder register filling itself in</label>
        </div>

        <p className="muted" style={{ marginBottom: 12 }}>
          {days > 0 && <>{days} day{days === 1 ? "" : "s"}. </>}
          {form.generate_outpasses && preview
            ? <>
                {preview.passes_to_create} approved pass{preview.passes_to_create === 1 ? "" : "es"} will be
                created for {preview.boarders} boarder{preview.boarders === 1 ? "" : "s"}
                {preview.already_hold_a_pass > 0 && <> ({preview.already_hold_a_pass} already hold one and will be left alone)</>}.
                {" "}The gate marks each child out as they actually leave.
              </>
            : <>No passes will be generated.</>}
        </p>

        {!confirming ? (
          <button className="btn primary" disabled={!ready} onClick={() => { setDone(null); setConfirming(true); }}>
            Announce holiday
          </button>
        ) : (
          <div style={{ display: "flex", gap: 10, alignItems: "center", flexWrap: "wrap" }}>
            <span>
              Announce <strong>{form.name}</strong> for {days} day{days === 1 ? "" : "s"}
              {form.generate_outpasses && preview ? <> and create {preview.passes_to_create} passes</> : null}?
            </span>
            <button className="btn primary" disabled={busy} onClick={announce}>
              {busy ? "Announcing…" : "Yes, announce"}
            </button>
            <button className="btn ghost" disabled={busy} onClick={() => setConfirming(false)}>Back</button>
          </div>
        )}
      </CX.Card>

      {/* ── What has been announced ──────────────────────────────── */}
      <CX.Card>
        <div className="cx-card-head"><div className="cx-card-title">Announced</div></div>
        {!list && <CX.Skeleton rows={3}/>}
        {list && list.length === 0 && <CX.Empty title="No holidays announced yet"/>}
        {list && list.length > 0 && (
          <div className="cx-tablescroll"><table className="cx-table">
            <thead>
              <tr>
                <th>Holiday</th><th>Dates</th><th>Passes</th><th>Pauses</th><th>Announced</th><th></th>
              </tr>
            </thead>
            <tbody>
              {list.map((h) => (
                <tr key={h.id} style={h.cancelled_at ? { opacity: 0.55 } : undefined}>
                  <td>
                    <strong>{h.name}</strong>
                    {h.running_now && <> <span className="cx-pill tint green">on now</span></>}
                    {h.cancelled_at && <> <span className="cx-pill grey tint">called off</span></>}
                    {h.notes && <div className="muted">{h.notes}</div>}
                  </td>
                  <td>{h.start_date === h.end_date ? CX.date(h.start_date) : `${CX.date(h.start_date)} – ${CX.date(h.end_date)}`}</td>
                  <td>
                    {h.passes_total === 0 ? <span className="muted">none</span> : (
                      <>
                        {h.passes_total} total
                        <div className="muted">
                          {h.passes_waiting} waiting · {h.passes_out} out · {h.passes_back} back
                          {h.passes_cancelled > 0 && <> · {h.passes_cancelled} cancelled</>}
                        </div>
                      </>
                    )}
                  </td>
                  <td className="muted">
                    {h.pause_staff_attendance ? "staff" : "—"}
                    {h.pause_student_automark ? " · register" : ""}
                  </td>
                  <td className="muted">
                    {CX.date(h.announced_at)}{h.announced_by_name ? ` · ${h.announced_by_name}` : ""}
                    {h.cancelled_at && <div>called off {CX.date(h.cancelled_at)}{h.cancelled_by_name ? ` · ${h.cancelled_by_name}` : ""}</div>}
                  </td>
                  <td>
                    {!h.cancelled_at && (
                      <button className="btn ghost sm" disabled={busy} onClick={() => cancel(h)}>Call off</button>
                    )}
                  </td>
                </tr>
              ))}
            </tbody>
          </table></div>
        )}
      </CX.Card>

      <p className="muted">
        Passes appear on the hostel app's Gate screen straight away. A boarder who is staying back
        keeps their pass until a warden cancels it there — see{" "}
        <a href="#" onClick={(e) => { e.preventDefault(); setScreen("hostel"); }}>Hostel</a>.
      </p>
    </div>
  );
};

window.CockpitHolidays = HolidaysScreen;
