"use client";

import { useState } from "react";
import { useTranslations } from "next-intl";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { Plus, Pencil, Trash2, Users, ShieldCheck } from "lucide-react";
import { apiDelete, apiGet, apiPatch, apiPost } from "@/lib/api/client";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { useConfirm } from "@/components/providers/confirm-provider";
import { cn } from "@/lib/utils";

// ─── Types ────────────────────────────────────────────────────────────────────

interface CustomRoleDto {
  id: string;
  name: string;
  description?: string | null;
  color?: string | null;
  permissions: string[];
  employeeCount: number;
  createdAt: string;
}

// ─── Permission catalogue ─────────────────────────────────────────────────────

interface PermGroup {
  labelKey: string;
  perms: string[];
}

const PERM_GROUPS: PermGroup[] = [
  {
    labelKey: "customRoles.groupAdmin",
    perms: [
      "ViewCafeSettings", "ManageCafeSettings", "ManageDiscoverProfile",
      "ViewBilling", "ManageBilling", "ManageRoles",
      "ViewPrintSettings", "ManagePrintSettings",
    ],
  },
  {
    labelKey: "customRoles.groupBranches",
    perms: ["ViewBranches", "CreateBranch", "EditBranch", "DeleteBranch"],
  },
  {
    labelKey: "customRoles.groupMenu",
    perms: ["ViewMenu", "CreateMenuItem", "EditMenuItem", "DeleteMenuItem"],
  },
  {
    labelKey: "customRoles.groupInventory",
    perms: ["ViewInventory", "CreateInventory", "EditInventory", "DeleteInventory"],
  },
  {
    labelKey: "customRoles.groupTaxes",
    perms: ["ViewTaxes", "CreateTax", "EditTax", "DeleteTax"],
  },
  {
    labelKey: "customRoles.groupStaff",
    perms: [
      "ViewStaff", "CreateStaff", "EditStaff", "DeleteStaff",
      "ManageStaff", "ManageStaffCredentials",
      "ViewAttendance", "ManageAttendance",
      "ViewSchedules", "ManageSchedules",
      "ViewLeave", "ReviewLeave",
      "ViewSalaries", "ManageSalaries",
    ],
  },
  {
    labelKey: "customRoles.groupTables",
    perms: [
      "ViewTables", "ManageTables",
      "ViewReservations", "CreateReservation", "EditReservation", "DeleteReservation",
    ],
  },
  {
    labelKey: "customRoles.groupOrders",
    perms: [
      "ViewOrders", "ProcessOrders", "EditOrder", "VoidOrder", "RefundOrder",
      "ApplyDiscount", "CompOrder", "HandlePayments", "UpdateOrderStatus",
    ],
  },
  {
    labelKey: "customRoles.groupRegister",
    perms: ["OperateRegister", "OpenCashDrawer"],
  },
  {
    labelKey: "customRoles.groupQueueKitchen",
    perms: ["ViewQueue", "ManageQueue", "ViewKitchen", "ManageKitchenStations"],
  },
  {
    labelKey: "customRoles.groupDelivery",
    perms: ["ViewDelivery", "HandleDelivery", "AssignDelivery"],
  },
  {
    labelKey: "customRoles.groupCustomers",
    perms: ["ViewCustomers", "CreateCustomer", "EditCustomer", "DeleteCustomer"],
  },
  {
    labelKey: "customRoles.groupCoupons",
    perms: ["ViewCoupons", "CreateCoupon", "EditCoupon", "DeleteCoupon"],
  },
  {
    labelKey: "customRoles.groupMarketing",
    perms: ["ViewSms", "SendSms", "ManageSmsSettings", "ViewReviews", "ManageReviews"],
  },
  {
    labelKey: "customRoles.groupReports",
    perms: ["ViewReports", "ExportReports", "ViewAuditLog", "ViewFinancials", "ManageFinancials"],
  },
  {
    labelKey: "customRoles.groupExpenses",
    perms: ["ViewExpenses", "CreateExpense", "EditExpense", "DeleteExpense"],
  },
];

const PRESET_COLORS = [
  "#6366F1", "#8B5CF6", "#EC4899", "#F59E0B",
  "#10B981", "#3B82F6", "#EF4444", "#64748B",
];

// ─── Permission checkbox matrix ───────────────────────────────────────────────

function PermissionMatrix({
  selected,
  onChange,
  t,
}: {
  selected: Set<string>;
  onChange: (next: Set<string>) => void;
  t: ReturnType<typeof useTranslations>;
}) {
  const toggle = (perm: string) => {
    const next = new Set(selected);
    if (next.has(perm)) next.delete(perm);
    else next.add(perm);
    onChange(next);
  };

  const toggleGroup = (perms: string[]) => {
    const allOn = perms.every((p) => selected.has(p));
    const next = new Set(selected);
    if (allOn) perms.forEach((p) => next.delete(p));
    else perms.forEach((p) => next.add(p));
    onChange(next);
  };

  return (
    <div className="space-y-3">
      {PERM_GROUPS.map((group) => {
        const allOn = group.perms.every((p) => selected.has(p));
        const someOn = group.perms.some((p) => selected.has(p));
        return (
          <div key={group.labelKey} className="rounded-lg border border-border p-3">
            <button
              type="button"
              onClick={() => toggleGroup(group.perms)}
              className="mb-2 flex w-full cursor-pointer items-center gap-2 text-start"
            >
              <span
                className={cn(
                  "flex h-4 w-4 shrink-0 items-center justify-center rounded border text-[10px] font-bold transition-colors",
                  allOn
                    ? "border-primary bg-primary text-primary-foreground"
                    : someOn
                      ? "border-primary bg-primary/20 text-primary"
                      : "border-border bg-background"
                )}
              >
                {allOn ? "✓" : someOn ? "−" : ""}
              </span>
              <span className="text-xs font-semibold text-foreground">
                {t(group.labelKey)}
              </span>
            </button>
            <div className="grid grid-cols-2 gap-1.5 ps-6 sm:grid-cols-3">
              {group.perms.map((perm) => (
                <label key={perm} className="flex cursor-pointer items-center gap-1.5">
                  <input
                    type="checkbox"
                    checked={selected.has(perm)}
                    onChange={() => toggle(perm)}
                    className="accent-primary"
                  />
                  <span className="text-[11px] text-muted-foreground">
                    {t(`customRoles.perm.${perm}`)}
                  </span>
                </label>
              ))}
            </div>
          </div>
        );
      })}
    </div>
  );
}

// ─── Create / Edit form ───────────────────────────────────────────────────────

function RoleForm({
  cafeId,
  role,
  onDone,
  t,
  tCommon,
}: {
  cafeId: string;
  role?: CustomRoleDto;
  onDone: () => void;
  t: ReturnType<typeof useTranslations>;
  tCommon: ReturnType<typeof useTranslations>;
}) {
  const qc = useQueryClient();
  const [name, setName] = useState(role?.name ?? "");
  const [description, setDescription] = useState(role?.description ?? "");
  const [color, setColor] = useState(role?.color ?? PRESET_COLORS[0]!);
  const [perms, setPerms] = useState<Set<string>>(new Set(role?.permissions ?? []));
  const [error, setError] = useState<string | null>(null);

  const save = useMutation({
    mutationFn: async () => {
      const body = {
        name: name.trim(),
        description: description.trim() || null,
        color,
        permissions: Array.from(perms),
      };
      if (role) {
        return apiPatch(`/api/cafes/${cafeId}/custom-roles/${role.id}`, body);
      }
      return apiPost(`/api/cafes/${cafeId}/custom-roles`, body);
    },
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ["custom-roles", cafeId] });
      onDone();
    },
    onError: () => setError(t("customRoles.saveError")),
  });

  return (
    <div className="space-y-4">
      {/* Name + color */}
      <div className="flex gap-3">
        <div className="flex-1 space-y-1">
          <label className="text-xs font-medium">{t("customRoles.name")}</label>
          <Input
            value={name}
            onChange={(e) => setName(e.target.value)}
            placeholder={t("customRoles.namePlaceholder")}
            maxLength={100}
          />
        </div>
        <div className="space-y-1">
          <label className="text-xs font-medium">{t("customRoles.color")}</label>
          <div className="flex flex-wrap gap-1.5">
            {PRESET_COLORS.map((c) => (
              <button
                key={c}
                type="button"
                onClick={() => setColor(c)}
                className={cn(
                  "h-7 w-7 cursor-pointer rounded-full border-2 transition-transform",
                  color === c ? "border-foreground scale-110" : "border-transparent"
                )}
                style={{ backgroundColor: c }}
                aria-label={c}
              />
            ))}
          </div>
        </div>
      </div>

      {/* Description */}
      <div className="space-y-1">
        <label className="text-xs font-medium">{t("customRoles.description")}</label>
        <Input
          value={description}
          onChange={(e) => setDescription(e.target.value)}
          placeholder={t("customRoles.descriptionPlaceholder")}
          maxLength={200}
        />
      </div>

      {/* Permissions */}
      <div className="space-y-1">
        <p className="text-xs font-medium">{t("customRoles.permissions")}</p>
        <PermissionMatrix selected={perms} onChange={setPerms} t={t} />
      </div>

      {error && <p className="text-sm text-destructive">{error}</p>}

      <div className="flex justify-end gap-2 pt-1">
        <Button variant="outline" onClick={onDone} disabled={save.isPending}>
          {tCommon("cancel")}
        </Button>
        <Button
          onClick={() => save.mutate()}
          disabled={save.isPending || !name.trim()}
        >
          {save.isPending ? tCommon("saving") : tCommon("save")}
        </Button>
      </div>
    </div>
  );
}

// ─── Main panel ───────────────────────────────────────────────────────────────

export function CustomRolesPanel({ cafeId }: { cafeId: string }) {
  const t = useTranslations("settings");
  const tCommon = useTranslations("common");
  const qc = useQueryClient();
  const confirm = useConfirm();
  const [editing, setEditing] = useState<CustomRoleDto | null | "new">(null);

  const { data: roles = [], isLoading } = useQuery<CustomRoleDto[]>({
    queryKey: ["custom-roles", cafeId],
    queryFn: () => apiGet(`/api/cafes/${cafeId}/custom-roles`),
  });

  const deleteRole = useMutation({
    mutationFn: (id: string) => apiDelete(`/api/cafes/${cafeId}/custom-roles/${id}`),
    onSuccess: () => qc.invalidateQueries({ queryKey: ["custom-roles", cafeId] }),
  });

  const handleDelete = async (role: CustomRoleDto) => {
    const ok = await confirm({
      description: t("customRoles.deleteConfirm", { name: role.name }),
      variant: "destructive",
      confirmLabel: tCommon("confirm"),
    });
    if (!ok) return;
    deleteRole.mutate(role.id);
  };

  if (editing !== null) {
    return (
      <Card>
        <CardHeader className="pb-3">
          <CardTitle className="text-base">
            {editing === "new" ? t("customRoles.newRole") : t("customRoles.editRole")}
          </CardTitle>
        </CardHeader>
        <CardContent>
          <RoleForm
            cafeId={cafeId}
            role={editing === "new" ? undefined : editing}
            onDone={() => setEditing(null)}
            t={t}
            tCommon={tCommon}
          />
        </CardContent>
      </Card>
    );
  }

  return (
    <div className="space-y-4">
      <Card>
        <CardHeader className="flex flex-row items-center justify-between gap-2 pb-3">
          <div>
            <CardTitle className="flex items-center gap-2 text-base">
              <ShieldCheck className="size-4 text-primary" />
              {t("customRoles.title")}
            </CardTitle>
            <p className="mt-0.5 text-xs text-muted-foreground">
              {t("customRoles.subtitle")}
            </p>
          </div>
          <Button size="sm" className="shrink-0 gap-1.5" onClick={() => setEditing("new")}>
            <Plus className="size-4" />
            {t("customRoles.newRole")}
          </Button>
        </CardHeader>
        <CardContent>
          {isLoading ? (
            <div className="space-y-2">
              {[0, 1, 2].map((i) => (
                <div key={i} className="h-16 animate-pulse rounded-lg bg-muted" />
              ))}
            </div>
          ) : roles.length === 0 ? (
            <p className="py-6 text-center text-sm text-muted-foreground">
              {t("customRoles.empty")}
            </p>
          ) : (
            <div className="space-y-2">
              {roles.map((role) => (
                <div
                  key={role.id}
                  className="flex items-start gap-3 rounded-lg border border-border p-3"
                >
                  {/* Color dot */}
                  <div
                    className="mt-0.5 h-3 w-3 shrink-0 rounded-full"
                    style={{ backgroundColor: role.color ?? "#6366F1" }}
                  />

                  <div className="min-w-0 flex-1">
                    <div className="flex items-center gap-2">
                      <span className="text-sm font-semibold">{role.name}</span>
                      {role.description && (
                        <span className="truncate text-xs text-muted-foreground">
                          — {role.description}
                        </span>
                      )}
                    </div>

                    {/* Permission badges */}
                    <div className="mt-1.5 flex flex-wrap gap-1">
                      {role.permissions.slice(0, 6).map((p) => (
                        <Badge key={p} variant="secondary" className="text-[10px]">
                          {t(`customRoles.perm.${p}`)}
                        </Badge>
                      ))}
                      {role.permissions.length > 6 && (
                        <Badge variant="outline" className="text-[10px]">
                          +{role.permissions.length - 6}
                        </Badge>
                      )}
                    </div>
                  </div>

                  {/* Employee count */}
                  <div className="flex shrink-0 items-center gap-1 text-xs text-muted-foreground">
                    <Users className="size-3.5" />
                    {role.employeeCount}
                  </div>

                  {/* Actions */}
                  <div className="flex shrink-0 gap-1">
                    <Button
                      size="icon"
                      variant="ghost"
                      className="h-8 w-8"
                      onClick={() => setEditing(role)}
                    >
                      <Pencil className="size-3.5" />
                    </Button>
                    <Button
                      size="icon"
                      variant="ghost"
                      className="h-8 w-8 text-destructive hover:text-destructive"
                      onClick={() => handleDelete(role)}
                      disabled={deleteRole.isPending}
                    >
                      <Trash2 className="size-3.5" />
                    </Button>
                  </div>
                </div>
              ))}
            </div>
          )}
        </CardContent>
      </Card>
    </div>
  );
}
