"use client";

import * as React from "react";
import {
  CircleCheckIcon,
  PowerIcon,
  PowerOffIcon,
  XCircleIcon,
} from "lucide-react";

import { ConfirmDialog } from "@/components/ui/confirm-dialog";
import { Typography } from "@/components/ui/typography";
import { useUpdateProviderStatus } from "@/hooks/providers/useUpdateProviderStatus";
import { useTranslation } from "@/hooks/useTranslation";

import type { ProviderStatusAction } from "./lib/provider-status";

const ACTION_ICONS: Record<
  ProviderStatusAction["confirmKey"],
  React.ReactNode
> = {
  approve: <CircleCheckIcon />,
  activate: <PowerIcon />,
  deactivate: <PowerOffIcon />,
  reject: <XCircleIcon />,
};

interface ProviderStatusConfirmDialogProps {
  /** The pending action, or null when no dialog should be shown */
  action: ProviderStatusAction | null;
  providerId: string;
  providerName: string;
  onClose: () => void;
  /** Called after a successful status change (e.g. to refetch a detail view) */
  onUpdated?: () => void;
}

/**
 * Confirmation for every provider account status change (activate / suspend /
 * reject / move back to review). Used by both the list rows and the detail
 * header so the wording and behavior stay identical.
 *
 * Deliberately NOT in `requireReason` mode: `PUT /providers/admin/:id/status`
 * accepts only `status` and `customCommissionRate`, and the backend rejects
 * unknown body keys — so a reason collected here could not be persisted. The
 * dialog says as much instead of pretending it was recorded.
 */
export function ProviderStatusConfirmDialog({
  action,
  providerId,
  providerName,
  onClose,
  onUpdated,
}: ProviderStatusConfirmDialogProps) {
  const { t } = useTranslation();
  const updateStatus = useUpdateProviderStatus(providerId, {
    onSuccess: onUpdated,
  });

  // Retain the last action so the dialog keeps its copy while it animates out
  // (`action` is nulled the moment the dialog starts closing). This is React's
  // "adjust state during render" pattern — a ref would be read during render,
  // which the compiler rules correctly reject.
  const [lastAction, setLastAction] =
    React.useState<ProviderStatusAction | null>(null);
  if (action && action !== lastAction) setLastAction(action);

  const shown = action ?? lastAction;
  if (!shown) return null;

  return (
    <ConfirmDialog
      open={!!action}
      onOpenChange={(next) => {
        if (!next) onClose();
      }}
      icon={ACTION_ICONS[shown.confirmKey]}
      title={t(`providers.confirm.${shown.confirmKey}Title`)}
      description={
        <span className="flex flex-col gap-2">
          <span>
            {t(`providers.confirm.${shown.confirmKey}Description`, {
              name: providerName,
            })}
          </span>
          <Typography as="span" variant="caption" color="secondary">
            {t("providers.confirm.noteNotRecorded")}
          </Typography>
        </span>
      }
      confirmLabel={t(shown.labelKey)}
      destructive={shown.destructive}
      // Rejecting keeps the dialog open; the hook's onError toast explains why.
      onConfirm={() => updateStatus.mutateAsync({ status: shown.status })}
    />
  );
}
