"use client";

import * as React from "react";
import Link from "next/link";
import { MoreHorizontal } from "lucide-react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { adminTexts } from "@/lib/i18n/admin";
import type { AdminActionFn, AdminMenuItem } from "./types";
import type { PendingAction } from "./action-dialog";

/**
 * Per-row "⋯" dropdown. Simple actions submit a hidden form rendered outside
 * the menu (so closing the menu can never cancel the submit); actions with
 * `confirm` or `fields` hand a PendingAction to the table-level dialog.
 *
 * Every action form carries BOTH `id` and `ids` for the row, so a server action
 * written for bulk selection also works from a single row.
 */
export function AdminRowMenu({
  items,
  rowId,
  label,
  onRequest,
}: {
  items: AdminMenuItem[];
  rowId: string;
  label?: string;
  onRequest: (pending: PendingAction) => void;
}) {
  const forms = React.useRef<Record<number, HTMLFormElement | null>>({});

  const wrap = React.useCallback(
    (action: AdminActionFn) => async (formData: FormData) => {
      try {
        const result = await action(formData);
        if (result && typeof result === "object" && "ok" in result) {
          const r = result as { ok: boolean; error?: string };
          if (r.ok === false) toast.error(r.error || "Action failed");
        }
      } catch (e) {
        if (e && typeof e === "object" && "digest" in e) throw e;
        toast.error(e instanceof Error ? e.message : "Action failed");
      }
    },
    [],
  );

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

  return (
    <>
      {/* Hidden submit targets — kept outside DropdownMenuContent on purpose. */}
      {items.map((item, index) =>
        item.kind === "action" && !item.confirm && !item.fields?.length ? (
          <form
            key={`f-${index}`}
            ref={(el) => {
              forms.current[index] = el;
            }}
            action={wrap(item.action)}
            className="hidden"
          >
            <input type="hidden" name="id" value={rowId} />
            <input type="hidden" name="ids" value={rowId} />
            {Object.entries(item.values ?? {}).map(([name, value]) => (
              <input key={name} type="hidden" name={name} value={String(value)} />
            ))}
          </form>
        ) : null,
      )}

      <DropdownMenu>
        <DropdownMenuTrigger asChild>
          <Button
            type="button"
            variant="ghost"
            size="icon-sm"
            aria-label={label ?? adminTexts.table.rowActions}
          >
            <MoreHorizontal className="size-4" />
          </Button>
        </DropdownMenuTrigger>

        <DropdownMenuContent align="end" className="w-52">
          {items.map((item, index) => {
            if (item.kind === "separator") {
              return <DropdownMenuSeparator key={`s-${index}`} />;
            }
            if (item.kind === "label") {
              return (
                <DropdownMenuLabel key={`l-${index}`} className="text-[11px]">
                  {item.label}
                </DropdownMenuLabel>
              );
            }
            if (item.kind === "link") {
              return (
                <DropdownMenuItem
                  key={`k-${index}`}
                  asChild
                  disabled={item.disabled}
                  variant={item.variant === "destructive" ? "destructive" : "default"}
                >
                  <Link href={item.href} className="cursor-pointer">
                    {item.icon}
                    {item.label}
                  </Link>
                </DropdownMenuItem>
              );
            }

            const needsDialog = Boolean(item.confirm || item.fields?.length);
            return (
              <DropdownMenuItem
                key={`a-${index}`}
                disabled={item.disabled}
                variant={item.variant === "destructive" ? "destructive" : "default"}
                className="cursor-pointer"
                onSelect={() => {
                  if (!needsDialog) {
                    forms.current[index]?.requestSubmit();
                    return;
                  }
                  onRequest({
                    title: item.label,
                    description: item.confirm,
                    fields: item.fields,
                    hidden: {
                      id: rowId,
                      ids: rowId,
                      ...Object.fromEntries(
                        Object.entries(item.values ?? {}).map(([k, v]) => [
                          k,
                          String(v),
                        ]),
                      ),
                    },
                    action: item.action,
                    submitLabel: item.submitLabel ?? item.label,
                    destructive: item.variant === "destructive",
                  });
                }}
              >
                {item.icon}
                {item.label}
              </DropdownMenuItem>
            );
          })}
        </DropdownMenuContent>
      </DropdownMenu>
    </>
  );
}

export default AdminRowMenu;
