import { createFileRoute, useRouter } from "@tanstack/react-router";
import { useServerFn } from "@tanstack/react-start";
import { useState, type FormEvent } from "react";
import { toast } from "sonner";
import { LogOut, Plus, Trash2, X } from "lucide-react";
import type { Database } from "@/integrations/supabase/types";
import {
  adminLogin,
  adminLogout,
  deleteBlogPost,
  deleteBook,
  deleteEnquiry,
  deleteEvent,
  deleteSubscriber,
  deleteTestimonial,
  deleteVideo,
  getAdminState,
  saveBlogPost,
  saveBook,
  saveEvent,
  saveTestimonial,
  saveVideo,
} from "@/lib/admin.functions";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Switch } from "@/components/ui/switch";
import { Textarea } from "@/components/ui/textarea";
import { LogoMark } from "@/components/brand/Logo";
import { cn } from "@/lib/utils";
import { formatAdminEventDate } from "@/lib/event-date";

export const Route = createFileRoute("/admin")({
  loader: () => getAdminState(),
  head: () => ({
    meta: [{ title: "Admin — Eva Shii Jason" }, { name: "robots", content: "noindex" }],
  }),
  component: AdminPage,
});

type BookRow = Database["public"]["Tables"]["books"]["Row"];
type EventRow = Database["public"]["Tables"]["events"]["Row"];
type VideoRow = Database["public"]["Tables"]["videos"]["Row"];
type TestimonialRow = Database["public"]["Tables"]["testimonials"]["Row"];
type EnquiryRow = Database["public"]["Tables"]["speaking_enquiries"]["Row"];
type PostRow = Database["public"]["Tables"]["blog_posts"]["Row"];
type SubscriberRow = Database["public"]["Tables"]["newsletter_subscribers"]["Row"];

type AdminState = Awaited<ReturnType<typeof getAdminState>>;

/* ---------- Login gate ---------- */

function LoginGate() {
  const router = useRouter();
  const loginFn = useServerFn(adminLogin);
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState(false);

  async function onSubmit(e: FormEvent<HTMLFormElement>) {
    e.preventDefault();
    const password = String(new FormData(e.currentTarget).get("password") ?? "");
    setBusy(true);
    try {
      const res = await loginFn({ data: { password } });
      if (res.ok) {
        await router.invalidate();
      } else {
        setError(true);
      }
    } catch {
      setError(true);
    }
    setBusy(false);
  }

  return (
    <div className="flex min-h-[70vh] items-center justify-center px-4">
      <form
        onSubmit={onSubmit}
        className="w-full max-w-sm rounded-2xl border border-gold/30 bg-card p-8 text-center"
      >
        <LogoMark className="mx-auto h-16 w-16 text-3xl" />
        <h1 className="mt-5 font-display text-2xl text-jungle">Admin</h1>
        <p className="mt-2 text-sm text-muted-foreground">Enter the admin password to manage content.</p>
        <Input
          name="password"
          type="password"
          required
          autoComplete="current-password"
          placeholder="Password"
          className="mt-6"
        />
        {error ? <p className="mt-3 text-sm text-destructive">Incorrect password.</p> : null}
        <Button type="submit" variant="green" className="mt-5 w-full" disabled={busy}>
          {busy ? "Checking…" : "Unlock"}
        </Button>
      </form>
    </div>
  );
}

/* ---------- Shared row shell ---------- */

function EditorCard({
  title,
  editing,
  onClose,
  children,
  onSubmit,
  busy,
}: {
  title: string;
  editing: boolean;
  onClose: () => void;
  children: React.ReactNode;
  onSubmit: (e: FormEvent) => void;
  busy: boolean;
}) {
  return (
    <form
      onSubmit={onSubmit}
      className={cn(
        "grid gap-4 rounded-2xl border p-6",
        editing ? "border-gold/50 bg-terra-soft" : "border-gold/25 bg-card",
      )}
    >
      <div className="flex items-center justify-between">
        <h3 className="font-display text-lg text-jungle">{title}</h3>
        {editing ? (
          <button
            type="button"
            onClick={onClose}
            aria-label="Close editor"
            className="text-muted-foreground hover:text-foreground"
          >
            <X className="h-4 w-4" />
          </button>
        ) : null}
      </div>
      {children}
      <Button
        type="submit"
        variant="green"
        size="sm"
        className="justify-self-start rounded-full"
        disabled={busy}
      >
        {busy ? "Saving…" : "Save"}
      </Button>
    </form>
  );
}

/* ---------- Books ---------- */

function BooksAdmin({ books }: { books: BookRow[] }) {
  const router = useRouter();
  const saveFn = useServerFn(saveBook);
  const deleteFn = useServerFn(deleteBook);
  const [draft, setDraft] = useState<Partial<BookRow> | null>(null);
  const [busy, setBusy] = useState(false);

  async function submit(e: FormEvent) {
    e.preventDefault();
    if (!draft) return;
    setBusy(true);
    const res = await saveFn({
      data: {
        id: (draft.id ?? "") as string,
        title: draft.title ?? "",
        subtitle: draft.subtitle ?? "",
        description: draft.description ?? "",
        category: draft.category ?? "",
        cover_image_url: draft.cover_image_url ?? "",
        purchase_url: draft.purchase_url ?? "",
        featured: draft.featured ?? false,
        sort_order: Number(draft.sort_order ?? 0),
      },
    });
    setBusy(false);
    if (!res.ok) {
      toast.error(res.error);
      return;
    }
    toast.success("Book saved.");
    setDraft(null);
    await router.invalidate();
  }

  async function del(id: string) {
    const res = await deleteFn({ data: { id } });
    if (!res.ok) {
      toast.error(res.error);
      return;
    }
    toast.success("Book deleted.");
    await router.invalidate();
  }

  return (
    <div className="grid gap-6">
      <Button
        variant="gold"
        size="sm"
        className="justify-self-start rounded-full"
        onClick={() => setDraft({ sort_order: books.length + 1 })}
      >
        <Plus className="h-4 w-4" /> Add book
      </Button>
      {draft ? (
        <EditorCard
          title={draft.id ? "Edit book" : "New book"}
          editing={!!draft.id}
          onClose={() => setDraft(null)}
          onSubmit={submit}
          busy={busy}
        >
          <div className="grid gap-4 sm:grid-cols-2">
            <div className="grid gap-2">
              <Label>Title</Label>
              <Input value={draft.title ?? ""} onChange={(e) => setDraft({ ...draft, title: e.target.value })} required />
            </div>
            <div className="grid gap-2">
              <Label>Subtitle</Label>
              <Input value={draft.subtitle ?? ""} onChange={(e) => setDraft({ ...draft, subtitle: e.target.value })} />
            </div>
            <div className="grid gap-2">
              <Label>Category</Label>
              <Input value={draft.category ?? ""} onChange={(e) => setDraft({ ...draft, category: e.target.value })} />
            </div>
            <div className="grid gap-2">
              <Label>Sort order</Label>
              <Input
                type="number"
                value={draft.sort_order ?? 0}
                onChange={(e) => setDraft({ ...draft, sort_order: Number(e.target.value) })}
              />
            </div>
            <div className="grid gap-2 sm:col-span-2">
              <Label>Description</Label>
              <Textarea
                rows={3}
                value={draft.description ?? ""}
                onChange={(e) => setDraft({ ...draft, description: e.target.value })}
              />
            </div>
            <div className="grid gap-2">
              <Label>Cover image URL</Label>
              <Input
                value={draft.cover_image_url ?? ""}
                onChange={(e) => setDraft({ ...draft, cover_image_url: e.target.value })}
              />
            </div>
            <div className="grid gap-2">
              <Label>Purchase URL</Label>
              <Input value={draft.purchase_url ?? ""} onChange={(e) => setDraft({ ...draft, purchase_url: e.target.value })} />
            </div>
            <label className="flex items-center gap-3 text-sm">
              <Switch checked={draft.featured ?? false} onCheckedChange={(v) => setDraft({ ...draft, featured: v })} />
              Featured on home page
            </label>
          </div>
        </EditorCard>
      ) : null}
      <div className="grid gap-3">
        {books.map((b) => (
          <div key={b.id} className="flex items-center justify-between gap-4 rounded-xl border border-gold/20 bg-card p-4">
            <div>
              <p className="font-display text-lg text-jungle">{b.title}</p>
              <p className="text-xs text-muted-foreground">
                {b.category ?? ""} · order {b.sort_order} {b.featured ? "· featured" : ""}
              </p>
            </div>
            <div className="flex gap-2">
              <Button variant="outline-gold" size="sm" onClick={() => setDraft(b)}>
                Edit
              </Button>
              <Button variant="ghost" size="sm" onClick={() => del(b.id)} aria-label={`Delete ${b.title}`}>
                <Trash2 className="h-4 w-4" />
              </Button>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

/* ---------- Events ---------- */

function EventsAdmin({ events }: { events: EventRow[] }) {
  const router = useRouter();
  const saveFn = useServerFn(saveEvent);
  const deleteFn = useServerFn(deleteEvent);
  const [draft, setDraft] = useState<Partial<EventRow> | null>(null);
  const [busy, setBusy] = useState(false);

  async function submit(e: FormEvent) {
    e.preventDefault();
    if (!draft) return;
    setBusy(true);
    const res = await saveFn({
      data: {
        id: (draft.id ?? "") as string,
        title: draft.title ?? "",
        description: draft.description ?? "",
        event_date: draft.event_date ?? new Date().toISOString(),
        date_tbc: draft.date_tbc ?? false,
        location: draft.location ?? "",
        event_url: draft.event_url ?? "",
      },
    });
    setBusy(false);
    if (!res.ok) {
      toast.error(res.error);
      return;
    }
    toast.success("Event saved.");
    setDraft(null);
    await router.invalidate();
  }

  function toLocalInput(iso: string) {
    const d = new Date(iso);
    const pad = (n: number) => String(n).padStart(2, "0");
    return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;
  }

  async function del(id: string) {
    const res = await deleteFn({ data: { id } });
    if (!res.ok) {
      toast.error(res.error);
      return;
    }
    toast.success("Event deleted.");
    await router.invalidate();
  }

  return (
    <div className="grid gap-6">
      <Button
        variant="gold"
        size="sm"
        className="justify-self-start rounded-full"
        onClick={() => setDraft({ event_date: new Date(Date.now() + 7 * 86_400_000).toISOString() })}
      >
        <Plus className="h-4 w-4" /> Add event
      </Button>
      {draft ? (
        <EditorCard
          title={draft.id ? "Edit event" : "New event"}
          editing={!!draft.id}
          onClose={() => setDraft(null)}
          onSubmit={submit}
          busy={busy}
        >
          <div className="grid gap-4 sm:grid-cols-2">
            <div className="grid gap-2 sm:col-span-2">
              <Label>Title</Label>
              <Input value={draft.title ?? ""} onChange={(e) => setDraft({ ...draft, title: e.target.value })} required />
            </div>
            <label className="flex items-center gap-3 text-sm sm:col-span-2">
              <Switch
                checked={draft.date_tbc ?? false}
                onCheckedChange={(v) => setDraft({ ...draft, date_tbc: v })}
              />
              <span>
                Date to be communicated
                <span className="block text-xs text-muted-foreground">
                  Choose this when the event date has not been decided yet.
                </span>
              </span>
            </label>
            {!(draft.date_tbc ?? false) ? (
              <div className="grid gap-2">
                <Label>Date & time</Label>
                <Input
                  type="datetime-local"
                  value={draft.event_date ? toLocalInput(draft.event_date) : ""}
                  onChange={(e) => setDraft({ ...draft, event_date: new Date(e.target.value).toISOString() })}
                  required
                />
              </div>
            ) : null}
            <div className="grid gap-2">
              <Label>Location</Label>
              <Input value={draft.location ?? ""} onChange={(e) => setDraft({ ...draft, location: e.target.value })} />
            </div>
            <div className="grid gap-2 sm:col-span-2">
              <Label>Description</Label>
              <Textarea
                rows={3}
                value={draft.description ?? ""}
                onChange={(e) => setDraft({ ...draft, description: e.target.value })}
              />
            </div>
            <div className="grid gap-2 sm:col-span-2">
              <Label>Event URL (optional)</Label>
              <Input value={draft.event_url ?? ""} onChange={(e) => setDraft({ ...draft, event_url: e.target.value })} />
            </div>
          </div>
        </EditorCard>
      ) : null}
      <div className="grid gap-3">
        {events.map((ev) => (
          <div key={ev.id} className="flex items-center justify-between gap-4 rounded-xl border border-gold/20 bg-card p-4">
            <div>
              <p className="font-display text-lg text-jungle">{ev.title}</p>
              <p className="text-xs text-muted-foreground">
                {formatAdminEventDate(ev)}
                {ev.location ? ` · ${ev.location}` : ""}
              </p>
            </div>
            <div className="flex gap-2">
              <Button variant="outline-gold" size="sm" onClick={() => setDraft(ev)}>
                Edit
              </Button>
              <Button variant="ghost" size="sm" onClick={() => del(ev.id)} aria-label={`Delete ${ev.title}`}>
                <Trash2 className="h-4 w-4" />
              </Button>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

/* ---------- Blog ---------- */

function BlogAdmin({ posts }: { posts: PostRow[] }) {
  const router = useRouter();
  const saveFn = useServerFn(saveBlogPost);
  const deleteFn = useServerFn(deleteBlogPost);
  const [draft, setDraft] = useState<Partial<PostRow> | null>(null);
  const [busy, setBusy] = useState(false);

  async function submit(e: FormEvent) {
    e.preventDefault();
    if (!draft) return;
    setBusy(true);
    const res = await saveFn({
      data: {
        id: (draft.id ?? "") as string,
        title: draft.title ?? "",
        slug: draft.slug ?? "",
        excerpt: draft.excerpt ?? "",
        content: draft.content ?? "",
        cover_image_url: draft.cover_image_url ?? "",
        published: draft.published ?? false,
        published_at: draft.published_at ?? new Date().toISOString(),
      },
    });
    setBusy(false);
    if (!res.ok) {
      toast.error(res.error.includes("duplicate") ? "Another post already uses that link." : res.error);
      return;
    }
    toast.success("Post saved.");
    setDraft(null);
    await router.invalidate();
  }

  async function del(id: string) {
    if (!confirm("Delete this post?")) return;
    const res = await deleteFn({ data: { id } });
    if (!res.ok) {
      toast.error(res.error);
      return;
    }
    toast.success("Post deleted.");
    await router.invalidate();
  }

  return (
    <div className="grid gap-6">
      <Button
        variant="gold"
        size="sm"
        className="justify-self-start rounded-full"
        onClick={() => setDraft({ published: true })}
      >
        <Plus className="h-4 w-4" /> New post
      </Button>
      {draft ? (
        <EditorCard
          title={draft.id ? "Edit post" : "New post"}
          editing={!!draft.id}
          onClose={() => setDraft(null)}
          onSubmit={submit}
          busy={busy}
        >
          <div className="grid gap-4 sm:grid-cols-2">
            <div className="grid gap-2 sm:col-span-2">
              <Label>Title</Label>
              <Input value={draft.title ?? ""} onChange={(e) => setDraft({ ...draft, title: e.target.value })} required />
            </div>
            <div className="grid gap-2 sm:col-span-2">
              <Label>Cover image URL (optional)</Label>
              <Input
                value={draft.cover_image_url ?? ""}
                onChange={(e) => setDraft({ ...draft, cover_image_url: e.target.value })}
              />
            </div>
            <div className="grid gap-2 sm:col-span-2">
              <Label>Short summary</Label>
              <Textarea rows={2} value={draft.excerpt ?? ""} onChange={(e) => setDraft({ ...draft, excerpt: e.target.value })} />
            </div>
            <div className="grid gap-2 sm:col-span-2">
              <Label>Post</Label>
              <Textarea
                rows={12}
                value={draft.content ?? ""}
                onChange={(e) => setDraft({ ...draft, content: e.target.value })}
                placeholder="Write your post. Leave an empty line between paragraphs."
                required
              />
            </div>
            <div className="flex items-center gap-3">
              <Switch checked={draft.published ?? false} onCheckedChange={(v) => setDraft({ ...draft, published: v })} />
              <Label>Published (visible on the website)</Label>
            </div>
          </div>
        </EditorCard>
      ) : null}
      <div className="grid gap-3">
        {posts.length === 0 ? <p className="text-sm text-muted-foreground">No posts yet.</p> : null}
        {posts.map((p) => (
          <div key={p.id} className="flex items-center justify-between gap-4 rounded-xl border border-gold/20 bg-card p-4">
            <div>
              <p className="font-display text-lg text-jungle">{p.title}</p>
              <p className="text-xs text-muted-foreground">
                {p.published ? "Published" : "Draft — hidden"} · {new Date(p.published_at).toLocaleDateString("en-GB")}
              </p>
            </div>
            <div className="flex gap-2">
              <Button variant="outline-gold" size="sm" onClick={() => setDraft(p)}>
                Edit
              </Button>
              <Button variant="ghost" size="sm" onClick={() => del(p.id)} aria-label={`Delete ${p.title}`}>
                <Trash2 className="h-4 w-4" />
              </Button>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

/* ---------- Videos ---------- */

function VideosAdmin({ videos }: { videos: VideoRow[] }) {
  const router = useRouter();
  const saveFn = useServerFn(saveVideo);
  const deleteFn = useServerFn(deleteVideo);
  const [draft, setDraft] = useState<Partial<VideoRow> | null>(null);
  const [busy, setBusy] = useState(false);

  async function submit(e: FormEvent) {
    e.preventDefault();
    if (!draft) return;
    setBusy(true);
    const res = await saveFn({
      data: {
        id: (draft.id ?? "") as string,
        title: draft.title ?? "",
        description: draft.description ?? "",
        video_url: draft.video_url ?? "",
        thumbnail_url: draft.thumbnail_url ?? "",
        sort_order: Number(draft.sort_order ?? 0),
      },
    });
    setBusy(false);
    if (!res.ok) {
      toast.error(res.error);
      return;
    }
    toast.success("Video saved.");
    setDraft(null);
    await router.invalidate();
  }

  async function del(id: string) {
    const res = await deleteFn({ data: { id } });
    if (!res.ok) {
      toast.error(res.error);
      return;
    }
    toast.success("Video deleted.");
    await router.invalidate();
  }

  return (
    <div className="grid gap-6">
      <Button
        variant="gold"
        size="sm"
        className="justify-self-start rounded-full"
        onClick={() => setDraft({ sort_order: videos.length + 1 })}
      >
        <Plus className="h-4 w-4" /> Add video
      </Button>
      {draft ? (
        <EditorCard
          title={draft.id ? "Edit video" : "New video"}
          editing={!!draft.id}
          onClose={() => setDraft(null)}
          onSubmit={submit}
          busy={busy}
        >
          <div className="grid gap-4 sm:grid-cols-2">
            <div className="grid gap-2">
              <Label>Title</Label>
              <Input value={draft.title ?? ""} onChange={(e) => setDraft({ ...draft, title: e.target.value })} required />
            </div>
            <div className="grid gap-2">
              <Label>Sort order</Label>
              <Input
                type="number"
                value={draft.sort_order ?? 0}
                onChange={(e) => setDraft({ ...draft, sort_order: Number(e.target.value) })}
              />
            </div>
            <div className="grid gap-2 sm:col-span-2">
              <Label>Video URL</Label>
              <Input value={draft.video_url ?? ""} onChange={(e) => setDraft({ ...draft, video_url: e.target.value })} required />
            </div>
            <div className="grid gap-2 sm:col-span-2">
              <Label>Thumbnail URL</Label>
              <Input
                value={draft.thumbnail_url ?? ""}
                onChange={(e) => setDraft({ ...draft, thumbnail_url: e.target.value })}
              />
            </div>
            <div className="grid gap-2 sm:col-span-2">
              <Label>Description</Label>
              <Textarea
                rows={2}
                value={draft.description ?? ""}
                onChange={(e) => setDraft({ ...draft, description: e.target.value })}
              />
            </div>
          </div>
        </EditorCard>
      ) : null}
      <div className="grid gap-3">
        {videos.map((v) => (
          <div key={v.id} className="flex items-center justify-between gap-4 rounded-xl border border-gold/20 bg-card p-4">
            <div>
              <p className="font-display text-lg text-jungle">{v.title}</p>
              <p className="text-xs text-muted-foreground">{v.video_url}</p>
            </div>
            <div className="flex gap-2">
              <Button variant="outline-gold" size="sm" onClick={() => setDraft(v)}>
                Edit
              </Button>
              <Button variant="ghost" size="sm" onClick={() => del(v.id)} aria-label={`Delete ${v.title}`}>
                <Trash2 className="h-4 w-4" />
              </Button>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

/* ---------- Testimonials ---------- */

function TestimonialsAdmin({ testimonials }: { testimonials: TestimonialRow[] }) {
  const router = useRouter();
  const saveFn = useServerFn(saveTestimonial);
  const deleteFn = useServerFn(deleteTestimonial);
  const [draft, setDraft] = useState<Partial<TestimonialRow> | null>(null);
  const [busy, setBusy] = useState(false);

  async function submit(e: FormEvent) {
    e.preventDefault();
    if (!draft) return;
    setBusy(true);
    const res = await saveFn({
      data: {
        id: (draft.id ?? "") as string,
        name: draft.name ?? "",
        role: draft.role ?? "",
        quote: draft.quote ?? "",
        sort_order: Number(draft.sort_order ?? 0),
      },
    });
    setBusy(false);
    if (!res.ok) {
      toast.error(res.error);
      return;
    }
    toast.success("Testimonial saved.");
    setDraft(null);
    await router.invalidate();
  }

  async function del(id: string) {
    const res = await deleteFn({ data: { id } });
    if (!res.ok) {
      toast.error(res.error);
      return;
    }
    toast.success("Testimonial deleted.");
    await router.invalidate();
  }

  return (
    <div className="grid gap-6">
      <Button
        variant="gold"
        size="sm"
        className="justify-self-start rounded-full"
        onClick={() => setDraft({ sort_order: testimonials.length + 1 })}
      >
        <Plus className="h-4 w-4" /> Add testimonial
      </Button>
      {draft ? (
        <EditorCard
          title={draft.id ? "Edit testimonial" : "New testimonial"}
          editing={!!draft.id}
          onClose={() => setDraft(null)}
          onSubmit={submit}
          busy={busy}
        >
          <div className="grid gap-4 sm:grid-cols-2">
            <div className="grid gap-2">
              <Label>Name</Label>
              <Input value={draft.name ?? ""} onChange={(e) => setDraft({ ...draft, name: e.target.value })} required />
            </div>
            <div className="grid gap-2">
              <Label>Role</Label>
              <Input value={draft.role ?? ""} onChange={(e) => setDraft({ ...draft, role: e.target.value })} />
            </div>
            <div className="grid gap-2 sm:col-span-2">
              <Label>Quote</Label>
              <Textarea
                rows={3}
                value={draft.quote ?? ""}
                onChange={(e) => setDraft({ ...draft, quote: e.target.value })}
                required
              />
            </div>
            <div className="grid gap-2">
              <Label>Sort order</Label>
              <Input
                type="number"
                value={draft.sort_order ?? 0}
                onChange={(e) => setDraft({ ...draft, sort_order: Number(e.target.value) })}
              />
            </div>
          </div>
        </EditorCard>
      ) : null}
      <div className="grid gap-3">
        {testimonials.map((t) => (
          <div key={t.id} className="flex items-start justify-between gap-4 rounded-xl border border-gold/20 bg-card p-4">
            <div>
              <p className="font-medium">
                {t.name}
                {t.role ? ` · ${t.role}` : ""}
              </p>
              <p className="mt-1 text-sm text-muted-foreground">“{t.quote}”</p>
            </div>
            <div className="flex shrink-0 gap-2">
              <Button variant="outline-gold" size="sm" onClick={() => setDraft(t)}>
                Edit
              </Button>
              <Button variant="ghost" size="sm" onClick={() => del(t.id)} aria-label={`Delete testimonial by ${t.name}`}>
                <Trash2 className="h-4 w-4" />
              </Button>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

/* ---------- Enquiries & subscribers ---------- */

function EnquiriesAdmin({ enquiries }: { enquiries: EnquiryRow[] }) {
  const router = useRouter();
  const deleteFn = useServerFn(deleteEnquiry);

  async function del(id: string) {
    const res = await deleteFn({ data: { id } });
    if (!res.ok) {
      toast.error(res.error);
      return;
    }
    toast.success("Enquiry removed.");
    await router.invalidate();
  }

  if (enquiries.length === 0) {
    return <p className="text-sm text-muted-foreground">No enquiries yet.</p>;
  }
  return (
    <div className="grid gap-3">
      {enquiries.map((q) => (
        <div key={q.id} className="flex items-start justify-between gap-4 rounded-xl border border-gold/20 bg-card p-4">
          <div>
            <p className="font-medium">
              {q.name} <span className="text-xs text-muted-foreground">· {q.email}</span>
            </p>
            <p className="text-xs text-terra">{q.subject}</p>
            <p className="mt-2 text-sm text-muted-foreground">{q.message}</p>
          </div>
          <Button variant="ghost" size="sm" onClick={() => del(q.id)} aria-label="Delete enquiry">
            <Trash2 className="h-4 w-4" />
          </Button>
        </div>
      ))}
    </div>
  );
}

function SubscribersAdmin({ subscribers }: { subscribers: SubscriberRow[] }) {
  const router = useRouter();
  const deleteFn = useServerFn(deleteSubscriber);

  async function del(id: string) {
    const res = await deleteFn({ data: { id } });
    if (!res.ok) {
      toast.error(res.error);
      return;
    }
    toast.success("Subscriber removed.");
    await router.invalidate();
  }

  if (subscribers.length === 0) {
    return <p className="text-sm text-muted-foreground">No subscribers yet.</p>;
  }
  return (
    <div className="grid gap-3">
      {subscribers.map((s) => (
        <div key={s.id} className="flex items-center justify-between gap-4 rounded-xl border border-gold/20 bg-card p-4">
          <p className="text-sm">{s.email}</p>
          <Button variant="ghost" size="sm" onClick={() => del(s.id)} aria-label="Delete subscriber">
            <Trash2 className="h-4 w-4" />
          </Button>
        </div>
      ))}
    </div>
  );
}

/* ---------- Dashboard ---------- */

const tabs = ["Books", "Events", "Videos", "Blog", "Testimonials", "Enquiries", "Subscribers"] as const;

function Dashboard({ state }: { state: Extract<AdminState, { unlocked: true }> }) {
  const router = useRouter();
  const logoutFn = useServerFn(adminLogout);
  const [tab, setTab] = useState<(typeof tabs)[number]>("Books");

  async function logout() {
    await logoutFn();
    await router.invalidate();
  }

  return (
    <div className="mx-auto max-w-5xl px-4 pb-24 pt-28 sm:px-6">
      <div className="flex flex-wrap items-center justify-between gap-4">
        <div>
          <h1 className="font-display text-3xl text-jungle">Content studio</h1>
          <p className="text-sm text-muted-foreground">Add or edit books, events, videos, blog posts and testimonials.</p>
        </div>
        <Button variant="outline-gold" size="sm" className="rounded-full" onClick={logout}>
          <LogOut className="h-4 w-4" /> Sign out
        </Button>
      </div>
      <div className="mt-8 flex flex-wrap gap-2">
        {tabs.map((t) => (
          <button
            key={t}
            type="button"
            onClick={() => setTab(t)}
            className={cn(
              "rounded-full border px-4 py-2 text-xs font-semibold uppercase tracking-widest transition-colors",
              tab === t ? "border-jungle bg-jungle text-ivory" : "border-gold/40 text-foreground hover:bg-gold/10",
            )}
          >
            {t}
            {t === "Enquiries" && state.enquiries.length > 0 ? ` (${state.enquiries.length})` : ""}
          </button>
        ))}
      </div>
      <div className="mt-8">
        {tab === "Books" ? <BooksAdmin books={state.books} /> : null}
        {tab === "Events" ? <EventsAdmin events={state.events} /> : null}
        {tab === "Videos" ? <VideosAdmin videos={state.videos} /> : null}
        {tab === "Blog" ? <BlogAdmin posts={state.posts} /> : null}
        {tab === "Testimonials" ? <TestimonialsAdmin testimonials={state.testimonials} /> : null}
        {tab === "Enquiries" ? <EnquiriesAdmin enquiries={state.enquiries} /> : null}
        {tab === "Subscribers" ? <SubscribersAdmin subscribers={state.subscribers} /> : null}
      </div>
    </div>
  );
}

function AdminPage() {
  const state = Route.useLoaderData();
  return state.unlocked ? <Dashboard state={state} /> : <LoginGate />;
}
