/* ==================================================================
   Admin → Announcements
   ------------------------------------------------------------------
   Authoring surface for school-wide announcements that flow to the
   Parent app. Class-specific announcements can be authored here too,
   or by teachers from the Teacher app.

   Composer + history list. Soft-delete on the trash button (sets
   deleted_at; the row stays for audit).

   WHERE A NOTICE GOES. Every announcement reaches parents in the app —
   a row in their Notices tab, a push on their phone — the moment it is
   published. "Also on the website" additionally lists it on the public
   notice board at {BRAND.website}/notices. It is an opt-in per notice and
   school-wide only: a class notice is addressed to particular families,
   and the website is public and indexed. The server and a table CHECK
   enforce the same rule, so this screen only has to explain it.
   ================================================================== */

const { Icon: AnnIcon } = window.AppUI;

const AdminAnnouncementsScreen = () => {
  const [rows, setRows]               = React.useState([]);
  const [classSections, setSections]  = React.useState([]);
  const [loading, setLoading]         = React.useState(true);
  const [err, setErr]                 = React.useState(null);

  const [scope, setScope]             = React.useState("school");
  const [classSectionId, setCsId]     = React.useState("");
  const [title, setTitle]             = React.useState("");
  const [body, setBody]               = React.useState("");
  const [pinned, setPinned]           = React.useState(false);
  const [onWebsite, setOnWebsite]     = React.useState(false);
  const [busy, setBusy]               = React.useState(false);
  const [flash, setFlash]             = React.useState(null);

  const load = React.useCallback(async () => {
    setLoading(true); setErr(null);
    try {
      setRows(await window.AppApi.get("/admin/announcements"));
    } catch (e) {
      setErr(String(e.message || e));
    } finally {
      setLoading(false);
    }
  }, []);
  React.useEffect(() => { load(); }, [load]);
  React.useEffect(() => {
    window.AppApi.get("/admin/class-sections").then(setSections).catch(() => {});
  }, []);

  const reset = () => { setTitle(""); setBody(""); setPinned(false); setOnWebsite(false); };

  // A class notice can never be public, so leaving "school-wide" drops the
  // website choice rather than carrying a selection the server would refuse.
  const changeScope = (next) => { setScope(next); if (next !== "school") setOnWebsite(false); };

  const publish = async (e) => {
    e.preventDefault();
    if (!title.trim() || !body.trim()) { window.alert("Title and body are required."); return; }
    if (scope !== "school" && !classSectionId) { window.alert("Pick a class."); return; }
    setBusy(true); setFlash(null);
    try {
      // pinned_until = +7 days when toggled on
      const pinned_until = pinned ? new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString() : null;
      await window.AppApi.post("/admin/announcements", {
        scope, title: title.trim(), body: body.trim(),
        class_section_id: scope === "school" ? null : classSectionId,
        pinned_until,
        publish_to_website: scope === "school" && onWebsite,
      });
      setFlash(scope === "school" && onWebsite
        ? "Published — parents notified in the app, and live on the website."
        : "Published — parents notified in the app.");
      reset();
      await load();
    } catch (e) {
      window.alert("Could not publish: " + (e.message || e));
    } finally {
      setBusy(false);
    }
  };

  const remove = async (id, t) => {
    if (!window.confirm(`Delete announcement "${t}"? Parents will stop seeing it.`)) return;
    try {
      await window.AppApi.del(`/admin/announcements/${id}`);
      await load();
    } catch (e) {
      window.alert("Could not delete: " + (e.message || e));
    }
  };

  // Put a notice on the website, or take it off, without touching what parents
  // already have. Deleting would do the latter too, which is rarely the intent.
  const setWebsite = async (r, on) => {
    const q = on
      ? `Show "${r.title}" on the public website? Anyone can read it there.`
      : `Take "${r.title}" off the website? Parents keep it in the app.`;
    if (!window.confirm(q)) return;
    try {
      await window.AppApi.patch(`/admin/announcements/${r.id}/website`, { publish_to_website: on });
      await load();
    } catch (e) {
      window.alert("Could not update: " + (e.message || e));
    }
  };

  const sectionLabel = (cs) => `${cs.label}${cs.academic_year ? ` · ${cs.academic_year}` : ""}`;
  const fmt = (iso) => new Date(iso).toLocaleString(undefined, {
    month: "short", day: "numeric", hour: "2-digit", minute: "2-digit",
  });

  const AnnBadge = window.AppUI.StatusBadge;
  return (
    <div style={{ overflow: "auto", height: "100%" }}>
    <div className="cx-page" style={{ maxWidth: 1100 }}>
      <window.AppUI.PageHeader
        eyebrow="Admin · announcements"
        title="Announcements"
        meta={["Author school-wide announcements that reach every approved parent. For class-specific notices, teachers can also write from the teacher app — both flow to the same parent feed."]}
      />

      {err && <div className="ui-alert red" style={{ marginBottom: 20 }}>{err}</div>}

      {/* Composer */}
      <form onSubmit={publish} className="cx-card">
        <div className="cx-card-head">
          <div className="cx-card-title">New announcement</div>
          <label style={{ display: "flex", gap: 8, alignItems: "center", fontSize: 13, color: "var(--ink-1)", cursor: "pointer" }}>
            <input type="checkbox" checked={pinned} onChange={e => setPinned(e.target.checked)} />
            Pin for 7 days
          </label>
        </div>

        <div style={{ display: "flex", gap: 12, alignItems: "flex-end", marginBottom: 14, flexWrap: "wrap" }}>
          <div className="field" style={{ margin: 0 }}>
            <label className="label">Scope</label>
            <window.AppUI.Tabs value={scope} onChange={changeScope} ariaLabel="Scope"
              items={[{ value: "school", label: "School-wide" }, { value: "class", label: "Class-specific" }]}/>
          </div>
          {scope !== "school" && (
            <div className="field" style={{ margin: 0 }}>
              <label className="label">Class</label>
              <select className="select" value={classSectionId}
                onChange={e => setCsId(e.target.value)}
                style={{ minWidth: 220 }}>
                <option value="">Pick a class…</option>
                {classSections.map(cs => (
                  <option key={cs.id} value={cs.id}>{sectionLabel(cs)}</option>
                ))}
              </select>
            </div>
          )}
        </div>

        <div className="field">
          <label className="label">Title</label>
          <input className="input" value={title}
            onChange={e => setTitle(e.target.value)}
            placeholder="Title — e.g. Annual Day Registration Deadline"
            style={{ width: "100%" }} />
        </div>

        <div className="field">
          <label className="label">Body</label>
          <textarea className="textarea" value={body}
            onChange={e => setBody(e.target.value)}
            placeholder="Body — include dates, contact, sign-up links…"
            rows={5}
            style={{ width: "100%", lineHeight: 1.5 }} />
        </div>

        {/* Where it goes. Two explicit choices rather than a lone checkbox:
            "app only" is a decision too, and should look like one. */}
        <div style={{ marginTop: 4 }}>
          <div className="ui-section-label" style={{ marginBottom: 8 }}>Publish to</div>
          <div style={{ display: "flex", gap: 10, flexWrap: "wrap" }}>
            {[
              { on: false, name: "Parent app only", icon: "phone", hint: "Notices tab + a notification on parents' phones" },
              { on: true,  name: "Parent app + website", icon: "monitor", hint: `Also listed publicly at ${String(window.BRAND.website || "").replace(/^https?:\/\//, "")}/notices` },
            ].map(o => {
              const disabled = o.on && scope !== "school";
              const active = onWebsite === o.on;
              return (
                <label key={String(o.on)} style={{
                  flex: "1 1 260px", display: "flex", gap: 12, alignItems: "flex-start",
                  padding: "14px 16px", borderRadius: "var(--radius-tile)", cursor: disabled ? "not-allowed" : "pointer",
                  border: `1px solid ${active ? "var(--accent)" : "var(--line)"}`,
                  background: active ? "var(--accent-bg)" : "var(--surface)",
                  opacity: disabled ? 0.45 : 1,
                }}>
                  <input type="radio" name="ann-destination" checked={active} disabled={disabled}
                    onChange={() => setOnWebsite(o.on)} style={{ marginTop: 3 }} />
                  <span style={{ minWidth: 0 }}>
                    <span style={{ display: "flex", alignItems: "center", gap: 6, fontSize: 14, color: "var(--ink-0)", fontWeight: 500 }}>
                      <AnnIcon name={o.icon} size={15}/>{o.name}
                    </span>
                    <span className="muted" style={{ display: "block", fontSize: 12.5, marginTop: 3 }}>
                      {disabled ? "School-wide notices only — a class notice is for those families" : o.hint}
                    </span>
                  </span>
                </label>
              );
            })}
          </div>
          {onWebsite && scope === "school" && (
            <div className="ui-alert amber" style={{ marginTop: 10 }}>
              The website is public and searchable. Leave out children's names and personal phone numbers.
            </div>
          )}
        </div>

        <div className="cx-card-foot">
          <span style={{ fontSize: 13, color: "var(--green)" }}>{flash}</span>
          <button type="submit" className="btn primary" disabled={busy}>
            <AnnIcon name="megaphone" size={15}/>{busy ? "Publishing…" : "Publish"}
          </button>
        </div>
      </form>

      {/* History */}
      <div className="cx-card" style={{ marginTop: 20 }}>
        <div className="cx-card-head" style={{ marginBottom: 4 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
            <span className="cx-card-title">Published</span>
            {!loading && <span className="ui-tab-count">{rows.length}</span>}
          </div>
          <button className="btn sm" onClick={load} disabled={loading}>
            <AnnIcon name="refresh" size={14}/>Refresh
          </button>
        </div>
        {loading && <div style={{ padding: "12px 0", color: "var(--ink-3)", fontSize: 13 }}>Loading…</div>}
        {!loading && rows.length === 0 && (
          <window.AppUI.EmptyState compact icon="megaphone" title="Nothing published yet" hint="No announcements published yet."/>
        )}
        <div className="ui-list">
          {rows.map(r => (
            <div key={r.id} className="ui-row" style={{ alignItems: "flex-start", padding: "14px 0", flexWrap: "wrap", rowGap: 8 }}>
              <div className="ui-row-main" style={{ minWidth: 220 }}>
                <div className="ui-row-title" style={{ display: "flex", alignItems: "center", gap: 8, whiteSpace: "normal" }}>
                  {r.title}
                  {r.pinned_until && new Date(r.pinned_until) > new Date() && (
                    <AnnBadge tone="amber" icon="flag">Pinned</AnnBadge>
                  )}
                </div>
                <div className="ui-row-sub" style={{ whiteSpace: "normal", lineHeight: 1.5, marginTop: 4 }}>
                  {r.body.length > 200 ? r.body.slice(0, 200) + "…" : r.body}
                </div>
                <div className="muted" style={{ fontSize: 12, marginTop: 6 }}>
                  by {r.author_name} ({r.author_role}) · <span className="tabular">{fmt(r.published_at)}</span>
                </div>
              </div>
              <div className="ui-row-end" style={{ gap: 8 }}>
                <AnnBadge tone="grey">
                  {r.scope === "school" ? "School-wide" : `${r.audience_count} class${r.audience_count === 1 ? "" : "es"}`}
                </AnnBadge>
                {/* Destination. Clickable for school-wide notices: on/off the
                    website after the fact, without deleting from the app. */}
                {r.scope === "school" ? (
                  <button type="button" onClick={() => setWebsite(r, !r.publish_to_website)}
                    className={`ui-badge ${r.publish_to_website ? "outline green" : "outline grey"}`}
                    title={r.publish_to_website ? "On the public website — click to take it off" : "Parents only — click to also show on the website"}
                    style={{ cursor: "pointer", font: "inherit", fontSize: 12 }}>
                    <AnnIcon name={r.publish_to_website ? "monitor" : "phone"} size={12}/>
                    {r.publish_to_website ? "App + website" : "App only"}
                  </button>
                ) : (
                  <AnnBadge tone="grey" variant="outline" icon="phone">App only</AnnBadge>
                )}
                <window.AppUI.IconButton icon="trash" label="Soft-delete this announcement" size={15} className="sm"
                  onClick={() => remove(r.id, r.title)}/>
              </div>
            </div>
          ))}
        </div>
      </div>
    </div>
    </div>
  );
};

window.AdminAnnouncementsScreen = AdminAnnouncementsScreen;
