import { createFileRoute } from "@tanstack/react-router";
import { useEffect, useState } from "react";
import { toast } from "sonner";
import { Frame } from "@/components/site/shell";
import { Button, Empty, Field, Input, Select } from "@/components/ui";
import { SignInGate } from "@/lib/auth/gates";
import { changeVisit, deleteMine, exportMine, getMe, getMyVisits, getOpenings, getPreferredLocale, getShell, saveProfile } from "@/lib/clinic/api";
import { LOCALES, formatWhen, type Locale } from "@/lib/clinic/locale";
import type { Visit } from "@/lib/clinic/types";
import { useI18n } from "@/lib/i18n/context";

export const Route = createFileRoute("/portal")({
  loader: async () => getShell({ data: await getPreferredLocale() }),
  component: PortalPage,
});

function PortalPage() {
  const shell = Route.useLoaderData();
  const { t } = useI18n();
  return (
    <Frame shell={shell}>
      <div className="mx-auto max-w-4xl px-4 py-14">
        <p className="text-xs tracking-[0.18em] text-gold-deep uppercase">{t("portal.kicker")}</p>
        <h1 className="mt-3 font-display text-5xl text-forest">{t("portal.title")}</h1>
        <p className="mt-3 text-muted">{t("portal.lead")}</p>
        <div className="mt-8">
          <SignInGate fallback={<a href="/login" className="inline-flex h-11 items-center rounded-full bg-forest px-5 text-ivory">{t("portal.signIn")}</a>}>
            <PortalInner />
          </SignInGate>
        </div>
      </div>
    </Frame>
  );
}

function PortalInner() {
  const { locale, setLocale, t } = useI18n();
  const [visits, setVisits] = useState<Visit[]>([]);
  const [notices, setNotices] = useState<{ id: string; title: string; body: string; channel: string }[]>([]);
  const [profile, setProfile] = useState({ fullName: "", email: "", phone: "", channel: "email", notifyEmail: true, notifySms: false });
  const [moveId, setMoveId] = useState<string | null>(null);
  const [slots, setSlots] = useState<{ start: string; label: string }[]>([]);
  const [date, setDate] = useState("");

  async function refresh() {
    const me = await getMe();
    if (me.patient) {
      setProfile({
        fullName: me.patient.fullName,
        email: me.patient.email,
        phone: me.patient.phone,
        channel: me.patient.channel,
        notifyEmail: me.patient.notifyEmail,
        notifySms: me.patient.notifySms,
      });
    }
    const data = await getMyVisits({ data: locale });
    setVisits(data.visits);
    setNotices(data.notices);
  }

  useEffect(() => { void refresh(); }, [locale]);

  const now = Date.now();
  const upcoming = visits.filter((visit) => new Date(visit.startsAt).getTime() >= now && visit.status !== "cancelled");
  const past = visits.filter((visit) => !upcoming.includes(visit));

  return (
    <div className="grid gap-8">
      <section>
        <h2 className="font-display text-3xl">{t("portal.upcoming")}</h2>
        {!upcoming.length ? <Empty>{t("portal.noneUpcoming")}</Empty> : upcoming.map((visit) => (
          <article key={visit.id} className="mt-3 rounded-xl border border-line p-4">
            <p className="font-mono text-sm">{visit.reference}</p>
            <h3 className="font-display text-2xl">{visit.serviceName}</h3>
            <p>{formatWhen(visit.startsAt, locale)} · {visit.staffName}</p>
            <p className="text-sm text-muted">{t(`status.${visit.status}`)}</p>
            <div className="mt-3 flex gap-2">
              <Button variant="line" onClick={async () => {
                const result = await changeVisit({ data: { id: visit.id, action: "cancel", locale } });
                if (!result.ok) { toast.error(t(`errors.${result.error}`)); return; }
                toast.success(t("portal.cancelOk"));
                void refresh();
              }}>{t("book.cancelVisit")}</Button>
              <Button variant="ghost" onClick={() => { setMoveId(visit.id); setDate(visit.startsAt.slice(0, 10)); }}>{t("portal.move")}</Button>
            </div>
            {moveId === visit.id ? (
              <div className="mt-3">
                <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" onClick={async () => {
                      const result = await changeVisit({ data: { id: visit.id, action: "move", start: slot.start, locale } });
                      if (!result.ok) { toast.error(t(`errors.${result.error}`)); return; }
                      toast.success(t("portal.moved"));
                      setMoveId(null);
                      void refresh();
                    }}>{slot.label}</button>
                  ))}
                </div>
              </div>
            ) : null}
          </article>
        ))}
      </section>
      <section>
        <h2 className="font-display text-3xl">{t("portal.past")}</h2>
        {!past.length ? <Empty>{t("portal.nonePast")}</Empty> : past.map((visit) => (
          <p key={visit.id} className="mt-2 text-sm">{visit.reference} · {visit.serviceName} · {formatWhen(visit.startsAt, locale)} · {t(`status.${visit.status}`)}</p>
        ))}
      </section>
      <section className="rounded-xl bg-paper p-5">
        <h2 className="font-display text-3xl">{t("portal.profile")}</h2>
        <form className="mt-4 grid gap-3" onSubmit={async (event) => {
          event.preventDefault();
          const result = await saveProfile({ data: { ...profile, locale, notifyEmail: profile.notifyEmail, notifySms: profile.notifySms } });
          if (!result.ok) { toast.error(t(`errors.${result.error}`)); return; }
          toast.success(t("common.saved"));
        }}>
          <Field label={t("common.name")}><Input value={profile.fullName} onChange={(event) => setProfile({ ...profile, fullName: event.target.value })} /></Field>
          <Field label={t("common.email")}><Input type="email" value={profile.email} onChange={(event) => setProfile({ ...profile, email: event.target.value })} /></Field>
          <Field label={t("common.phone")}><Input value={profile.phone} onChange={(event) => setProfile({ ...profile, phone: event.target.value })} /></Field>
          <Field label={t("portal.language")}>
            <Select value={locale} onChange={(event) => setLocale(event.target.value as Locale)}>
              {LOCALES.map((code) => <option key={code} value={code}>{code}</option>)}
            </Select>
          </Field>
          <Field label={t("portal.channel")}>
            <Select value={profile.channel} onChange={(event) => setProfile({ ...profile, channel: event.target.value })}>
              <option value="email">{t("contact.emailPref")}</option>
              <option value="phone">{t("contact.phonePref")}</option>
            </Select>
          </Field>
          <label className="flex items-center gap-2 text-sm"><input type="checkbox" checked={profile.notifyEmail} onChange={(event) => setProfile({ ...profile, notifyEmail: event.target.checked })} />{t("portal.notifyEmail")}</label>
          <label className="flex items-center gap-2 text-sm"><input type="checkbox" checked={profile.notifySms} onChange={(event) => setProfile({ ...profile, notifySms: event.target.checked })} />{t("portal.notifySms")}</label>
          <p className="text-xs text-muted">{t("common.previewOnly")}</p>
          <Button type="submit">{t("portal.saveProfile")}</Button>
        </form>
      </section>
      <section>
        <h2 className="font-display text-3xl">{t("portal.prefs")}</h2>
        {notices.map((notice) => (
          <article key={notice.id} className="mt-3 rounded-lg border border-line p-3 text-sm">
            <p className="font-medium">{notice.title}</p>
            <p>{notice.body}</p>
            <p className="text-muted">{notice.channel} · {t("common.previewOnly")}</p>
          </article>
        ))}
      </section>
      <section className="rounded-xl border border-line p-5">
        <h2 className="font-display text-3xl">{t("portal.privacy")}</h2>
        <div className="mt-4 flex flex-wrap gap-3">
          <Button variant="line" onClick={async () => {
            const data = await exportMine();
            const blob = new Blob([JSON.stringify(data, null, 2)], { type: "application/json" });
            const url = URL.createObjectURL(blob);
            const link = document.createElement("a");
            link.href = url;
            link.download = "aurelia-demo-record.json";
            link.click();
            URL.revokeObjectURL(url);
          }}>{t("portal.export")}</Button>
          <Button variant="ghost" onClick={async () => {
            if (!window.confirm(t("portal.deleteWarn"))) return;
            await deleteMine();
            toast.success(t("portal.deleted"));
            void refresh();
          }}>{t("portal.delete")}</Button>
        </div>
      </section>
    </div>
  );
}
