import { useEffect, useMemo, useState } from "react";
import {
  AlertCircle,
  Boxes,
  CheckCircle2,
  Eye,
  Filter,
  ListOrdered,
  Loader2,
  MoreHorizontal,
  Pencil,
  Plus,
  Search,
  Settings,
  Shield,
  Sparkles,
  Trash2,
} from "lucide-react";

import Breadcrumbs from "@/components/ui/Breadcrumbs";
import EditDropdownSettingDialog from "./EditDropdownSettingDialog";
import ManageDropdownOptionsDialog from "./ManageDropdownOptionsDialog";
import DeleteDropdownSettingDialog from "./DeleteDropdownSettingDialog";
import { useQuery } from "@tanstack/react-query";
import { api } from "@/services/api";
import { useDeleteDropdownSetting } from "@/hooks/useDropdownSettings";
import type { DropdownSetting } from "@/types/dropdownSettings";
import {
  DataTable,
  DataTableFooter,
  type ColumnDef,
  usePagination,
  Button,
  Card,
  CardHeader,
  CardTitle,
  CardDescription,
  CardContent,
  Input,
  DropdownMenu,
  DropdownMenuTrigger,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
} from "@edr/ui-common";

type ActiveDialog = "edit" | "options" | "delete";

export default function DropdownSettingsPage() {
  const { pagination, setPagination } = usePagination({ pageSize: 10 });
  const [query, setQuery] = useState("");

  const [activeDialog, setActiveDialog] = useState<ActiveDialog | null>(null);
  const [activeSetting, setActiveSetting] = useState<DropdownSetting | null>(
    null,
  );

  const openDialogFor = (dialog: ActiveDialog, setting: DropdownSetting) => {
    // Defer past the DropdownMenu's close cycle. Radix's modal lock can leave
    // `pointer-events: none` on <body> when a menu closes and a dialog opens
    // in the same frame — wait two RAFs and then explicitly reset the body
    // style so the dialog interior is interactive.
    requestAnimationFrame(() => {
      requestAnimationFrame(() => {
        document.body.style.pointerEvents = "";
        setActiveSetting(setting);
        setActiveDialog(dialog);
      });
    });
  };
  const closeDialog = () => {
    setActiveDialog(null);
    // Keep activeSetting briefly so dialog content doesn't flash empty during
    // the close animation; cleared on next open.
  };

  // Belt-and-suspenders for the Radix pointer-events leak: any time the active
  // dialog changes, schedule a body-style cleanup after the next paint.
  useEffect(() => {
    const id = requestAnimationFrame(() => {
      if (document.body.style.pointerEvents === "none") {
        document.body.style.pointerEvents = "";
      }
    });
    return () => cancelAnimationFrame(id);
  }, [activeDialog]);

  const { data, isLoading, isError, error } = useQuery(
    api.dropdownSettings.list.queryOptions(),
  );
  const deleteMutation = useDeleteDropdownSetting();

  const dropdownSettings = useMemo<DropdownSetting[]>(
    () => (Array.isArray(data) ? data : []),
    [data],
  );

  const filtered = useMemo(() => {
    const q = query.trim().toLowerCase();
    if (!q) return dropdownSettings;
    return dropdownSettings.filter(
      (s) =>
        s.code.toLowerCase().includes(q) ||
        s.label.toLowerCase().includes(q) ||
        (s.description ?? "").toLowerCase().includes(q),
    );
  }, [dropdownSettings, query]);

  const total = filtered.length;
  const pageCount = Math.max(1, Math.ceil(total / pagination.pageSize));
  const start = pagination.pageIndex * pagination.pageSize;
  const end = Math.min(start + pagination.pageSize, total);

  const paginatedData = useMemo(
    () => filtered.slice(start, end),
    [start, end, filtered],
  );

  const totalOptions = dropdownSettings.reduce(
    (sum, s) => sum + (s.children?.length ?? 0),
    0,
  );
  const multipleCount = dropdownSettings.filter((s) => s.multiple).length;
  const searchableCount = dropdownSettings.filter(
    (s) => s.meta?.searchable,
  ).length;

  const status: "loading" | "error" | "success" = isLoading
    ? "loading"
    : isError
      ? "error"
      : "success";

  const columns: ColumnDef<DropdownSetting>[] = [
    {
      id: "setting",
      header: "Setting",
      cell: ({ row }) => {
        const s = row.original;
        return (
          <div className="flex items-center gap-3">
            <div className="flex h-10 w-10 items-center justify-center rounded-full bg-primary text-primary-foreground">
              <Settings />
            </div>
            <div>
              <p className="font-medium text-slate-900">{s.label}</p>
              <p className="text-xs text-slate-500">
                {s.description ?? "No description"}
              </p>
            </div>
          </div>
        );
      },
    },
    {
      id: "code",
      header: "Code",
      cell: ({ row }) => (
        <span className="rounded-md bg-slate-100 px-2 py-1 font-mono text-xs text-slate-700">
          {row.original.code}
        </span>
      ),
    },
    {
      id: "options",
      header: "Options",
      cell: ({ row }) => {
        const s = row.original;
        return (
          <div className="flex items-center gap-2 text-sm text-slate-700">
            <Boxes />
            <span className="font-medium">{s.children?.length ?? 0}</span>
          </div>
        );
      },
    },
    {
      id: "behavior",
      header: "Behavior",
      cell: ({ row }) => {
        const s = row.original;
        return (
          <div className="flex flex-wrap gap-1">
            {s.multiple ? (
              <BehaviorChip label="Multi" />
            ) : (
              <BehaviorChip label="Single" muted />
            )}
            {s.meta?.searchable ? <BehaviorChip label="Searchable" /> : null}
            {s.meta?.clearable ? <BehaviorChip label="Clearable" /> : null}
          </div>
        );
      },
    },
    {
      id: "permissions",
      header: "Permissions",
      cell: ({ row }) => {
        const s = row.original;
        const perms = s.meta?.permissions ?? [];
        return (
          <div className="flex flex-wrap items-center gap-1">
            {perms.length === 0 ? (
              <span className="text-xs text-slate-400">—</span>
            ) : (
              perms.map((p) => (
                <span
                  key={p}
                  className="inline-flex items-center gap-1 rounded-full bg-primary/10 px-2 py-0.5 text-xs font-medium text-primary"
                >
                  <Shield />
                  {p}
                </span>
              ))
            )}
          </div>
        );
      },
    },
    {
      id: "actions",
      size: 40,
      cell: ({ row }) => {
        const setting = row.original;
        return (
          <div
            className="flex justify-end"
            onClick={(e) => e.stopPropagation()}
          >
            <DropdownMenu modal={false}>
              <DropdownMenuTrigger asChild>
                <Button variant="outline" size="icon">
                  <MoreHorizontal />
                </Button>
              </DropdownMenuTrigger>
              <DropdownMenuContent align="end">
                <DropdownMenuItem>
                  <Eye />
                  View
                </DropdownMenuItem>
                <DropdownMenuItem
                  onSelect={() => openDialogFor("options", setting)}
                >
                  <CheckCircle2 />
                  Options
                </DropdownMenuItem>
                <DropdownMenuSeparator />
                <DropdownMenuItem
                  onSelect={() => openDialogFor("edit", setting)}
                >
                  <Pencil />
                  Edit
                </DropdownMenuItem>
                <DropdownMenuSeparator />
                <DropdownMenuItem
                  onSelect={() => openDialogFor("delete", setting)}
                  variant="destructive"
                >
                  <Trash2 />
                  Delete
                </DropdownMenuItem>
              </DropdownMenuContent>
            </DropdownMenu>
          </div>
        );
      },
    },
  ];

  return (
    <div className="min-h-screen p-6">
      <div className="space-y-6">
        <Breadcrumbs
          items={[
            { label: "Admin", href: "/admin" },
            { label: "Dropdown Settings" },
          ]}
        />

        <Card className="p-6 flex-row justify-between">
          <div>
            <h1 className="text-3xl font-bold tracking-tight text-slate-900">
              Dropdown Settings
            </h1>
            <p className="mt-1 text-sm text-secondary-foreground">
              Manage every dynamic dropdown across the platform — labels,
              options, ordering, and permissions.
            </p>
          </div>

          <div className="flex flex-col items-stretch gap-3 sm:flex-row sm:items-center">
            <div className="relative w-full sm:w-80">
              <Search className="pointer-events-none absolute left-2 top-1/2 h-4 w-4 -translate-y-1/2 text-slate-400" />
              <Input
                type="search"
                value={query}
                onChange={(e) => {
                  setQuery(e.target.value);
                  setPagination({
                    pageIndex: 0,
                    pageSize: pagination.pageSize,
                  });
                }}
                placeholder="Search by code, label, description..."
                className="pl-8!"
              />
            </div>

            <EditDropdownSettingDialog mode="create">
              <Button>
                <Plus />
                New Setting
              </Button>
            </EditDropdownSettingDialog>
          </div>
        </Card>

        <div className="grid gap-4 md:grid-cols-4">
          <StatCard
            label="Settings"
            value={dropdownSettings.length}
            icon={<Settings />}
          />
          <StatCard
            label="Total Options"
            value={totalOptions}
            icon={<Boxes />}
          />
          <StatCard
            label="Multi-select"
            value={multipleCount}
            icon={<ListOrdered />}
          />
          <StatCard
            label="Searchable"
            value={searchableCount}
            icon={<Sparkles />}
          />
        </div>

        {isError ? (
          <Card>
            <CardContent className="flex items-center gap-3 py-6 text-sm text-red-600">
              <AlertCircle className="h-5 w-5" />
              Failed to load dropdown settings.{" "}
              {error instanceof Error ? error.message : "Unknown error."}
            </CardContent>
          </Card>
        ) : null}

        <Card className="gap-0">
          <CardHeader className="flex flex-row items-center justify-between border-b">
            <div>
              <CardTitle>Registered Dropdowns</CardTitle>
              <CardDescription>
                Every dynamic dropdown the platform reads from.
              </CardDescription>
            </div>

            <Button variant="secondary" size="sm">
              <Filter />
              Filter
            </Button>
          </CardHeader>

          <CardContent className="px-0">
            {isLoading ? (
              <div className="flex items-center justify-center py-12 text-sm text-slate-500">
                <Loader2 className="mr-2 h-4 w-4 animate-spin text-primary" />
                Loading dropdown settings…
              </div>
            ) : (
              <DataTable
                columns={columns}
                data={paginatedData}
                status={status}
                onRowClick={() => { }}
                pagination={{
                  pageIndex: pagination.pageIndex,
                  pageSize: pagination.pageSize,
                  pageCount: pageCount,
                  totalCount: total,
                }}
                tableOptions={{
                  state: { pagination },
                  onPaginationChange: setPagination,
                }}
                containerClassName="border-b shadow-none"
                footer={DataTableFooter}
              />
            )}
          </CardContent>
        </Card>
      </div>

      {/* Controlled dialogs — hoisted out of the DropdownMenu so they can open
          reliably after a menu item is selected. */}
      {activeSetting ? (
        <>
          <EditDropdownSettingDialog
            key={`edit-${activeSetting.id}`}
            mode="edit"
            setting={activeSetting}
            open={activeDialog === "edit"}
            onOpenChange={(next) => (next ? null : closeDialog())}
          />
          <ManageDropdownOptionsDialog
            key={`options-${activeSetting.id}`}
            setting={activeSetting}
            open={activeDialog === "options"}
            onOpenChange={(next) => (next ? null : closeDialog())}
          />
          <DeleteDropdownSettingDialog
            key={`delete-${activeSetting.id}`}
            settingLabel={activeSetting.label}
            settingCode={activeSetting.code}
            onConfirm={() => deleteMutation.mutate(activeSetting.id)}
            open={activeDialog === "delete"}
            onOpenChange={(next) => (next ? null : closeDialog())}
          />
        </>
      ) : null}
    </div>
  );
}

function StatCard({
  label,
  value,
  icon,
}: {
  label: string;
  value: number;
  icon: React.ReactNode;
}) {
  return (
    <Card>
      <CardContent className="flex items-center justify-between">
        <div>
          <p className="text-sm text-slate-500">{label}</p>
          <h3 className="mt-2 text-3xl font-bold text-slate-900">{value}</h3>
        </div>
        <div className="flex h-12 w-12 items-center justify-center rounded-2xl bg-primary/10 text-primary">
          {icon}
        </div>
      </CardContent>
    </Card>
  );
}

function BehaviorChip({
  label,
  muted = false,
}: {
  label: string;
  muted?: boolean;
}) {
  return (
    <span
      className={
        muted
          ? "rounded-full bg-slate-100 px-2 py-0.5 text-xs font-medium text-slate-600"
          : "rounded-full bg-primary/10 px-2 py-0.5 text-xs font-medium text-primary"
      }
    >
      {label}
    </span>
  );
}
