"use client";

import * as React from "react";

import { CalendarClock, Clock3, KeyRound, Layers3, ShieldCheck, UserRound, UsersRound } from "lucide-react";
import { toast } from "sonner";

import { ListPageCard } from "@/app/dashboard/_components";
import { deleteRole, viewRole } from "@/components/admins/rbac/api/roles-api";
import { DeleteConfirmDialog } from "@/components/admins/rbac/delete-confirm-dialog";
import { RolesHeaderActions, RolesTable } from "@/components/admins/rbac/roles-table";
import { ErrorBanner } from "@/components/shared/error-banner";
import type { Role } from "@/components/admins/rbac/types";
import { formatDisplayDateTime } from "@/lib/format/dates";
import { Badge } from "@/components/ui/badge";
import {
  Sheet,
  SheetContent,
  SheetDescription,
  SheetHeader,
  SheetTitle,
} from "@/components/ui/sheet";

type RolesPageClientProps = {
  initialRoles: Role[];
  initialErrorMessage: string | null;
};

export function RolesPageClient({
  initialRoles,
  initialErrorMessage,
}: RolesPageClientProps) {
  const [roles, setRoles] = React.useState<Role[]>(initialRoles);
  const [selectedRole, setSelectedRole] = React.useState<Role | null>(null);
  const [sheetOpen, setSheetOpen] = React.useState(false);
  const [viewingRoleName, setViewingRoleName] = React.useState<string | null>(null);
  const [pendingDeleteRole, setPendingDeleteRole] = React.useState<Role | null>(null);
  const [deletingRoleName, setDeletingRoleName] = React.useState<string | null>(null);

  const handleDelete = async (role: { id: string; name: string }) => {
    setDeletingRoleName(role.name);

    try {
      const data = await deleteRole(role.name);
      setRoles((current) => current.filter((item) => item.id !== role.id));
      setPendingDeleteRole(null);
      toast.success(data.message ?? `Role "${role.name}" deleted.`);
    } catch (error) {
      const message = error instanceof Error ? error.message : "Could not delete role.";
      toast.error(message);
    } finally {
      setDeletingRoleName(null);
    }
  };

  const handleViewRole = async (role: Role) => {
    setSheetOpen(true);
    setSelectedRole(null);
    setViewingRoleName(role.name);

    try {
      setSelectedRole(await viewRole(role.name));
    } catch (error) {
      const message = error instanceof Error ? error.message : "Could not load role details.";
      toast.error(message);
      setSheetOpen(false);
    } finally {
      setViewingRoleName(null);
    }
  };

  if (initialErrorMessage) {
    return <ErrorBanner message={initialErrorMessage} />;
  }

  return (
    <>
      <RolesTable
        data={roles}
        onDelete={setPendingDeleteRole}
        onView={(role) => void handleViewRole(role)}
      />

      <Sheet
        open={sheetOpen}
        onOpenChange={(open) => {
          setSheetOpen(open);
          if (!open) setSelectedRole(null);
        }}
      >
        <SheetContent className="flex h-full !w-[min(860px,calc(100vw-1rem))] !max-w-none flex-col gap-0 overflow-hidden bg-muted/40 p-0">
          <SheetHeader className="border-b px-6 py-5 pr-14">
            <SheetTitle>Role details</SheetTitle>
            <SheetDescription>
              View assigned permissions, modules, and role usage.
            </SheetDescription>
          </SheetHeader>

          {viewingRoleName && !selectedRole ? (
            <RoleDetailSkeleton />
          ) : selectedRole ? (
            <RoleDetail role={selectedRole} />
          ) : null}
        </SheetContent>
      </Sheet>

      <DeleteConfirmDialog
        open={Boolean(pendingDeleteRole)}
        itemName={pendingDeleteRole?.name ?? null}
        title="Delete this role?"
        itemType="role"
        confirmLabel="Delete role"
        isDeleting={Boolean(deletingRoleName)}
        onOpenChange={(open) => {
          if (!open && !deletingRoleName) setPendingDeleteRole(null);
        }}
        onConfirm={() => {
          if (pendingDeleteRole) void handleDelete(pendingDeleteRole);
        }}
      />
    </>
  );
}

function RoleDetail({ role }: { role: Role }) {
  const permissionCount = role.permissionCount ?? role.permissions.length;
  const createdAt = formatDisplayDateTime(role.createdAt);
  const updatedAt = formatDisplayDateTime(role.updatedAt);
  const initials = getRoleInitials(role.name);

  return (
    <div className="min-h-0 flex-1 space-y-5 overflow-y-auto px-6 py-6">
      <section className="overflow-hidden rounded-[2rem] border bg-card shadow-sm">
        <div className="relative border-b bg-[radial-gradient(circle_at_top_right,hsl(var(--primary)/0.18),transparent_36%),linear-gradient(135deg,hsl(var(--background)),hsl(var(--muted)))] px-6 py-6">
          <div className="absolute -top-16 -right-12 size-44 rounded-full bg-primary/10 blur-3xl" />
          <div className="relative flex flex-wrap items-start justify-between gap-5">
            <div className="flex min-w-0 items-start gap-4">
              <div className="relative flex size-16 shrink-0 items-center justify-center rounded-3xl bg-foreground text-background shadow-lg">
                <span className="font-semibold text-lg">{initials}</span>
                <div className="-right-1 -bottom-1 absolute flex size-7 items-center justify-center rounded-full border-2 border-card bg-primary text-primary-foreground">
                  <ShieldCheck className="size-3.5" />
                </div>
              </div>
              <div className="min-w-0">
                <div className="flex flex-wrap items-center gap-2">
                  <Badge variant={role.type === "custom" ? "secondary" : "outline"} className="capitalize">
                    {role.type}
                  </Badge>
                  {role.capability ? <Badge variant="outline">{role.capability}</Badge> : null}
                </div>
                <h2 className="mt-3 break-words font-semibold text-3xl tracking-tight">{role.name}</h2>
                <p className="mt-1 break-all font-mono text-muted-foreground text-xs">{role.id}</p>
                <p className="mt-4 max-w-2xl text-muted-foreground text-sm leading-6">
                  {role.description || "No description provided."}
                </p>
              </div>
            </div>
          </div>
        </div>

        <div className="grid gap-3 bg-muted/30 p-4 sm:grid-cols-3">
          <SummaryCard icon={KeyRound} label="Permissions" value={permissionCount} />
          <SummaryCard icon={UsersRound} label="Staff" value={role.assignedStaffCount} />
          <SummaryCard icon={UserRound} label="Customers" value={role.assignedCustomerCount} />
        </div>
      </section>

      <SectionCard icon={Clock3} title="Timeline" description="Creation and last update timestamps.">
        <div className="mt-4 grid gap-3 sm:grid-cols-2">
          <SummaryTextCard icon={CalendarClock} label="Created" value={createdAt} />
          <SummaryTextCard icon={Clock3} label="Updated" value={updatedAt} />
        </div>
      </SectionCard>

      <SectionCard icon={Layers3} title="Modules" description="Grouped permission actions by module.">
        <div className="mt-4 flex flex-wrap gap-2.5">
          {role.modules?.length ? (
            role.modules.map((module) => (
              <span
                key={module}
                className="inline-flex items-center gap-2 rounded-full border bg-background px-3 py-1.5 font-medium text-sm shadow-xs"
              >
                <Layers3 className="size-3.5 text-primary" />
                {module}
              </span>
            ))
          ) : (
            <p className="text-muted-foreground text-sm">No module breakdown available.</p>
          )}
        </div>
      </SectionCard>

      <SectionCard icon={KeyRound} title="Permissions" description="Atomic permissions assigned to this role.">
        <div className="mt-4 flex flex-wrap gap-2.5">
          {role.permissions.map((permission) => (
            <Badge
              key={permission}
              variant="outline"
              className="rounded-full bg-background px-3 py-1 font-mono shadow-xs"
            >
              {permission}
            </Badge>
          ))}
        </div>
      </SectionCard>
    </div>
  );
}

function SummaryCard({
  icon: Icon,
  label,
  value,
}: {
  icon: React.ComponentType<{ className?: string }>;
  label: string;
  value: number;
}) {
  return (
    <div className="group rounded-2xl border bg-background p-4 shadow-xs transition-colors hover:bg-background/80">
      <div className="flex items-center justify-between gap-3">
        <p className="text-muted-foreground text-xs">{label}</p>
        <div className="flex size-9 items-center justify-center rounded-2xl bg-muted text-foreground transition-colors group-hover:bg-primary/10 group-hover:text-primary">
          <Icon className="size-4" />
        </div>
      </div>
      <p className="mt-2 font-semibold text-2xl tracking-tight">{value}</p>
    </div>
  );
}

function SummaryTextCard({
  icon: Icon,
  label,
  value,
}: {
  icon: React.ComponentType<{ className?: string }>;
  label: string;
  value: string;
}) {
  return (
    <div className="rounded-2xl border bg-background p-4 shadow-xs">
      <div className="flex items-center gap-2 text-muted-foreground text-xs">
        <Icon className="size-3.5" />
        {label}
      </div>
      <p className="mt-2 font-medium text-sm">{value}</p>
    </div>
  );
}

function SectionCard({
  icon: Icon,
  title,
  description,
  children,
}: {
  icon: React.ComponentType<{ className?: string }>;
  title: string;
  description: string;
  children: React.ReactNode;
}) {
  return (
    <section className="rounded-[1.75rem] border bg-card p-5 shadow-sm">
      <div className="flex items-start gap-3">
        <div className="flex size-10 shrink-0 items-center justify-center rounded-2xl bg-muted text-foreground">
          <Icon className="size-4" />
        </div>
        <div>
          <h3 className="font-semibold text-sm">{title}</h3>
          <p className="mt-0.5 text-muted-foreground text-xs">{description}</p>
        </div>
      </div>
      {children}
    </section>
  );
}

function RoleDetailSkeleton() {
  return (
    <div className="min-h-0 flex-1 space-y-6 overflow-y-auto bg-muted/30 px-6 py-6">
      <div className="h-48 animate-pulse rounded-2xl bg-muted" />
      <div className="h-32 animate-pulse rounded-2xl bg-muted" />
      <div className="h-64 animate-pulse rounded-2xl bg-muted" />
    </div>
  );
}

function getRoleInitials(value: string) {
  const initials = value
    .split(/[_\s-]+/)
    .filter(Boolean)
    .slice(0, 2)
    .map((part) => part[0]?.toUpperCase())
    .join("");

  return initials || "R";
}

export function RolesPageShell({ children }: { children: React.ReactNode }) {
  return (
    <ListPageCard
      icon={ShieldCheck}
      title="Roles"
      description="Permission containers for backend staff and corporate customers. Templates are seeded; custom roles can be created."
      breadcrumb={[
        { label: "Admins & Access", href: "/dashboard/admins/users" },
        { label: "Roles" },
      ]}
      actions={<RolesHeaderActions />}
    >
      {children}
    </ListPageCard>
  );
}
