"use client";

import * as React from "react";

import { ChevronDown } from "lucide-react";

import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import {
  Collapsible,
  CollapsibleContent,
  CollapsibleTrigger,
} from "@/components/ui/collapsible";
import { cn } from "@/lib/utils";
import type { PermissionModule } from "@/config/rbac-permissions";

import { HighRiskBadge } from "./high-risk-badge";
import { RoleCapabilityBadge } from "./role-capability-badge";

function getAccentClass(selected: number, total: number) {
  if (selected === total) return "border-l-emerald-500";
  if (selected === 0) return "border-l-rose-400";
  return "border-l-amber-400";
}

function getChipClass(selected: number, total: number) {
  if (selected === total) return "bg-emerald-100 text-emerald-700 dark:bg-emerald-950 dark:text-emerald-300";
  if (selected === 0) return "bg-rose-100 text-rose-700 dark:bg-rose-950 dark:text-rose-300";
  return "bg-amber-100 text-amber-800 dark:bg-amber-950 dark:text-amber-300";
}

type Props = {
  module: PermissionModule;
  value: string[];
  onChange: (permissions: string[]) => void;
  readOnly?: boolean;
  query?: string;
  defaultOpen?: boolean;
  compact?: boolean;
};

export function PermissionModulePanel({
  module,
  value,
  onChange,
  readOnly = false,
  query = "",
  defaultOpen = false,
  compact = false,
}: Props) {
  const [open, setOpen] = React.useState(defaultOpen);

  const filteredPermissions = React.useMemo(() => {
    const q = query.trim().toLowerCase();
    if (!q) return module.permissions;
    return module.permissions.filter(
      (p) =>
        p.name.toLowerCase().includes(q) ||
        p.label.toLowerCase().includes(q) ||
        p.description.toLowerCase().includes(q),
    );
  }, [module.permissions, query]);

  if (filteredPermissions.length === 0) return null;

  const modulePermissionNames = module.permissions.map((p) => p.name);
  const selectedCount = modulePermissionNames.filter((name) => value.includes(name)).length;
  const totalCount = module.permissions.length;

  const togglePermission = (name: string, checked: boolean) => {
    if (readOnly) return;
    if (checked) {
      onChange([...new Set([...value, name])]);
    } else {
      onChange(value.filter((p) => p !== name));
    }
  };

  const selectAll = () => {
    if (readOnly) return;
    onChange([...new Set([...value, ...modulePermissionNames])]);
  };

  const clearAll = () => {
    if (readOnly) return;
    onChange(value.filter((p) => !modulePermissionNames.includes(p)));
  };

  return (
    <Collapsible open={open} onOpenChange={setOpen}>
      <div
        className={cn(
          "rounded-lg border border-l-4 bg-card",
          getAccentClass(selectedCount, totalCount),
        )}
      >
        <div className="flex flex-wrap items-center justify-between gap-2 px-4 py-3">
          <CollapsibleTrigger asChild>
            <button
              type="button"
              className="flex min-w-0 flex-1 items-center gap-2 text-left"
            >
              <ChevronDown
                className={cn("size-4 shrink-0 transition-transform", open && "rotate-180")}
              />
              <div className="min-w-0">
                <div className="font-medium text-sm">{module.label}</div>
                {!compact ? (
                  <div className="text-muted-foreground text-xs">{module.description}</div>
                ) : null}
              </div>
            </button>
          </CollapsibleTrigger>
          <div className="flex items-center gap-2">
            <span
              className={cn(
                "rounded-full px-2 py-0.5 text-xs font-medium",
                getChipClass(selectedCount, totalCount),
              )}
            >
              {selectedCount}/{totalCount}
            </span>
            {!readOnly ? (
              <>
                <Button type="button" variant="ghost" size="sm" className="h-7 text-xs" onClick={selectAll}>
                  All
                </Button>
                <Button type="button" variant="ghost" size="sm" className="h-7 text-xs" onClick={clearAll}>
                  None
                </Button>
              </>
            ) : null}
          </div>
        </div>
        <CollapsibleContent>
          <div className="grid gap-2 border-t px-4 py-3 sm:grid-cols-2">
            {filteredPermissions.map((permission) => {
              const checked = value.includes(permission.name);
              return (
                <label
                  key={permission.name}
                  className={cn(
                    "flex cursor-pointer items-start gap-2 rounded-md border p-2.5 transition-colors",
                    checked ? "border-primary/30 bg-primary/5" : "hover:bg-muted/50",
                    readOnly && "cursor-default opacity-80",
                  )}
                >
                  <Checkbox
                    checked={checked}
                    disabled={readOnly}
                    onCheckedChange={(v) => togglePermission(permission.name, v === true)}
                    className="mt-0.5"
                  />
                  <div className="min-w-0 flex-1">
                    <div className="flex flex-wrap items-center gap-1.5">
                      <span className="font-medium text-sm">{permission.label}</span>
                      {permission.highRisk ? <HighRiskBadge /> : null}
                      {permission.workflowTier === "suggest" ? (
                        <RoleCapabilityBadge capability="suggester" />
                      ) : null}
                      {permission.workflowTier === "review" ? (
                        <RoleCapabilityBadge capability="reviewer" />
                      ) : null}
                    </div>
                    <div className="font-mono text-muted-foreground text-xs">{permission.name}</div>
                    {!compact ? (
                      <div className="text-muted-foreground text-xs">{permission.description}</div>
                    ) : null}
                  </div>
                </label>
              );
            })}
          </div>
        </CollapsibleContent>
      </div>
    </Collapsible>
  );
}
