"use client";

import * as React from "react";

import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogMedia,
  AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Typography } from "@/components/ui/typography";
import { useTranslation } from "@/hooks/useTranslation";
import { cn } from "@/lib/utils";

interface ConfirmDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  /** Already-translated title — pass `t("...")` */
  title: React.ReactNode;
  /** Already-translated description */
  description?: React.ReactNode;
  /** Optional icon rendered in the dialog media circle */
  icon?: React.ReactNode;
  /** Defaults to `t("common.confirm")` */
  confirmLabel?: React.ReactNode;
  /** Defaults to `t("common.cancel")` */
  cancelLabel?: React.ReactNode;
  /** Renders the confirm button in the destructive style */
  destructive?: boolean;
  /**
   * Reason mode: adds a required textarea and passes its value to `onConfirm`.
   * Used for decline order / reject provider / suspend account flows.
   */
  requireReason?: boolean;
  /** Defaults to `t("confirmDialog.reasonLabel")` */
  reasonLabel?: React.ReactNode;
  /** Defaults to `t("confirmDialog.reasonPlaceholder")` */
  reasonPlaceholder?: string;
  /**
   * Confirm handler — may be async; the dialog shows a loading state and only
   * closes after it resolves (stays open if it throws, so the caller's toast
   * can explain the failure). Receives the trimmed reason in reason mode.
   */
  onConfirm: (reason?: string) => void | Promise<void>;
}

/**
 * Reusable confirmation dialog (controlled). Covers both the plain
 * confirm/cancel case and the "confirm with required reason" case.
 *
 *   const [open, setOpen] = useState(false)
 *   <ConfirmDialog
 *     open={open}
 *     onOpenChange={setOpen}
 *     title={t("auth.logoutConfirm.title")}
 *     description={t("auth.logoutConfirm.description")}
 *     destructive
 *     onConfirm={logout}
 *   />
 */
function ConfirmDialog({
  open,
  onOpenChange,
  title,
  description,
  icon,
  confirmLabel,
  cancelLabel,
  destructive = false,
  requireReason = false,
  reasonLabel,
  reasonPlaceholder,
  onConfirm,
}: ConfirmDialogProps) {
  const { t } = useTranslation();
  const [submitting, setSubmitting] = React.useState(false);
  const [reason, setReason] = React.useState("");
  const [reasonError, setReasonError] = React.useState(false);

  /** Reset transient state on every close (cancel, backdrop, confirm success) */
  function handleOpenChange(nextOpen: boolean) {
    if (!nextOpen) {
      setSubmitting(false);
      setReason("");
      setReasonError(false);
    }
    onOpenChange(nextOpen);
  }

  async function handleConfirm() {
    const trimmedReason = reason.trim();
    if (requireReason && !trimmedReason) {
      setReasonError(true);
      return;
    }

    try {
      setSubmitting(true);
      await onConfirm(requireReason ? trimmedReason : undefined);
      handleOpenChange(false);
    } catch {
      // Deliberately swallowed. A throwing `onConfirm` means "keep the dialog
      // open" (documented above) so the user can retry or cancel — the caller's
      // own onError toast explains what failed. Re-throwing here would only
      // surface as an unhandled rejection from the click handler.
    } finally {
      setSubmitting(false);
    }
  }

  return (
    <AlertDialog open={open} onOpenChange={handleOpenChange}>
      <AlertDialogContent>
        <AlertDialogHeader>
          {icon && (
            <AlertDialogMedia
              className={cn(
                "rounded-full",
                destructive
                  ? "bg-mistake-light text-destructive"
                  : "bg-information-light text-primary-blue",
              )}
            >
              {icon}
            </AlertDialogMedia>
          )}
          <AlertDialogTitle>{title}</AlertDialogTitle>
          {description && (
            <AlertDialogDescription>{description}</AlertDialogDescription>
          )}
        </AlertDialogHeader>

        {requireReason && (
          <div className="flex flex-col gap-1.5">
            <Label htmlFor="confirm-dialog-reason">
              {reasonLabel ?? t("confirmDialog.reasonLabel")}
            </Label>
            <Textarea
              id="confirm-dialog-reason"
              value={reason}
              placeholder={
                reasonPlaceholder ?? t("confirmDialog.reasonPlaceholder")
              }
              aria-invalid={reasonError}
              disabled={submitting}
              onChange={(event) => {
                setReason(event.target.value);
                if (reasonError && event.target.value.trim())
                  setReasonError(false);
              }}
            />
            {reasonError && (
              <Typography
                as="p"
                variant="caption"
                className="text-destructive mt-0.5"
              >
                {t("confirmDialog.reasonRequired")}
              </Typography>
            )}
          </div>
        )}

        <AlertDialogFooter>
          <AlertDialogCancel disabled={submitting}>
            {cancelLabel ?? t("common.cancel")}
          </AlertDialogCancel>
          <AlertDialogAction
            variant={destructive ? "destructive" : "default"}
            loading={submitting}
            disabled={submitting}
            onClick={handleConfirm}
          >
            {confirmLabel ?? t("common.confirm")}
          </AlertDialogAction>
        </AlertDialogFooter>
      </AlertDialogContent>
    </AlertDialog>
  );
}

export { ConfirmDialog };
export type { ConfirmDialogProps };
