"use client";

import { useMemo, useState } from "react";
import { useLang } from "@/context/LanguageContext";
import {
  Alert,
  Button,
  Card,
  DatePicker,
  EmptyState,
  Input,
  Modal,
  PageHeader,
  PageLoader,
  Select,
  StatCard,
  Textarea,
} from "@/components/ui";
import { api, useApi } from "@/lib/client";
import { formatDate } from "@/lib/utils";
import { NOTICE_AUDIENCES } from "@/lib/constants";
import { IconBell, IconEdit, IconPlus, IconSparkle, IconTrash } from "@/components/icons";
import { emsConfirm } from "@/components/ConfirmDialog";

interface NoticeRow {
  id: number;
  title: string;
  titleBn: string | null;
  body: string;
  audience: string;
  publishDate: string;
  expiryDate: string | null;
  isPinned: boolean;
  isActive: boolean;
  expired: boolean;
}

interface NoticesData {
  stats: { total: number; active: number; pinned: number; expired: number };
  notices: NoticeRow[];
}

const emptyForm = {
  title: "",
  titleBn: "",
  body: "",
  audience: "ALL",
  publishDate: "",
  expiryDate: "",
  isPinned: false,
};

/** recipient-group defaults per notice-board audience */
function groupsFor(audience: string): string[] {
  if (audience === "STUDENTS") return ["students", "parents"];
  if (audience === "STAFF") return ["teachers", "staff"];
  return [...ALL_NOTIFY_GROUPS];
}

const ALL_NOTIFY_GROUPS = ["students", "parents", "teachers", "staff"];

export default function PortalNoticesPage() {
  const { t, locale } = useLang();
  const [notifyGroups, setNotifyGroups] = useState<string[]>([...ALL_NOTIFY_GROUPS]);
  const [message, setMessage] = useState<{ type: "success" | "error"; text: string } | null>(null);
  const { data, loading, reload } = useApi<NoticesData>("/api/portal/notices");

  const [formOpen, setFormOpen] = useState(false);
  const [editing, setEditing] = useState<NoticeRow | null>(null);
  const [form, setForm] = useState(emptyForm);
  const [saving, setSaving] = useState(false);
  const [search, setSearch] = useState("");

  const notices = useMemo(() => {
    if (!data) return [];
    const q = search.trim().toLowerCase();
    if (!q) return data.notices;
    return data.notices.filter(
      (n) => n.title.toLowerCase().includes(q) || n.body.toLowerCase().includes(q)
    );
  }, [data, search]);

  function notify(type: "success" | "error", text: string) {
    setMessage({ type, text });
    window.scrollTo({ top: 0, behavior: "smooth" });
  }

  function openCreate() {
    setEditing(null);
    setForm({ ...emptyForm, publishDate: new Date().toISOString().slice(0, 10) });
    setFormOpen(true);
  }

  function openEdit(n: NoticeRow) {
    setEditing(n);
    setForm({
      title: n.title,
      titleBn: n.titleBn ?? "",
      body: n.body,
      audience: NOTICE_AUDIENCES.includes(n.audience as never) ? n.audience : "ALL",
      publishDate: n.publishDate,
      expiryDate: n.expiryDate ?? "",
      isPinned: n.isPinned,
    });
    setFormOpen(true);
  }

  async function save() {
    setSaving(true);
    try {
      if (editing) {
        await api(`/api/portal/notices/${editing.id}`, { method: "PUT", body: JSON.stringify(form) });
        notify("success", t.portal.noticesPage.noticeUpdated);
      } else {
        await api("/api/portal/notices", { method: "POST", body: JSON.stringify({ ...form, notifyGroups }) });
        notify("success", t.portal.noticesPage.noticeCreated);
      }
      setFormOpen(false);
      reload();
    } catch {
      notify("error", t.common.tryAgain);
    } finally {
      setSaving(false);
    }
  }

  async function remove(n: NoticeRow) {
    if (!(await emsConfirm({ message: t.common.confirmDelete, danger: true }))) return;
    try {
      await api(`/api/portal/notices/${n.id}`, { method: "DELETE" });
      notify("success", t.common.deletedSuccessfully);
      reload();
    } catch {
      notify("error", t.common.tryAgain);
    }
  }

  if (loading) return <PageLoader text={t.common.loading} />;
  const s = data?.stats;

  return (
    <div>
      <PageHeader
        title={t.portal.noticesPage.title}
        subtitle={t.portal.noticesPage.subtitle}
        action={
          <Button onClick={openCreate}>
            <IconPlus className="svg-16" />
            <span className="ms-1">{t.portal.noticesPage.newNotice}</span>
          </Button>
        }
      />

      {message && (
        <div className="mb-4">
          <Alert type={message.type} onClose={() => setMessage(null)}>{message.text}</Alert>
        </div>
      )}

      <div className="row g-3 mb-4">
        <div className="col-xl-3 col-sm-6 col-6">
          <StatCard label={t.portal.noticesPage.totalNotices} value={String(s?.total ?? 0)} icon={<IconBell />} accent="teal" />
        </div>
        <div className="col-xl-3 col-sm-6 col-6">
          <StatCard label={t.portal.noticesPage.activeNotices} value={String(s?.active ?? 0)} icon={<IconSparkle />} accent="sky" />
        </div>
        <div className="col-xl-3 col-sm-6 col-6">
          <StatCard label={t.portal.noticesPage.pinnedNotices} value={String(s?.pinned ?? 0)} icon={<IconSparkle />} accent="orange" />
        </div>
        <div className="col-xl-3 col-sm-6 col-6">
          <StatCard label={t.portal.noticesPage.expiredNotices} value={String(s?.expired ?? 0)} icon={<IconBell />} accent="red" />
        </div>
      </div>

      {/* Notice board */}
      {notices.length === 0 ? (
        <div className="card">
          <EmptyState
            icon={<IconBell />}
            title={search ? t.common.noData : t.portal.noticesPage.noNotices}
            action={
              !search ? (
                <Button onClick={openCreate}>
                  <IconPlus className="svg-16" />
                  <span className="ms-1">{t.portal.noticesPage.newNotice}</span>
                </Button>
              ) : undefined
            }
          />
        </div>
      ) : (
        <div className="row g-3">
          {notices.map((n) => (
            <div className="col-xl-6" key={n.id}>
              <Card className={n.isPinned ? "ems-notice-pinned" : undefined}>
                <div className="d-flex justify-content-between align-items-start gap-2">
                  <div className="min-w-0">
                    <h5 className="f-w-700 mb-1 d-flex align-items-center gap-2">
                      {n.isPinned && <IconSparkle className="svg-16 text-warning" />}
                      {n.title}
                      {!n.isActive && (
                        <span className="badge badge-secondary">{t.common.inactive}</span>
                      )}
                    </h5>
                    <p className="mb-2 ems-fs-12 text-muted">
                      {t.portal.noticesPage.published}: {formatDate(n.publishDate, locale)}
                      {n.expiryDate ? ` · ${t.portal.noticesPage.expires}: ${formatDate(n.expiryDate, locale)}` : ""}
                      {n.expired ? ` · ${t.portal.noticesPage.expiredBadge}` : ""}
                    </p>
                  </div>
                  <div className="d-flex flex-shrink-0">
                    <button className="btn btn-soft-secondary btn-sm me-1" onClick={() => openEdit(n)} type="button">
                      <IconEdit className="svg-16" />
                    </button>
                    <button className="btn btn-soft-danger btn-sm" onClick={() => remove(n)} type="button">
                      <IconTrash className="svg-16" />
                    </button>
                  </div>
                </div>
                <p className="mb-0 ems-fs-13" style={{ whiteSpace: "pre-wrap" }}>{n.body}</p>
                <div className="mt-2">
                  <span className="ems-type-pill">{t.noticeAudiences[n.audience as keyof typeof t.noticeAudiences] ?? n.audience}</span>
                </div>
              </Card>
            </div>
          ))}
        </div>
      )}

      {/* Create/edit modal */}
      <Modal
        open={formOpen}
        onClose={() => setFormOpen(false)}
        title={editing ? t.portal.noticesPage.editNotice : t.portal.noticesPage.newNotice}
        wide
      >
        <div className="row">
          <div className="col-md-6">
            <Input label={t.portal.noticesPage.noticeTitle} value={form.title} onChange={(e) => setForm({ ...form, title: e.target.value })} />
          </div>
          <div className="col-md-6">
            <Input label={t.portal.noticesPage.noticeTitleBn} value={form.titleBn} onChange={(e) => setForm({ ...form, titleBn: e.target.value })} />
          </div>
          <div className="col-md-12">
            <Textarea label={t.portal.noticesPage.noticeBody} value={form.body} onChange={(e) => setForm({ ...form, body: e.target.value })} />
          </div>
          <div className="col-md-4">
            <Select label={t.portal.noticesPage.audienceLabel} value={form.audience} onChange={(e) => { setForm({ ...form, audience: e.target.value }); setNotifyGroups(groupsFor(e.target.value)); }}>
              {NOTICE_AUDIENCES.map((a) => (
                <option key={a} value={a}>
                  {t.noticeAudiences[a]}
                </option>
              ))}
            </Select>
          </div>
          <div className="col-md-4">
            <DatePicker label={t.portal.noticesPage.publishDate} value={form.publishDate} onChange={(e) => setForm({ ...form, publishDate: e.target.value })} />
          </div>
          <div className="col-md-4">
            <DatePicker label={`${t.portal.noticesPage.expiryDate} (${t.common.optional})`} value={form.expiryDate} onChange={(e) => setForm({ ...form, expiryDate: e.target.value })} />
          </div>
          <div className="col-md-12">
            <label className="col-form-label pt-0 f-w-600">{t.notifications.pushTo}</label>
            <div className="d-flex flex-wrap gap-3">
              {[["students", t.notifications.groupStudents], ["parents", t.notifications.groupParents], ["teachers", t.notifications.groupTeachers], ["staff", t.notifications.groupStaff]].map(([key, label]) => (
                <div className="form-check" key={key}>
                  <input
                    className="form-check-input"
                    type="checkbox"
                    id={`notice-notify-${key}`}
                    checked={notifyGroups.includes(key)}
                    onChange={(e) =>
                      setNotifyGroups((prev) =>
                        e.target.checked ? [...prev, key] : prev.filter((g) => g !== key)
                      )
                    }
                  />
                  <label className="form-check-label ems-fs-13" htmlFor={`notice-notify-${key}`}>
                    {label}
                  </label>
                </div>
              ))}
            </div>
            <p className="ems-fs-11 text-muted mb-0">{t.notifications.pushTo} — {t.notifications.announcementsHint}</p>
          </div>
          <div className="col-md-12">
            <div className="form-check form-switch d-flex align-items-center gap-2">
              <input
                className="form-check-input"
                type="checkbox"
                role="switch"
                id="notice-pin"
                checked={form.isPinned}
                onChange={(e) => setForm({ ...form, isPinned: e.target.checked })}
              />
              <label className="form-check-label f-w-600" htmlFor="notice-pin">
                {t.portal.noticesPage.pinNotice}
              </label>
            </div>
          </div>
        </div>
        <div className="d-flex justify-content-end gap-2">
          <Button variant="secondary" onClick={() => setFormOpen(false)}>
            {t.common.cancel}
          </Button>
          <Button onClick={save} loading={saving} disabled={!form.title.trim() || !form.body.trim()}>
            {t.common.save}
          </Button>
        </div>
      </Modal>
    </div>
  );
}
