import { ReactNode, useState } from "react";
import { Head } from "@inertiajs/react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import AdminLayout from "@/layouts/AdminLayout";
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 { Badge } from "@/components/ui/badge";
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
import {
  Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter,
} from "@/components/ui/dialog";
import {
  AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent,
  AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import {
  Table, TableBody, TableCell, TableHead, TableHeader, TableRow,
} from "@/components/ui/table";
import { Plus, Pencil, Trash2, Tag, ArrowUp, ArrowDown, Power, X } from "lucide-react";
import { toast } from "sonner";

const csrfToken = () =>
  (document.querySelector('meta[name="csrf-token"]') as HTMLMetaElement | null)?.content ?? "";

interface CategoryRow {
  id: string;
  type: "main" | "sub";
  name: string;
  slug: string | null;
  href: string | null;
  show_in_menu: boolean;
  sort_order: number;
  is_active: boolean;
  course_count: number;
  created_at?: string;
  updated_at?: string;
}

type CatTab = "main" | "sub" | "training";

interface CourseRow {
  id: string;
  title: string;
  slug: string | null;
  category: string;
  is_active: boolean;
  show_in_nav: boolean;
  nav_sort_order: number;
}

const emptyForm = (type: "main" | "sub"): Partial<CategoryRow> => ({
  type,
  name: "",
  slug: "",
  href: type === "main" ? "/courses" : "",
  show_in_menu: type === "main",
  sort_order: 0,
  is_active: true,
});

const CategoriesPage = () => {
  const qc = useQueryClient();
  const [activeType, setActiveType] = useState<CatTab>("main");
  const [dialogOpen, setDialogOpen] = useState(false);
  const [editing, setEditing] = useState<CategoryRow | null>(null);
  const [form, setForm] = useState<Partial<CategoryRow>>(emptyForm("main"));
  const [deleteRow, setDeleteRow] = useState<CategoryRow | null>(null);
  const [pickerOpen, setPickerOpen] = useState(false);
  const [courseSearch, setCourseSearch] = useState("");

  const { data: categories = [], isLoading } = useQuery({
    queryKey: ["admin-categories"],
    queryFn: async (): Promise<CategoryRow[]> => {
      const res = await fetch("/api/admin/categories");
      if (!res.ok) return [];
      return res.json();
    },
  });

  const main = categories.filter((c) => c.type === "main");
  const sub = categories.filter((c) => c.type === "sub");
  const visible = activeType === "main" ? main : sub;

  // Training Courses tab — the curated main-nav dropdown. Backed by the courses
  // table's show_in_nav / nav_sort_order columns rather than by a category row.
  const { data: courses = [], isLoading: coursesLoading } = useQuery({
    queryKey: ["admin-nav-courses"],
    queryFn: async (): Promise<CourseRow[]> => {
      const res = await fetch("/api/admin/courses");
      if (!res.ok) return [];
      return res.json();
    },
  });

  const navSelected = courses
    .filter((c) => c.show_in_nav)
    .slice()
    .sort((a, b) => a.nav_sort_order - b.nav_sort_order || a.title.localeCompare(b.title));

  const courseSearchQ = courseSearch.trim().toLowerCase();
  const candidates = courses
    .filter((c) => !c.show_in_nav)
    .filter((c) =>
      !courseSearchQ ||
      c.title.toLowerCase().includes(courseSearchQ) ||
      (c.slug || "").toLowerCase().includes(courseSearchQ) ||
      (c.category || "").toLowerCase().includes(courseSearchQ),
    )
    .slice()
    .sort((a, b) => a.title.localeCompare(b.title));

  const saveMutation = useMutation({
    mutationFn: async (payload: Partial<CategoryRow>) => {
      const url = editing
        ? `/api/admin/categories/${editing.id}`
        : `/api/admin/categories`;
      const res = await fetch(url, {
        method: editing ? "PATCH" : "POST",
        headers: { "Content-Type": "application/json", "X-CSRF-TOKEN": csrfToken() },
        body: JSON.stringify(payload),
      });
      if (!res.ok) {
        const err = await res.json().catch(() => ({ error: "Failed" }));
        throw new Error(err.error || "Failed to save");
      }
      return res.json();
    },
    onSuccess: () => {
      toast.success(editing ? "Category updated" : "Category created");
      qc.invalidateQueries({ queryKey: ["admin-categories"] });
      qc.invalidateQueries({ queryKey: ["public-categories"] });
      setDialogOpen(false);
      setEditing(null);
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const deleteMutation = useMutation({
    mutationFn: async (id: string) => {
      const res = await fetch(`/api/admin/categories/${id}`, {
        method: "DELETE",
        headers: { "X-CSRF-TOKEN": csrfToken() },
      });
      if (!res.ok) {
        const err = await res.json().catch(() => ({ error: "Failed" }));
        throw new Error(err.error || "Failed to delete");
      }
      return res.json();
    },
    onSuccess: () => {
      toast.success("Category deleted");
      qc.invalidateQueries({ queryKey: ["admin-categories"] });
      qc.invalidateQueries({ queryKey: ["public-categories"] });
      setDeleteRow(null);
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const reorderMutation = useMutation({
    mutationFn: async (items: { id: string; sort_order: number }[]) => {
      const res = await fetch("/api/admin/categories/reorder", {
        method: "POST",
        headers: { "Content-Type": "application/json", "X-CSRF-TOKEN": csrfToken() },
        body: JSON.stringify({ items }),
      });
      if (!res.ok) throw new Error("Failed to reorder");
      return res.json();
    },
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ["admin-categories"] });
      qc.invalidateQueries({ queryKey: ["public-categories"] });
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const move = (row: CategoryRow, direction: -1 | 1) => {
    const list = activeType === "main" ? [...main] : [...sub];
    list.sort((a, b) => a.sort_order - b.sort_order || a.name.localeCompare(b.name));
    const idx = list.findIndex((r) => r.id === row.id);
    const swapIdx = idx + direction;
    if (idx < 0 || swapIdx < 0 || swapIdx >= list.length) return;
    const a = list[idx];
    const b = list[swapIdx];
    reorderMutation.mutate([
      { id: a.id, sort_order: b.sort_order },
      { id: b.id, sort_order: a.sort_order },
    ]);
  };

  const toggleActive = (row: CategoryRow) => {
    saveSilent(row.id, { is_active: !row.is_active });
  };

  // Inline single-field update without opening the dialog.
  const saveSilent = async (id: string, patch: Partial<CategoryRow>) => {
    try {
      const res = await fetch(`/api/admin/categories/${id}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json", "X-CSRF-TOKEN": csrfToken() },
        body: JSON.stringify(patch),
      });
      if (!res.ok) {
        const err = await res.json().catch(() => ({ error: "Failed" }));
        throw new Error(err.error || "Failed");
      }
      qc.invalidateQueries({ queryKey: ["admin-categories"] });
      qc.invalidateQueries({ queryKey: ["public-categories"] });
    } catch (e: any) {
      toast.error(e.message || "Failed to update");
    }
  };

  // --- Training Courses (nav dropdown) mutations ---
  const patchCourseNav = async (
    id: string,
    patch: Partial<Pick<CourseRow, "show_in_nav" | "nav_sort_order">>,
  ) => {
    const res = await fetch(`/api/admin/courses/${id}`, {
      method: "PATCH",
      headers: { "Content-Type": "application/json", "X-CSRF-TOKEN": csrfToken() },
      body: JSON.stringify(patch),
    });
    if (!res.ok) {
      const err = await res.json().catch(() => ({ error: "Failed" }));
      throw new Error(err.error || "Failed to update course");
    }
    return res.json();
  };

  const invalidateCourses = () => {
    qc.invalidateQueries({ queryKey: ["admin-nav-courses"] });
    qc.invalidateQueries({ queryKey: ["nav-training-courses"] });
  };

  const courseNavMutation = useMutation({
    mutationFn: (vars: { id: string; patch: Partial<Pick<CourseRow, "show_in_nav" | "nav_sort_order">> }) =>
      patchCourseNav(vars.id, vars.patch),
    onSuccess: invalidateCourses,
    onError: (e: Error) => toast.error(e.message),
  });

  const addCourseToNav = (c: CourseRow) => {
    const nextOrder = (navSelected[navSelected.length - 1]?.nav_sort_order ?? 0) + 1;
    courseNavMutation.mutate(
      { id: c.id, patch: { show_in_nav: true, nav_sort_order: nextOrder } },
      { onSuccess: () => toast.success(`Added "${c.title}" to the menu`) },
    );
  };

  const removeCourseFromNav = (c: CourseRow) => {
    courseNavMutation.mutate(
      { id: c.id, patch: { show_in_nav: false } },
      { onSuccess: () => toast.success(`Removed "${c.title}" from the menu`) },
    );
  };

  // Reorder by swapping nav_sort_order with the neighbour (mirrors category reorder).
  const moveCourse = async (row: CourseRow, direction: -1 | 1) => {
    const idx = navSelected.findIndex((r) => r.id === row.id);
    const swapIdx = idx + direction;
    if (idx < 0 || swapIdx < 0 || swapIdx >= navSelected.length) return;
    const a = navSelected[idx];
    const b = navSelected[swapIdx];
    try {
      await Promise.all([
        patchCourseNav(a.id, { nav_sort_order: b.nav_sort_order }),
        patchCourseNav(b.id, { nav_sort_order: a.nav_sort_order }),
      ]);
      invalidateCourses();
    } catch (e: any) {
      toast.error(e?.message || "Failed to reorder");
    }
  };

  const openCreate = () => {
    setEditing(null);
    setForm(emptyForm(activeType === "training" ? "main" : activeType));
    setDialogOpen(true);
  };

  const openEdit = (row: CategoryRow) => {
    setEditing(row);
    setForm({ ...row });
    setDialogOpen(true);
  };

  const onSubmit = () => {
    if (!form.name?.trim()) {
      toast.error("Name is required");
      return;
    }
    const payload: Partial<CategoryRow> = {
      type: form.type ?? activeType,
      name: form.name.trim(),
      slug: form.slug?.trim() || null,
      href: form.type === "main" ? (form.href?.trim() || "/courses") : null,
      show_in_menu: form.type === "main" ? (form.show_in_menu ?? false) : false,
      sort_order: Number.isFinite(Number(form.sort_order)) ? Number(form.sort_order) : 0,
      is_active: form.is_active ?? true,
    };
    saveMutation.mutate(payload);
  };

  return (
    <>
      <Head title="Categories" />
      <div>
        <div className="flex items-center justify-between mb-6">
          <div>
            <h1 className="text-2xl font-bold text-foreground flex items-center gap-2">
              <Tag className="w-5 h-5 text-primary" /> Categories
            </h1>
            <p className="text-sm text-muted-foreground mt-1">
              Manage course main categories (with their own landing pages), orthogonal sub-categories, and the curated “Training Courses” menu shown in the site navigation.
            </p>
          </div>
          {activeType === "training" ? (
            <Button onClick={() => setPickerOpen(true)}>
              <Plus className="w-4 h-4 mr-1.5" />
              Add Course to Menu
            </Button>
          ) : (
            <Button onClick={openCreate}>
              <Plus className="w-4 h-4 mr-1.5" />
              New {activeType === "main" ? "Main" : "Sub"} Category
            </Button>
          )}
        </div>

        <Tabs value={activeType} onValueChange={(v) => setActiveType(v as CatTab)}>
          <TabsList>
            <TabsTrigger value="main">Main Categories ({main.length})</TabsTrigger>
            <TabsTrigger value="sub">Sub-Categories ({sub.length})</TabsTrigger>
            <TabsTrigger value="training">Training Courses ({navSelected.length})</TabsTrigger>
          </TabsList>

          {activeType !== "training" && (
          <TabsContent value={activeType} className="mt-4">
            <div className="bg-card border border-border rounded-xl overflow-hidden">
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead className="w-[80px]">Order</TableHead>
                    <TableHead>Name</TableHead>
                    <TableHead>Slug</TableHead>
                    {activeType === "main" && <TableHead>Landing href</TableHead>}
                    {activeType === "main" && <TableHead className="text-center">Main Menu</TableHead>}
                    <TableHead className="text-center">Courses</TableHead>
                    <TableHead className="text-center">Active</TableHead>
                    <TableHead className="text-right">Actions</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {isLoading ? (
                    <TableRow>
                      <TableCell colSpan={activeType === "main" ? 8 : 6} className="text-center text-muted-foreground py-12">
                        Loading…
                      </TableCell>
                    </TableRow>
                  ) : visible.length === 0 ? (
                    <TableRow>
                      <TableCell colSpan={activeType === "main" ? 8 : 6} className="text-center text-muted-foreground py-12">
                        No {activeType === "main" ? "main" : "sub"} categories yet.
                      </TableCell>
                    </TableRow>
                  ) : (
                    visible
                      .slice()
                      .sort((a, b) => a.sort_order - b.sort_order || a.name.localeCompare(b.name))
                      .map((row, i, arr) => (
                        <TableRow key={row.id}>
                          <TableCell>
                            <div className="flex items-center gap-1">
                              <Button
                                variant="ghost"
                                size="sm"
                                className="h-7 w-7 p-0"
                                disabled={i === 0 || reorderMutation.isPending}
                                onClick={() => move(row, -1)}
                              >
                                <ArrowUp className="w-3.5 h-3.5" />
                              </Button>
                              <Button
                                variant="ghost"
                                size="sm"
                                className="h-7 w-7 p-0"
                                disabled={i === arr.length - 1 || reorderMutation.isPending}
                                onClick={() => move(row, 1)}
                              >
                                <ArrowDown className="w-3.5 h-3.5" />
                              </Button>
                            </div>
                          </TableCell>
                          <TableCell className="font-medium">{row.name}</TableCell>
                          <TableCell className="text-muted-foreground text-xs font-mono">{row.slug || "—"}</TableCell>
                          {activeType === "main" && (
                            <TableCell className="text-muted-foreground text-xs font-mono">{row.href || "—"}</TableCell>
                          )}
                          {activeType === "main" && (
                            <TableCell className="text-center">
                              <Switch
                                checked={row.show_in_menu}
                                onCheckedChange={(v) => saveSilent(row.id, { show_in_menu: v })}
                                aria-label="Show in main menu"
                              />
                            </TableCell>
                          )}
                          <TableCell className="text-center">
                            {row.course_count > 0 ? (
                              <Badge variant="secondary">{row.course_count}</Badge>
                            ) : (
                              <span className="text-muted-foreground text-xs">0</span>
                            )}
                          </TableCell>
                          <TableCell className="text-center">
                            <button
                              onClick={() => toggleActive(row)}
                              title={row.is_active ? "Deactivate" : "Activate"}
                              className="inline-flex items-center"
                            >
                              <Power className={`w-4 h-4 ${row.is_active ? "text-emerald-600" : "text-muted-foreground"}`} />
                            </button>
                          </TableCell>
                          <TableCell className="text-right">
                            <div className="flex items-center gap-1 justify-end">
                              <Button variant="ghost" size="sm" className="h-7" onClick={() => openEdit(row)}>
                                <Pencil className="w-3.5 h-3.5" />
                              </Button>
                              <Button
                                variant="ghost"
                                size="sm"
                                className="h-7 text-destructive hover:text-destructive"
                                onClick={() => setDeleteRow(row)}
                              >
                                <Trash2 className="w-3.5 h-3.5" />
                              </Button>
                            </div>
                          </TableCell>
                        </TableRow>
                      ))
                  )}
                </TableBody>
              </Table>
            </div>
          </TabsContent>
          )}

          {activeType === "training" && (
          <TabsContent value="training" className="mt-4">
            <p className="text-sm text-muted-foreground mb-3">
              These courses appear in the site's main “Training Courses” dropdown, in this order. An
              “All Training Courses” link is always shown first automatically. Inactive courses stay
              listed here but won't appear on the public site until reactivated.
            </p>
            <div className="bg-card border border-border rounded-xl overflow-hidden">
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead className="w-[80px]">Order</TableHead>
                    <TableHead>Course</TableHead>
                    <TableHead>Slug</TableHead>
                    <TableHead className="text-center">Active</TableHead>
                    <TableHead className="text-right">Actions</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {coursesLoading ? (
                    <TableRow>
                      <TableCell colSpan={5} className="text-center text-muted-foreground py-12">
                        Loading…
                      </TableCell>
                    </TableRow>
                  ) : navSelected.length === 0 ? (
                    <TableRow>
                      <TableCell colSpan={5} className="text-center text-muted-foreground py-12">
                        No courses in the menu yet. Use “Add Course to Menu” to choose some.
                      </TableCell>
                    </TableRow>
                  ) : (
                    navSelected.map((row, i, arr) => (
                      <TableRow key={row.id}>
                        <TableCell>
                          <div className="flex items-center gap-1">
                            <Button
                              variant="ghost"
                              size="sm"
                              className="h-7 w-7 p-0"
                              disabled={i === 0 || courseNavMutation.isPending}
                              onClick={() => moveCourse(row, -1)}
                            >
                              <ArrowUp className="w-3.5 h-3.5" />
                            </Button>
                            <Button
                              variant="ghost"
                              size="sm"
                              className="h-7 w-7 p-0"
                              disabled={i === arr.length - 1 || courseNavMutation.isPending}
                              onClick={() => moveCourse(row, 1)}
                            >
                              <ArrowDown className="w-3.5 h-3.5" />
                            </Button>
                          </div>
                        </TableCell>
                        <TableCell className="font-medium">{row.title}</TableCell>
                        <TableCell className="text-muted-foreground text-xs font-mono">{row.slug || "—"}</TableCell>
                        <TableCell className="text-center">
                          <span title={row.is_active ? "Active" : "Inactive — hidden from the public site"}>
                            <Power className={`w-4 h-4 inline ${row.is_active ? "text-emerald-600" : "text-muted-foreground"}`} />
                          </span>
                        </TableCell>
                        <TableCell className="text-right">
                          <Button
                            variant="ghost"
                            size="sm"
                            className="h-7 text-destructive hover:text-destructive"
                            title="Remove from menu"
                            disabled={courseNavMutation.isPending}
                            onClick={() => removeCourseFromNav(row)}
                          >
                            <X className="w-3.5 h-3.5" />
                          </Button>
                        </TableCell>
                      </TableRow>
                    ))
                  )}
                </TableBody>
              </Table>
            </div>
          </TabsContent>
          )}
        </Tabs>
      </div>

      {/* Create / Edit dialog */}
      <Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
        <DialogContent className="sm:max-w-md">
          <DialogHeader>
            <DialogTitle>{editing ? "Edit Category" : "New Category"}</DialogTitle>
          </DialogHeader>
          <div className="space-y-4">
            <div>
              <Label>Type</Label>
              <div className="flex gap-2 mt-1.5">
                <Button
                  variant={form.type === "main" ? "default" : "outline"}
                  size="sm"
                  onClick={() => setForm((f) => ({ ...f, type: "main", href: f.href || "/courses" }))}
                  disabled={!!editing}
                >
                  Main
                </Button>
                <Button
                  variant={form.type === "sub" ? "default" : "outline"}
                  size="sm"
                  onClick={() => setForm((f) => ({ ...f, type: "sub", href: "" }))}
                  disabled={!!editing}
                >
                  Sub
                </Button>
              </div>
              <p className="text-xs text-muted-foreground mt-1">
                {form.type === "main"
                  ? "Main categories appear in navigation and have a landing page."
                  : "Sub-categories are used to further classify courses (orthogonal to main)."}
              </p>
            </div>

            <div>
              <Label>Name *</Label>
              <Input
                value={form.name || ""}
                onChange={(e) => setForm((f) => ({ ...f, name: e.target.value }))}
                placeholder={form.type === "main" ? "e.g. NRSWA" : "e.g. Civils"}
              />
              {editing && form.name !== editing.name && editing.course_count > 0 && (
                <p className="text-xs text-amber-600 mt-1">
                  Renaming will update {editing.course_count} course(s) currently using this category.
                </p>
              )}
            </div>

            <div>
              <Label>Slug</Label>
              <Input
                value={form.slug || ""}
                onChange={(e) => setForm((f) => ({ ...f, slug: e.target.value }))}
                placeholder="auto-generated from name"
                className="font-mono text-xs"
              />
            </div>

            {form.type === "main" && (
              <div>
                <Label>Landing href</Label>
                <Input
                  value={form.href || ""}
                  onChange={(e) => setForm((f) => ({ ...f, href: e.target.value }))}
                  placeholder="/courses"
                  className="font-mono text-xs"
                />
                <p className="text-xs text-muted-foreground mt-1">
                  Where the public site links visitors when they pick this category.
                </p>
              </div>
            )}

            <div>
              <Label>Sort order</Label>
              <Input
                type="number"
                value={form.sort_order ?? 0}
                onChange={(e) => setForm((f) => ({ ...f, sort_order: parseInt(e.target.value) || 0 }))}
              />
            </div>

            {form.type === "main" && (
              <div className="flex items-center justify-between">
                <div>
                  <Label>Main Menu</Label>
                  <p className="text-xs text-muted-foreground">Show this category in the site's main navigation.</p>
                </div>
                <Switch
                  checked={form.show_in_menu ?? false}
                  onCheckedChange={(v) => setForm((f) => ({ ...f, show_in_menu: v }))}
                />
              </div>
            )}

            <div className="flex items-center justify-between">
              <Label>Active</Label>
              <Switch
                checked={form.is_active ?? true}
                onCheckedChange={(v) => setForm((f) => ({ ...f, is_active: v }))}
              />
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setDialogOpen(false)}>Cancel</Button>
            <Button onClick={onSubmit} disabled={saveMutation.isPending}>
              {saveMutation.isPending ? "Saving…" : editing ? "Save Changes" : "Create"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Delete confirm */}
      <AlertDialog open={!!deleteRow} onOpenChange={(open) => !open && setDeleteRow(null)}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Delete category?</AlertDialogTitle>
            <AlertDialogDescription>
              {deleteRow?.course_count
                ? `This category is used by ${deleteRow.course_count} course(s). You'll need to reassign them first.`
                : `"${deleteRow?.name}" will be removed permanently.`}
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>Cancel</AlertDialogCancel>
            <AlertDialogAction
              className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
              disabled={deleteMutation.isPending}
              onClick={() => deleteRow && deleteMutation.mutate(deleteRow.id)}
            >
              {deleteMutation.isPending ? "Deleting…" : "Delete"}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>

      {/* Add courses to the nav dropdown */}
      <Dialog
        open={pickerOpen}
        onOpenChange={(o) => { setPickerOpen(o); if (!o) setCourseSearch(""); }}
      >
        <DialogContent className="sm:max-w-lg">
          <DialogHeader>
            <DialogTitle>Add courses to the menu</DialogTitle>
          </DialogHeader>
          <Input
            placeholder="Search courses…"
            value={courseSearch}
            onChange={(e) => setCourseSearch(e.target.value)}
            autoFocus
          />
          <div className="max-h-[50vh] overflow-y-auto -mx-1 px-1 space-y-1">
            {candidates.length === 0 ? (
              <p className="text-sm text-muted-foreground py-6 text-center">
                {courseSearch ? "No matching courses." : "Every course is already in the menu."}
              </p>
            ) : (
              candidates.map((c) => (
                <button
                  key={c.id}
                  onClick={() => addCourseToNav(c)}
                  disabled={courseNavMutation.isPending}
                  className="flex w-full items-center justify-between gap-3 rounded-md px-3 py-2 text-left hover:bg-secondary/80 transition-colors disabled:opacity-50"
                >
                  <span className="min-w-0">
                    <span className="block truncate text-sm font-medium text-foreground">{c.title}</span>
                    <span className="block truncate text-xs text-muted-foreground font-mono">{c.slug}</span>
                  </span>
                  <span className="flex items-center gap-2 shrink-0">
                    {!c.is_active && <Badge variant="outline" className="text-xs">inactive</Badge>}
                    <Plus className="w-4 h-4 text-primary" />
                  </span>
                </button>
              ))
            )}
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setPickerOpen(false)}>Done</Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </>
  );
};

CategoriesPage.layout = (page: ReactNode) => <AdminLayout>{page}</AdminLayout>;

export default CategoriesPage;
