"use client";

import * as React from "react";

import {
  Clock3,
  KeyRound,
  Plus,
} from "lucide-react";
import Link from "next/link";
import { toast } from "sonner";

import { ListPageCard } from "@/app/dashboard/_components";
import { DeleteConfirmDialog } from "@/components/admins/rbac/delete-confirm-dialog";
import { ErrorBanner } from "@/components/shared/error-banner";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
  Sheet,
  SheetContent,
  SheetDescription,
  SheetHeader,
  SheetTitle,
} from "@/components/ui/sheet";
import {
  deletePermission,
  fetchPermissionCatalog,
  viewPermission,
} from "@/components/admins/rbac/api/permissions-api";
import { PermissionsCatalogTable } from "@/components/admins/rbac/permissions-catalog-table";
import type { PermissionCatalogEntry } from "@/components/admins/rbac/types";
import { formatDisplayDateTimeParts } from "@/lib/format/dates";

type PermissionsPageClientProps = {
  initialCatalog: PermissionCatalogEntry[];
  initialErrorMessage: string | null;
};

export function PermissionsPageClient({
  initialCatalog,
  initialErrorMessage,
}: PermissionsPageClientProps) {
  const [catalog, setCatalog] = React.useState<PermissionCatalogEntry[]>(initialCatalog);
  const [loading, setLoading] = React.useState(false);
  const [errorMessage, setErrorMessage] = React.useState<string | null>(initialErrorMessage);
  const [selectedPermission, setSelectedPermission] =
    React.useState<PermissionCatalogEntry | null>(null);
  const [viewingPermissionName, setViewingPermissionName] = React.useState<string | null>(null);
  const [deletingPermissionName, setDeletingPermissionName] = React.useState<string | null>(null);
  const [pendingDeleteName, setPendingDeleteName] = React.useState<string | null>(null);
  const [sheetOpen, setSheetOpen] = React.useState(false);

  const refresh = React.useCallback(async () => {
    setLoading(true);
    setErrorMessage(null);

    try {
      setCatalog(await fetchPermissionCatalog());
    } catch (error) {
      const message =
        error instanceof Error ? error.message : "Could not load permissions.";
      setErrorMessage(message);
      toast.error(message);
    } finally {
      setLoading(false);
    }
  }, []);

  const handleDeletePermission = React.useCallback(
    async (name: string) => {
      setDeletingPermissionName(name);

      try {
        const data = await deletePermission(name);

        toast.success(data.message ?? `Permission "${name}" deleted.`);
        setPendingDeleteName(null);
        await refresh();
      } catch (error) {
        const message =
          error instanceof Error ? error.message : "Could not delete permission.";
        toast.error(message);
      } finally {
        setDeletingPermissionName(null);
      }
    },
    [refresh],
  );

  const handleViewPermission = React.useCallback(async (name: string) => {
    setViewingPermissionName(name);
    setSheetOpen(true);
    setSelectedPermission(null);

    try {
      setSelectedPermission(await viewPermission(name));
    } catch (error) {
      const message =
        error instanceof Error ? error.message : "Could not load permission details.";
      toast.error(message);
      setSheetOpen(false);
    } finally {
      setViewingPermissionName(null);
    }
  }, []);

  return (
    <>
      <ListPageCard
        icon={KeyRound}
        title="Permissions"
        description="Catalog of atomic permissions used across roles and direct assignments."
        breadcrumb={[
          { label: "Admins & Access", href: "/dashboard/admins/users" },
          { label: "Permissions" },
        ]}
        actions={
          <div className="flex flex-wrap gap-2">
            <Button type="button" size="sm" asChild>
              <Link href="/dashboard/admins/access/permissions/form">
                <Plus className="size-4" />
                Create permission
              </Link>
            </Button>
            <Button
              type="button"
              size="sm"
              variant="outline"
              onClick={() => void refresh()}
              disabled={loading}
            >
              Refresh
            </Button>
          </div>
        }
      >
        {loading ? (
          <p className="text-muted-foreground text-sm">Loading permissions...</p>
        ) : errorMessage ? (
          <ErrorBanner message={errorMessage} />
        ) : null}
        <PermissionsCatalogTable
          data={catalog}
          onView={handleViewPermission}
          onDelete={setPendingDeleteName}
          viewingPermissionName={viewingPermissionName}
          deletingPermissionName={deletingPermissionName}
        />
      </ListPageCard>

      <Sheet open={sheetOpen} onOpenChange={setSheetOpen}>
        <SheetContent className="flex h-full !w-[min(800px,calc(100vw-1rem))] !max-w-none flex-col gap-0 overflow-hidden bg-muted/30 p-0">
          <SheetHeader className="shrink-0 border-b bg-card px-6 py-5 pr-14">
            <SheetTitle>Permission details</SheetTitle>
            <SheetDescription>
              Live permission metadata from the RBAC registry.
            </SheetDescription>
          </SheetHeader>

          <div className="min-h-0 flex-1 overflow-y-auto">
            {viewingPermissionName && !selectedPermission ? (
              <div className="space-y-6 px-6 py-6">
                <div className="h-36 animate-pulse rounded-2xl bg-muted" />
                <div className="grid grid-cols-3 gap-3">
                  <div className="h-20 animate-pulse rounded-xl bg-muted" />
                  <div className="h-20 animate-pulse rounded-xl bg-muted" />
                  <div className="h-20 animate-pulse rounded-xl bg-muted" />
                </div>
              </div>
            ) : selectedPermission ? (
              <div className="space-y-6 px-6 py-6">
                <PermissionDetail permission={selectedPermission} />
              </div>
            ) : null}
          </div>
        </SheetContent>
      </Sheet>

      <DeleteConfirmDialog
        open={Boolean(pendingDeleteName)}
        itemName={pendingDeleteName}
        title="Delete this permission?"
        itemType="permission"
        confirmLabel="Delete permission"
        isDeleting={Boolean(deletingPermissionName)}
        onOpenChange={(open) => {
          if (!open && !deletingPermissionName) setPendingDeleteName(null);
        }}
        onConfirm={() => {
          if (pendingDeleteName) void handleDeletePermission(pendingDeleteName);
        }}
      />
    </>
  );
}

function PermissionDetail({ permission }: { permission: PermissionCatalogEntry }) {
  const createdAt = formatDisplayDateTimeParts(permission.createdAt);
  const updatedAt = formatDisplayDateTimeParts(permission.updatedAt);

  return (
    <div className="space-y-6">
      <div className="overflow-hidden rounded-2xl border border-border/60 bg-card shadow-sm">
        <div className="bg-gradient-to-r from-primary/10 via-transparent to-transparent px-6 py-6">
          <div className="flex items-start gap-4">
            <div className="flex size-14 shrink-0 items-center justify-center rounded-2xl bg-foreground text-background shadow-md">
              <KeyRound className="size-6" />
            </div>
            <div className="min-w-0 flex-1">
              <div className="flex flex-wrap items-start justify-between gap-3">
                <div className="min-w-0">
                  <p className="break-all font-mono text-muted-foreground text-xs">
                    {permission.name}
                  </p>
                  <h2 className="mt-2 break-words font-semibold text-2xl tracking-tight">
                    {permission.label}
                  </h2>
                </div>
                <Badge variant="outline" className="shrink-0 bg-background/70">
                  {formatRoleCount(permission.usedByRoleCount)}
                </Badge>
              </div>

              <p className="mt-3 max-w-3xl break-words text-muted-foreground text-sm leading-6">
                {permission.description || "No description provided."}
              </p>
            </div>
          </div>
        </div>

        <div className="grid grid-cols-1 border-t border-border/60 bg-muted/50 sm:grid-cols-3">
          <MetricItem label="Used by" value={formatRoleCount(permission.usedByRoleCount)} />
          <MetricItem label="Created" value={createdAt.short} />
          <MetricItem label="Updated" value={updatedAt.short} />
        </div>
      </div>

      <div className="rounded-2xl border border-border/60 bg-card p-6 shadow-sm">
        <h3 className="font-semibold text-sm">Permission details</h3>
        <p className="mt-0.5 text-muted-foreground text-xs">Catalog information from the backend</p>

        <div className="mt-5 space-y-6">
          <DetailSection icon={Clock3} title="Timeline">
            <DetailItem label="Created" value={createdAt.long} />
            <DetailItem label="Updated" value={updatedAt.long} />
            <DetailItem label="Used by roles" value={formatRoleCount(permission.usedByRoleCount)} />
          </DetailSection>
        </div>
      </div>
    </div>
  );
}

function MetricItem({ label, value }: { label: string; value?: string | number | null }) {
  return (
    <div className="flex min-w-0 flex-col justify-center border-border/60 px-5 py-4 even:border-l md:[&:not(:first-child)]:border-l">
      <span className="text-muted-foreground text-xs font-medium">{label}</span>
      <span className="mt-2 break-words font-semibold text-sm tracking-tight">
        {value || "-"}
      </span>
    </div>
  );
}

function formatRoleCount(value: number) {
  return `${value} ${value === 1 ? "role" : "roles"}`;
}

function DetailSection({
  icon: Icon,
  title,
  children,
}: {
  icon: React.ComponentType<{ className?: string }>;
  title: string;
  children: React.ReactNode;
}) {
  return (
    <section>
      <p className="mb-3 flex items-center gap-2 text-muted-foreground text-xs font-semibold uppercase tracking-wide">
        <Icon className="size-3.5" />
        {title}
      </p>
      <dl className="grid gap-2 sm:grid-cols-2 lg:grid-cols-3">{children}</dl>
    </section>
  );
}

function DetailItem({
  label,
  value,
  mono = false,
}: {
  label: string;
  value?: string | number | null;
  mono?: boolean;
}) {
  return (
    <div className="group rounded-lg border border-transparent px-3 py-2.5 transition-colors hover:border-border/60 hover:bg-muted/40">
      <dt className="text-muted-foreground text-xs">{label}</dt>
      <dd
        className={
          mono ? "mt-1 break-all font-mono text-xs" : "mt-1 break-words text-sm font-medium"
        }
      >
        {value || "-"}
      </dd>
    </div>
  );
}

