"use client";

import * as React from "react";
import { useFormStatus } from "react-dom";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { NativeSelect, NativeSelectOption } from "@/components/ui/native-select";
import { adminTexts } from "@/lib/i18n/admin";
import type { AdminActionFn, AdminMenuField } from "./types";

/** What the table asks the dialog to run once the admin confirms. */
export type PendingAction = {
  title: string;
  description?: string;
  fields?: AdminMenuField[];
  /** Extra hidden inputs (ids, row id, action key, …). */
  hidden: Record<string, string>;
  action: AdminActionFn;
  submitLabel: string;
  destructive?: boolean;
};

function SubmitButton({
  label,
  destructive,
}: {
  label: string;
  destructive?: boolean;
}) {
  const { pending } = useFormStatus();
  return (
    <Button
      type="submit"
      size="lg"
      variant={destructive ? "destructive" : "default"}
      disabled={pending}
    >
      {pending ? "…" : label}
    </Button>
  );
}

function FieldControl({ field }: { field: AdminMenuField }) {
  if (field.type === "hidden") {
    return <input type="hidden" name={field.name} value={field.defaultValue ?? ""} />;
  }

  const id = `admin-field-${field.name}`;

  return (
    <div className="space-y-1.5">
      <Label htmlFor={id} className="text-xs font-medium">
        {field.label}
      </Label>
      {field.type === "textarea" ? (
        <Textarea
          id={id}
          name={field.name}
          rows={4}
          required={field.required}
          placeholder={field.placeholder}
          defaultValue={field.defaultValue}
          className="text-sm"
        />
      ) : field.type === "select" ? (
        <NativeSelect
          id={id}
          name={field.name}
          required={field.required}
          defaultValue={field.defaultValue}
          className="w-full"
        >
          {(field.options ?? []).map((o) => (
            <NativeSelectOption key={o.value} value={o.value}>
              {o.label}
            </NativeSelectOption>
          ))}
        </NativeSelect>
      ) : (
        <Input
          id={id}
          name={field.name}
          type={field.type === "number" ? "number" : "text"}
          step={field.type === "number" ? "any" : undefined}
          required={field.required}
          placeholder={field.placeholder}
          defaultValue={field.defaultValue}
          className="h-8 text-sm"
        />
      )}
      {field.hint ? (
        <p className="text-[11px] text-muted-foreground">{field.hint}</p>
      ) : null}
    </div>
  );
}

/**
 * One dialog instance shared by the row menus and the bulk-action bar.
 * Handles both the "just confirm" and the "collect a few inputs" cases.
 */
export function AdminActionDialog({
  pending,
  onClose,
}: {
  pending: PendingAction | null;
  onClose: () => void;
}) {
  const open = pending !== null;

  async function run(formData: FormData) {
    if (!pending) return;
    try {
      const result = await pending.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 || adminTexts.common.none);
          return;
        }
      }
      onClose();
    } catch (e) {
      // A redirect() inside a server action rejects with a control-flow error —
      // let Next handle it instead of showing a bogus failure toast.
      if (e && typeof e === "object" && "digest" in e) throw e;
      toast.error(e instanceof Error ? e.message : "Action failed");
    }
  }

  return (
    <Dialog open={open} onOpenChange={(next) => (next ? null : onClose())}>
      <DialogContent className="sm:max-w-md">
        <form action={run} className="space-y-4">
          <DialogHeader>
            <DialogTitle className="text-base">{pending?.title}</DialogTitle>
            {pending?.description ? (
              <DialogDescription className="text-sm">
                {pending.description}
              </DialogDescription>
            ) : null}
          </DialogHeader>

          {Object.entries(pending?.hidden ?? {}).map(([name, value]) => (
            <input key={name} type="hidden" name={name} value={value} />
          ))}

          {pending?.fields?.length ? (
            <div className="space-y-3">
              {pending.fields.map((field) => (
                <FieldControl key={field.name} field={field} />
              ))}
            </div>
          ) : null}

          <DialogFooter>
            <Button type="button" variant="outline" size="lg" onClick={onClose}>
              {adminTexts.common.cancel}
            </Button>
            <SubmitButton
              label={pending?.submitLabel ?? adminTexts.table.run}
              destructive={pending?.destructive}
            />
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  );
}

export default AdminActionDialog;
