import { createFileRoute, Link } from "@tanstack/react-router";
import { useEffect, useState } from "react";
import { Bar, BarChart, CartesianGrid, ResponsiveContainer, Tooltip, XAxis, YAxis } from "recharts";
import { toast } from "sonner";
import { Studio } from "@/components/admin/studio";
import { Button, Field, Input, Select, TextArea } from "@/components/ui";
import { SignInGate } from "@/lib/auth/gates";
import {
  applyDemoRole,
  askConcierge,
  getAdminAnalytics,
  getAdminAssistant,
  getAdminContent,
  getAdminNotices,
  getAdminOverview,
  getAdminPatients,
  getAdminServices,
  getAdminSettings,
  getAdminTeam,
  getAdminVisits,
  getClinicians,
  getOpenings,
  getPreferredLocale,
  getServices,
  saveAdminAssistant,
  saveAdminContent,
  saveAdminNotice,
  saveAdminPatient,
  saveAdminService,
  saveAdminSettings,
  saveAdminTeam,
  saveAdminVisit,
  uploadSiteFile,
} from "@/lib/clinic/api";
import { LOCALES, formatWhen, type Locale } from "@/lib/clinic/locale";
import { DEMO_CODES } from "@/lib/clinic/logic";
import { useI18n } from "@/lib/i18n/context";

type Section = "overview" | "appointments" | "patients" | "services" | "staff" | "content" | "assistant" | "analytics" | "notifications" | "settings" | "look";

export const Route = createFileRoute("/admin")({
  validateSearch: (search: Record<string, unknown>): { section: Section } => {
    const allowed: Section[] = ["overview", "look", "appointments", "patients", "services", "staff", "content", "assistant", "analytics", "notifications", "settings"];
    const section = typeof search.section === "string" && allowed.includes(search.section as Section) ? search.section as Section : "overview";
    return { section };
  },
  component: AdminPage,
});

function AdminPage() {
  const { section } = Route.useSearch();
  const { t } = useI18n();
  return (
    <SignInGate fallback={<main className="grid min-h-screen place-items-center p-6"><Link to="/login" className="rounded-full bg-forest px-5 py-3 text-ivory">{t("nav.signIn")}</Link></main>}>
      <Desk section={section} />
    </SignInGate>
  );
}

function Desk({ section }: { section: Section }) {
  const { locale, t } = useI18n();
  const navigate = Route.useNavigate();
  const [overview, setOverview] = useState<Awaited<ReturnType<typeof getAdminOverview>> | null>(null);
  const [code, setCode] = useState("AURELIA-OWNER");

  useEffect(() => {
    let live = true;
    getAdminOverview({ data: "" }).then((data) => { if (live) setOverview(data); }).catch(() => { if (live) setOverview({ ok: false, error: "forbidden" }); });
    return () => { live = false; };
  }, [section]);

  if (!overview) return <main className="p-8 text-muted">{t("common.loading")}</main>;
  if (!overview.ok) {
    return (
      <main className="mx-auto max-w-lg px-4 py-16">
        <h1 className="font-display text-4xl text-forest">{t("admin.roleGate")}</h1>
        <p className="mt-3 text-sm text-muted">{t("admin.roleLead")}</p>
        <form className="mt-4 grid gap-3" onSubmit={async (event) => {
          event.preventDefault();
          const result = await applyDemoRole({ data: { code } });
          if (!result.ok) { toast.error(t("admin.badCode")); return; }
          window.location.href = "/admin";
        }}>
          <Field label={t("admin.code")}><Input value={code} onChange={(event) => setCode(event.target.value)} /></Field>
          <ul className="text-sm text-muted">{Object.keys(DEMO_CODES).map((item) => <li key={item}>{item}</li>)}</ul>
          <Button type="submit">{t("admin.applyCode")}</Button>
        </form>
      </main>
    );
  }

  const items: [Section, string, boolean][] = [
    ["overview", t("admin.overview"), true],
    ["look", t("admin.look"), overview.canSettings],
    ["appointments", t("admin.appointments"), true],
    ["patients", t("admin.patients"), overview.canPatients],
    ["services", t("admin.services"), overview.canContent || overview.canPrice],
    ["staff", t("admin.staff"), overview.canStaff],
    ["content", t("admin.content"), overview.canContent],
    ["assistant", t("admin.assistant"), overview.canAssistant],
    ["analytics", t("admin.analytics"), overview.canAnalytics],
    ["notifications", t("admin.notifications"), overview.canNotify],
    ["settings", t("admin.settings"), overview.canSettings],
  ];

  return (
    <div className="min-h-screen bg-ivory text-charcoal md:grid md:grid-cols-[220px_1fr]">
      <aside className="border-b border-line p-4 md:border-e md:border-b-0">
        <p className="text-xs tracking-[0.16em] text-gold-deep uppercase">{t("admin.kicker")}</p>
        <p className="mt-1 text-sm text-muted">{overview.role}</p>
        <nav className="mt-4 grid gap-1">
          {items.filter((item) => item[2]).map(([id, label]) => (
            <button key={id} type="button" className={`h-11 rounded-md px-3 text-start text-sm ${section === id ? "bg-forest text-ivory" : "hover:bg-sage"}`} onClick={() => navigate({ search: { section: id } })}>{label}</button>
          ))}
        </nav>
        <Link to="/" className="mt-6 inline-block text-sm">{t("nav.home")}</Link>
      </aside>
      <main className="p-4 md:p-8">
        <h1 className="font-display text-4xl text-forest">{t("admin.title")}</h1>
        <p className="mt-2 max-w-2xl text-sm text-muted">{t("admin.lead")}</p>
        <div className="mt-6">
          {section === "overview" ? <Overview data={overview} /> : null}
          {section === "look" ? <Studio /> : null}
          {section === "appointments" ? <Visits locale={locale} /> : null}
          {section === "patients" ? <Patients /> : null}
          {section === "services" ? <Services canPrice={overview.canPrice} locale={locale} /> : null}
          {section === "staff" ? <Team /> : null}
          {section === "content" ? <Content locale={locale} /> : null}
          {section === "assistant" ? <Assistant locale={locale} /> : null}
          {section === "analytics" ? <Analytics /> : null}
          {section === "notifications" ? <Notices locale={locale} /> : null}
          {section === "settings" ? <Settings /> : null}
        </div>
      </main>
    </div>
  );
}

function Overview({ data }: { data: Extract<Awaited<ReturnType<typeof getAdminOverview>>, { ok: true }> }) {
  const { t } = useI18n();
  const cards = [
    [t("admin.total"), data.total],
    [t("admin.pending"), data.pending],
    [t("admin.cancelled"), data.cancelled],
    [t("admin.requests"), data.requests],
    [t("admin.conversations"), data.conversations],
  ];
  return (
    <div>
      <div className="grid grid-cols-2 gap-3 md:grid-cols-5">
        {cards.map(([label, value]) => (
          <article key={String(label)} className="rounded-xl bg-paper p-4">
            <p className="text-xs text-muted">{label}</p>
            <p className="font-display text-4xl tabular-nums">{value}</p>
          </article>
        ))}
      </div>
      <h2 className="mt-8 font-display text-2xl">{t("admin.popular")}</h2>
      <ul className="mt-2 text-sm">{data.popular.map((item) => <li key={item.name}>{item.name} · {item.count}</li>)}</ul>
      <h2 className="mt-6 font-display text-2xl">{t("admin.activity")}</h2>
      <ul className="mt-2 text-sm">{data.activity.map((item, index) => <li key={index}>{item.action} · {item.detail}</li>)}</ul>
    </div>
  );
}

function Visits({ locale }: { locale: Locale }) {
  const { t } = useI18n();
  const [status, setStatus] = useState("");
  const [staffId, setStaffId] = useState("");
  const [q, setQ] = useState("");
  const [rows, setRows] = useState<Extract<Awaited<ReturnType<typeof getAdminVisits>>, { ok: true }>["visits"]>([]);
  const [people, setPeople] = useState<{ id: string; name: string; title: string }[]>([]);
  const [services, setServices] = useState<{ id: string; name: string }[]>([]);
  const [patients, setPatients] = useState<{ id: string; name: string }[]>([]);
  const [openId, setOpenId] = useState<string | null>(null);
  const [slots, setSlots] = useState<{ start: string; label: string }[]>([]);
  const [date, setDate] = useState("");
  const [create, setCreate] = useState({ patientId: "", staffId: "", serviceId: "", date: "", start: "" });
  const [createSlots, setCreateSlots] = useState<{ start: string; label: string }[]>([]);

  async function load() {
    const data = await getAdminVisits({ data: { status, staffId, q, locale } });
    if (data.ok) setRows(data.visits);
    else toast.error(t("admin.noAccess"));
  }
  useEffect(() => { void load(); }, [status, staffId, locale]);
  useEffect(() => {
    void Promise.all([getClinicians({ data: locale }), getServices({ data: locale }), getAdminPatients({ data: { q: "" } })]).then(([staff, catalog, patientData]) => {
      setPeople(staff.map((person) => ({ id: person.id, name: person.name, title: person.title })));
      setServices(catalog.services.filter((item) => item.bookable).map((item) => ({ id: item.id, name: item.name })));
      if (patientData.ok) setPatients(patientData.patients.map((item) => ({ id: item.id, name: item.name })));
    });
  }, [locale]);

  return (
    <div>
      <div className="flex flex-wrap gap-2">
        <Input placeholder={t("admin.searchPh")} value={q} onChange={(event) => setQ(event.target.value)} className="max-w-xs" />
        <Button variant="line" onClick={() => void load()}>{t("common.search")}</Button>
        <Select value={status} onChange={(event) => setStatus(event.target.value)} className="max-w-40">
          <option value="">{t("common.all")}</option>
          {["pending", "confirmed", "cancelled", "completed", "no_show"].map((item) => <option key={item} value={item}>{t(`status.${item}`)}</option>)}
        </Select>
        <Select value={staffId} onChange={(event) => setStaffId(event.target.value)} className="max-w-48">
          <option value="">{t("book.stepStaff")}</option>
          {people.map((person) => <option key={person.id} value={person.id}>{person.name}</option>)}
        </Select>
      </div>
      <form className="mt-4 grid gap-2 rounded-xl bg-paper p-4 md:grid-cols-2" onSubmit={async (event) => {
        event.preventDefault();
        const result = await saveAdminVisit({ data: { action: "create", patientId: create.patientId, staffId: create.staffId, serviceId: create.serviceId, start: create.start } });
        if (!result.ok) { toast.error(t(`errors.${result.error}`)); return; }
        toast.success(t("common.saved"));
        setCreate({ ...create, start: "" });
        void load();
      }}>
        <h2 className="font-display text-2xl md:col-span-2">{t("common.create")}</h2>
        <Select value={create.patientId} onChange={(event) => setCreate({ ...create, patientId: event.target.value })} required>
          <option value="">{t("admin.patients")}</option>
          {patients.map((item) => <option key={item.id} value={item.id}>{item.name}</option>)}
        </Select>
        <Select value={create.serviceId} onChange={(event) => setCreate({ ...create, serviceId: event.target.value, start: "" })} required>
          <option value="">{t("book.stepService")}</option>
          {services.map((item) => <option key={item.id} value={item.id}>{item.name}</option>)}
        </Select>
        <Select value={create.staffId} onChange={(event) => setCreate({ ...create, staffId: event.target.value, start: "" })} required>
          <option value="">{t("book.stepStaff")}</option>
          {people.map((person) => <option key={person.id} value={person.id}>{person.name}</option>)}
        </Select>
        <Input type="date" required value={create.date} onChange={async (event) => {
          const value = event.target.value;
          setCreate({ ...create, date: value, start: "" });
          if (!create.staffId || !create.serviceId) return;
          const open = await getOpenings({ data: { staffId: create.staffId, serviceId: create.serviceId, date: value } });
          setCreateSlots(open.slots);
        }} />
        <div className="flex flex-wrap gap-2 md:col-span-2">
          {createSlots.map((slot) => (
            <button key={slot.start} type="button" className={`h-11 rounded-md border px-3 tabular-nums ${create.start === slot.start ? "border-forest bg-forest text-ivory" : "border-line"}`} onClick={() => setCreate({ ...create, start: slot.start })}>{slot.label}</button>
          ))}
        </div>
        <Button type="submit" disabled={!create.start}>{t("common.confirm")}</Button>
      </form>
      <div className="mt-4 overflow-x-auto">
        <table className="w-full text-sm">
          <thead><tr className="text-start text-muted"><th>{t("book.reference")}</th><th>{t("common.name")}</th><th>{t("common.date")}</th><th>{t("common.status")}</th><th>{t("common.actions")}</th></tr></thead>
          <tbody>
            {rows.map((visit) => (
              <tr key={visit.id} className="border-t border-line align-top">
                <td className="py-2 font-mono">{visit.reference}</td>
                <td>{visit.patientName}<span className="block text-muted">{visit.staffName}</span></td>
                <td className="tabular-nums">{formatWhen(visit.startsAt, locale)}</td>
                <td>{t(`status.${visit.status}`)}</td>
                <td className="py-2">
                  <div className="flex flex-wrap gap-2">
                    <button type="button" className="underline" onClick={async () => { await saveAdminVisit({ data: { action: "confirm", id: visit.id } }); void load(); }}>{t("admin.confirm")}</button>
                    <button type="button" className="underline" onClick={async () => { await saveAdminVisit({ data: { action: "cancel", id: visit.id } }); toast.success(t("portal.cancelOk")); void load(); }}>{t("admin.cancelAppt")}</button>
                    <button type="button" className="underline" onClick={() => { setOpenId(openId === visit.id ? null : visit.id); setDate(visit.startsAt.slice(0, 10)); setSlots([]); }}>{t("portal.move")}</button>
                  </div>
                  <form className="mt-2 flex gap-2" onSubmit={async (event) => {
                    event.preventDefault();
                    const note = (event.currentTarget.elements.namedItem("note") as HTMLTextAreaElement).value;
                    const result = await saveAdminVisit({ data: { action: "note", id: visit.id, note } });
                    if (!result.ok) toast.error(t(`errors.${result.error}`));
                    else toast.success(t("common.saved"));
                  }}>
                    <TextArea name="note" defaultValue={visit.internalNotes} className="min-h-16" aria-label={t("admin.patientNotes")} />
                    <Button type="submit" variant="line">{t("common.save")}</Button>
                  </form>
                  {openId === visit.id ? (
                    <div className="mt-2">
                      <Input type="date" value={date} onChange={async (event) => {
                        const value = event.target.value;
                        setDate(value);
                        const open = await getOpenings({ data: { staffId: visit.staffId, serviceId: visit.serviceId, date: value, excludeId: visit.id } });
                        setSlots(open.slots);
                      }} />
                      <div className="mt-2 flex flex-wrap gap-2">
                        {slots.map((slot) => (
                          <button key={slot.start} type="button" className="h-11 rounded-md border border-line px-3 tabular-nums" onClick={async () => {
                            const result = await saveAdminVisit({ data: { action: "move", id: visit.id, start: slot.start } });
                            if (!result.ok) { toast.error(t(`errors.${result.error}`)); return; }
                            toast.success(t("portal.moved"));
                            setOpenId(null);
                            void load();
                          }}>{slot.label}</button>
                        ))}
                      </div>
                    </div>
                  ) : null}
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}

function Patients() {
  const { t } = useI18n();
  const [q, setQ] = useState("");
  const [rows, setRows] = useState<{ id: string; name: string; email: string; phone: string; notes: string; status: string }[]>([]);
  async function load() {
    const data = await getAdminPatients({ data: { q } });
    if (data.ok) setRows(data.patients);
    else toast.error(t("admin.noAccess"));
  }
  useEffect(() => { void load(); }, []);
  return (
    <div>
      <div className="flex gap-2">
        <Input value={q} onChange={(event) => setQ(event.target.value)} placeholder={t("common.search")} />
        <Button variant="line" onClick={() => void load()}>{t("common.search")}</Button>
      </div>
      <div className="mt-4 grid gap-3">
        {rows.map((patient) => (
          <article key={patient.id} className="rounded-xl border border-line p-4">
            <h3 className="font-display text-2xl">{patient.name}</h3>
            <p className="text-sm text-muted">{patient.email} · {patient.phone}</p>
            <TextArea className="mt-2" defaultValue={patient.notes} id={`n-${patient.id}`} />
            <div className="mt-2 flex gap-2">
              <Button variant="line" onClick={async () => {
                const notes = (document.getElementById(`n-${patient.id}`) as HTMLTextAreaElement).value;
                await saveAdminPatient({ data: { id: patient.id, notes, status: patient.status } });
                toast.success(t("common.saved"));
              }}>{t("common.save")}</Button>
              <Button variant="ghost" onClick={async () => {
                await saveAdminPatient({ data: { id: patient.id, notes: "", status: "inactive", anonymise: true } });
                toast.success(t("portal.deleted"));
                void load();
              }}>{t("admin.anonymise")}</Button>
            </div>
          </article>
        ))}
      </div>
    </div>
  );
}

function Services({ canPrice, locale }: { canPrice: boolean; locale: Locale }) {
  const { t } = useI18n();
  const [rows, setRows] = useState<Extract<Awaited<ReturnType<typeof getAdminServices>>, { ok: true }>["services"]>([]);
  const [edit, setEdit] = useState<string>("");
  useEffect(() => { void getAdminServices({ data: "" }).then((data) => { if (data.ok) setRows(data.services); }); }, []);
  const current = rows.find((row) => row.id === edit) ?? rows[0];
  const [lang, setLang] = useState<Locale>(locale);
  if (!current) return null;
  const copy = current.translations[lang] ?? { name: "", description: "", preparation: "" };
  return (
    <div className="grid gap-4">
      <p className="text-sm text-muted">{t("admin.publishNow")}</p>
      <Select value={current.id} onChange={(event) => setEdit(event.target.value)}>
        {rows.map((row) => <option key={row.id} value={row.id}>{row.translations.en?.name ?? row.slug}</option>)}
      </Select>
      <Select value={lang} onChange={(event) => setLang(event.target.value as Locale)}>
        {LOCALES.map((code) => <option key={code} value={code}>{code}</option>)}
      </Select>
      <ServiceForm key={`${current.id}-${lang}`} canPrice={canPrice} service={current} copy={copy} lang={lang} onSaved={() => void getAdminServices({ data: "" }).then((data) => { if (data.ok) setRows(data.services); })} />
    </div>
  );
}

function ServiceForm({ canPrice, service, copy, lang, onSaved }: { canPrice: boolean; service: { id: string; priceCents: number; durationMin: number; active: boolean; bookable: boolean; image: string }; copy: { name: string; description: string; preparation: string }; lang: Locale; onSaved: () => void }) {
  const { t } = useI18n();
  const [name, setName] = useState(copy.name);
  const [description, setDescription] = useState(copy.description);
  const [preparation, setPreparation] = useState(copy.preparation);
  const [price, setPrice] = useState(String(service.priceCents / 100));
  const [duration, setDuration] = useState(String(service.durationMin));
  const [active, setActive] = useState(service.active);
  const [bookable, setBookable] = useState(service.bookable);
  const [image, setImage] = useState(service.image);
  return (
    <form className="grid gap-3" onSubmit={async (event) => {
      event.preventDefault();
      const result = await saveAdminService({ data: { id: service.id, locale: lang, name, description, preparation, priceEuros: Number(price), durationMin: Number(duration), active, bookable, image } });
      if (!result.ok) { toast.error(t(`errors.${result.error}`)); return; }
      toast.success(t("common.saved"));
      onSaved();
    }}>
      <Field label={t("admin.image")}>
        <img src={image} alt="" className="aspect-square w-28 rounded-2xl object-cover" />
        {canPrice ? <input type="file" accept="image/jpeg,image/png,image/webp" onChange={async (event) => {
          const file = event.target.files?.[0];
          event.target.value = "";
          if (!file || file.size > 1_200_000) { toast.error(t("errors.invalid")); return; }
          const bytes = new Uint8Array(await file.arrayBuffer());
          let binary = "";
          for (let i = 0; i < bytes.length; i += 0x8000) binary += String.fromCharCode(...bytes.subarray(i, i + 0x8000));
          const uploaded = await uploadSiteFile({ data: { data: btoa(binary), kind: "image" } });
          if (!uploaded.ok) { toast.error(t(`errors.${uploaded.error}`)); return; }
          setImage(uploaded.url);
        }} /> : null}
      </Field>
      <Field label={t("common.name")}><Input value={name} onChange={(event) => setName(event.target.value)} /></Field>
      <Field label={t("admin.description")}><TextArea value={description} onChange={(event) => setDescription(event.target.value)} /></Field>
      <Field label={t("admin.preparation")}><TextArea value={preparation} onChange={(event) => setPreparation(event.target.value)} /></Field>
      {canPrice ? (
        <>
          <Field label={t("admin.price")}><Input value={price} onChange={(event) => setPrice(event.target.value)} /></Field>
          <Field label={t("admin.duration")}><Input value={duration} onChange={(event) => setDuration(event.target.value)} /></Field>
          <label className="text-sm"><input type="checkbox" checked={active} onChange={(event) => setActive(event.target.checked)} /> {t("admin.active")}</label>
          <label className="text-sm"><input type="checkbox" checked={bookable} onChange={(event) => setBookable(event.target.checked)} /> {t("admin.bookable")}</label>
        </>
      ) : null}
      <Button type="submit">{t("common.save")}</Button>
    </form>
  );
}

function Team() {
  const { t } = useI18n();
  const [data, setData] = useState<Extract<Awaited<ReturnType<typeof getAdminTeam>>, { ok: true }> | null>(null);
  const [day, setDay] = useState("1");
  const [label, setLabel] = useState("Closure");
  const [date, setDate] = useState("");
  async function load() {
    const next = await getAdminTeam({ data: "" });
    if (next.ok) setData(next);
  }
  useEffect(() => { void load(); }, []);
  if (!data) return null;
  return (
    <div className="grid gap-4">
      {data.people.map((person) => (
        <article key={String(person.id)} className="rounded-xl border border-line p-4">
          <h3 className="font-display text-2xl">{String(person.name)}</h3>
          <label className="text-sm"><input type="checkbox" defaultChecked={Boolean(person.active)} onChange={async (event) => { await saveAdminTeam({ data: { staffId: String(person.id), active: event.target.checked } }); toast.success(t("common.saved")); }} /> {t("admin.active")}</label>
        </article>
      ))}
      <form className="grid gap-2 rounded-xl bg-paper p-4" onSubmit={async (event) => {
        event.preventDefault();
        await saveAdminTeam({ data: { holiday: date, holidayLabel: label } });
        toast.success(t("common.saved"));
        void load();
      }}>
        <h3 className="font-display text-2xl">{t("admin.holiday")}</h3>
        <Input type="date" required value={date} onChange={(event) => setDate(event.target.value)} />
        <Input value={label} onChange={(event) => setLabel(event.target.value)} />
        <Button type="submit">{t("admin.addHoliday")}</Button>
        <ul className="text-sm">{data.holidays.map((holiday) => (
          <li key={String(holiday.id)} className="flex justify-between gap-2">{String(holiday.day)} {String(holiday.label)}
            <button type="button" onClick={async () => { await saveAdminTeam({ data: { removeHoliday: String(holiday.id) } }); void load(); }}>{t("common.remove")}</button>
          </li>
        ))}</ul>
      </form>
      <form className="grid gap-2" onSubmit={async (event) => {
        event.preventDefault();
        const staffId = String(data.people[0]?.id ?? "");
        await saveAdminTeam({ data: { staffId, weekday: Number(day), startMin: 9 * 60, endMin: 13 * 60 } });
        toast.success(t("common.saved"));
      }}>
        <h3 className="font-display text-2xl">{t("admin.hoursWindows")}</h3>
        <Select value={day} onChange={(event) => setDay(event.target.value)}>
          {[0, 1, 2, 3, 4, 5, 6].map((value) => <option key={value} value={value}>{t(`weekdays.d${value}`)}</option>)}
        </Select>
        <Button type="submit">{t("common.add")}</Button>
      </form>
    </div>
  );
}

function Content({ locale }: { locale: Locale }) {
  const { t } = useI18n();
  const [doc, setDoc] = useState<Record<string, { heroTitle?: string; heroLead?: string; hours?: string; visitNote?: string }>>({});
  const [faqs, setFaqs] = useState<{ id: string; locale: string; question: string; answer: string }[]>([]);
  const [lang, setLang] = useState<Locale>(locale);
  useEffect(() => {
    void getAdminContent({ data: "" }).then((data) => {
      if (!data.ok || !data.document) return;
      const published = (data.document as { published?: Record<string, { heroTitle?: string; heroLead?: string; hours?: string; visitNote?: string }> }).published ?? {};
      setDoc(published);
      setFaqs((data.faqs as { id: string; locale: string; question: string; answer: string }[]) ?? []);
    });
  }, []);
  const block = doc[lang] ?? { heroTitle: "", heroLead: "", hours: "", visitNote: "" };
  return (
    <div className="grid gap-4">
      <Select value={lang} onChange={(event) => setLang(event.target.value as Locale)}>{LOCALES.map((code) => <option key={code}>{code}</option>)}</Select>
      <form className="grid gap-3" onSubmit={async (event) => {
        event.preventDefault();
        await saveAdminContent({ data: { action: "draft", locale: lang, patch: { heroTitle: block.heroTitle, heroLead: block.heroLead, hours: block.hours, visitNote: block.visitNote } } });
        await saveAdminContent({ data: { action: "publish" } });
        toast.success(t("admin.publishedOk"));
      }}>
        <Field label={t("home.title")}><Input value={block.heroTitle ?? ""} onChange={(event) => setDoc({ ...doc, [lang]: { ...block, heroTitle: event.target.value } })} /></Field>
        <Field label={t("home.lead")}><TextArea value={block.heroLead ?? ""} onChange={(event) => setDoc({ ...doc, [lang]: { ...block, heroLead: event.target.value } })} /></Field>
        <Field label={t("contact.hours")}><Input value={block.hours ?? ""} onChange={(event) => setDoc({ ...doc, [lang]: { ...block, hours: event.target.value } })} /></Field>
        <Field label={t("admin.clinicInfo")}><TextArea value={block.visitNote ?? ""} onChange={(event) => setDoc({ ...doc, [lang]: { ...block, visitNote: event.target.value } })} /></Field>
        <div className="flex gap-2">
          <Button type="submit">{t("admin.publish")}</Button>
          <Button type="button" variant="line" onClick={async () => { await saveAdminContent({ data: { action: "rollback" } }); toast.success(t("admin.rolled")); }}>{t("common.rollback")}</Button>
        </div>
      </form>
      {faqs.filter((item) => item.locale === lang).map((item) => (
        <form key={`${item.id}-${item.locale}`} className="grid gap-3 rounded-xl border border-line p-4" onSubmit={async (event) => {
          event.preventDefault();
          await saveAdminContent({ data: { faqId: item.id, locale: lang, question: item.question, answer: item.answer } });
          toast.success(t("common.saved"));
        }}>
          <h3 className="font-display text-2xl">{t("nav.faq")}</h3>
          <Field label={t("admin.question")}><Input value={item.question} onChange={(event) => setFaqs(faqs.map((row) => row === item ? { ...row, question: event.target.value } : row))} /></Field>
          <Field label={t("admin.answer")}><TextArea value={item.answer} onChange={(event) => setFaqs(faqs.map((row) => row === item ? { ...row, answer: event.target.value } : row))} /></Field>
          <Button type="submit">{t("common.save")}</Button>
        </form>
      ))}
    </div>
  );
}

function Assistant({ locale }: { locale: Locale }) {
  const { t } = useI18n();
  const [question, setQuestion] = useState("");
  const [answer, setAnswer] = useState("");
  const [knowledge, setKnowledge] = useState<{ id: string; locale: string; title: string; body: string }[]>([]);
  const [voice, setVoice] = useState({ voice: "", forbidden: "", escalation: "", allowed: "" });
  useEffect(() => {
    void getAdminAssistant({ data: "" }).then((data) => {
      if (!data.ok) return;
      setKnowledge(data.knowledge.map((row) => ({ id: row.id, locale: row.locale, title: row.title, body: row.body })));
      if (data.settings) setVoice({ voice: data.settings.voice, forbidden: data.settings.forbidden, escalation: data.settings.escalation, allowed: data.settings.allowed });
    });
  }, []);
  const item = knowledge.find((row) => row.locale === locale) ?? knowledge[0];
  return (
    <div className="grid gap-4">
      <form className="grid gap-3 rounded-xl border border-line p-4" onSubmit={async (event) => {
        event.preventDefault();
        await saveAdminAssistant({ data: voice });
        toast.success(t("common.saved"));
      }}>
        <Field label={t("admin.voice")}><TextArea value={voice.voice} onChange={(event) => setVoice({ ...voice, voice: event.target.value })} /></Field>
        <Field label={t("admin.allowed")}><TextArea value={voice.allowed} onChange={(event) => setVoice({ ...voice, allowed: event.target.value })} /></Field>
        <Field label={t("admin.forbidden")}><TextArea value={voice.forbidden} onChange={(event) => setVoice({ ...voice, forbidden: event.target.value })} /></Field>
        <Field label={t("admin.escalation")}><TextArea value={voice.escalation} onChange={(event) => setVoice({ ...voice, escalation: event.target.value })} /></Field>
        <Button type="submit">{t("common.save")}</Button>
      </form>
      {item ? (
        <form className="grid gap-3" onSubmit={async (event) => {
          event.preventDefault();
          await saveAdminAssistant({ data: { itemId: item.id, locale: item.locale, title: item.title, body: item.body, active: true } });
          toast.success(t("common.saved"));
        }}>
          <Field label={t("admin.knowledge")}><Input value={item.title} onChange={(event) => setKnowledge(knowledge.map((row) => row === item ? { ...row, title: event.target.value } : row))} /></Field>
          <TextArea value={item.body} onChange={(event) => setKnowledge(knowledge.map((row) => row === item ? { ...row, body: event.target.value } : row))} />
          <Button type="submit">{t("common.save")}</Button>
        </form>
      ) : null}
      <form className="grid gap-3" onSubmit={async (event) => {
        event.preventDefault();
        const result = await askConcierge({ data: { locale, message: question } });
        if (result.ok) setAnswer(`${result.text}\n\n${result.mode}`);
      }}>
        <h3 className="font-display text-2xl">{t("admin.testSandbox")}</h3>
        <TextArea value={question} onChange={(event) => setQuestion(event.target.value)} />
        <Button type="submit">{t("admin.ask")}</Button>
        {answer ? <p className="whitespace-pre-wrap rounded-lg bg-paper p-3 text-sm">{answer}</p> : null}
      </form>
    </div>
  );
}

function Analytics() {
  const { t } = useI18n();
  const [data, setData] = useState<Extract<Awaited<ReturnType<typeof getAdminAnalytics>>, { ok: true }> | null>(null);
  useEffect(() => { void getAdminAnalytics({ data: "" }).then((next) => { if (next.ok) setData(next); }); }, []);
  if (!data) return <p>{t("common.loading")}</p>;
  return (
    <div className="grid gap-6">
      <p className="text-sm text-muted">{t("admin.chartsNote")}</p>
      <p className="tabular-nums">{t("admin.cancelRate")}: {data.cancelRate}% · {t("admin.conversion")}: {data.conversion}%</p>
      <div className="h-64">
        <ResponsiveContainer width="100%" height="100%">
          <BarChart data={data.byDay}>
            <CartesianGrid stroke="#d9d3c5" vertical={false} />
            <XAxis dataKey="day" hide />
            <YAxis allowDecimals={false} />
            <Tooltip />
            <Bar dataKey="count" fill="#183735" />
          </BarChart>
        </ResponsiveContainer>
      </div>
      <h3 className="font-display text-2xl">{t("admin.byService")}</h3>
      <ul className="text-sm">{data.byService.map((item) => <li key={item.name}>{item.name} · {item.count}</li>)}</ul>
      <h3 className="font-display text-2xl">{t("admin.languages")}</h3>
      <ul className="text-sm">{data.languages.map((item) => <li key={item.locale}>{item.locale} · {item.count}</li>)}</ul>
      <h3 className="font-display text-2xl">{t("admin.staffActivity")}</h3>
      <ul className="text-sm">{data.staff.map((item) => <li key={item.name}>{item.name} · {item.count}</li>)}</ul>
      <h3 className="font-display text-2xl">{t("admin.sources")}</h3>
      <ul className="text-sm">{data.sources.map((item) => <li key={item.source}>{item.source} · {item.count}</li>)}</ul>
    </div>
  );
}

function Notices({ locale }: { locale: Locale }) {
  const { t } = useI18n();
  const [sample, setSample] = useState<{ title?: string; body?: string } | null>(null);
  const [requests, setRequests] = useState<{ id: string; name: string; message: string; status: string }[]>([]);
  useEffect(() => {
    void getAdminNotices({ data: { locale } }).then((data) => {
      if (!data.ok) return;
      setSample(data.sample as { title?: string; body?: string } | null);
      setRequests((data.requests as { id: string; name: string; message: string; status: string }[]) ?? []);
    });
  }, [locale]);
  return (
    <div className="grid gap-4">
      <p className="text-sm text-muted">{t("common.previewOnly")}</p>
      {sample ? <article className="rounded-xl bg-paper p-4"><h3 className="font-display text-2xl">{String(sample.title)}</h3><p className="mt-2 whitespace-pre-wrap">{String(sample.body)}</p></article> : null}
      {requests.map((request) => (
        <article key={request.id} className="rounded-lg border border-line p-3 text-sm">
          <p className="font-medium">{request.name}</p>
          <p>{request.message}</p>
          <button type="button" className="mt-2 underline" onClick={async () => { await saveAdminNotice({ data: { requestId: request.id, status: "read" } }); toast.success(t("common.saved")); }}>{t("admin.markRead")}</button>
        </article>
      ))}
    </div>
  );
}

function Settings() {
  const { t } = useI18n();
  const [address, setAddress] = useState("");
  const [phone, setPhone] = useState("");
  const [email, setEmail] = useState("");
  const [city, setCity] = useState("");
  const [gold, setGold] = useState("#C2A878");
  const [horizon, setHorizon] = useState("60");
  useEffect(() => {
    void getAdminSettings({ data: "" }).then((data) => {
      if (!data.ok || !data.tenant) return;
      const tenant = data.tenant as { address?: string; phone?: string; email?: string; city?: string; theme?: { gold?: string }; settings?: { horizonDays?: number } };
      setAddress(String(tenant.address ?? ""));
      setPhone(String(tenant.phone ?? ""));
      setEmail(String(tenant.email ?? ""));
      setCity(String(tenant.city ?? ""));
      setGold(tenant.theme?.gold ?? "#C2A878");
      setHorizon(String(tenant.settings?.horizonDays ?? 60));
    });
  }, []);
  return (
    <form className="grid max-w-lg gap-3" onSubmit={async (event) => {
      event.preventDefault();
      const result = await saveAdminSettings({ data: { address, phone, email, city, horizonDays: Number(horizon), theme: { gold } } });
      if (!result.ok) { toast.error(t(`errors.${result.error}`)); return; }
      toast.success(t("common.saved"));
    }}>
      <Field label={t("contact.address")}><Input value={address} onChange={(event) => setAddress(event.target.value)} /></Field>
      <Field label={t("platform.city")}><Input value={city} onChange={(event) => setCity(event.target.value)} /></Field>
      <Field label={t("common.phone")}><Input value={phone} onChange={(event) => setPhone(event.target.value)} /></Field>
      <Field label={t("common.email")}><Input value={email} onChange={(event) => setEmail(event.target.value)} /></Field>
      <Field label={t("admin.theme")}><Input value={gold} onChange={(event) => setGold(event.target.value)} /></Field>
      <Field label={t("admin.horizon")}><Input value={horizon} onChange={(event) => setHorizon(event.target.value)} /></Field>
      <Button type="submit">{t("admin.saveSettings")}</Button>
    </form>
  );
}
