'use client';

import { useState } from 'react';
import {
  useAdminRetryPayout,
  useAdminVoidPayout,
} from '@/lib/queries/use-admin-financials';
import { useEscapeToClose } from '@/lib/hooks/use-escape-to-close';

export type PayoutActionKind = 'retry' | 'void';

interface Props {
  open: boolean;
  kind: PayoutActionKind;
  payoutId: string;
  /**
   * Stripe/processor failure reason from the previous payout attempt. Echoed
   * back in the retry dialog so the admin sees why the last run failed before
   * choosing to re-fire — gives context for whether a retry is reasonable now
   * versus voiding instead.
   */
  failureReason?: string | null;
  onClose: () => void;
  onSuccess?: () => void;
}

/**
 * Modal for retry / void actions on the admin payouts queue. Void requires a
 * ≥ 10-character resolution note (compliance + audit trail); retry's note is
 * optional but still threaded through to the API when the admin types one.
 *
 * The success path closes the modal and lets parent re-render via the
 * mutation hooks' onSuccess invalidations.
 */
export function AdminPayoutActionDialog({
  open,
  kind,
  payoutId,
  failureReason,
  onClose,
  onSuccess,
}: Props) {
  const [note, setNote] = useState('');
  const [error, setError] = useState<string | null>(null);

  const retry = useAdminRetryPayout();
  const void_ = useAdminVoidPayout();
  const isPending = retry.isPending || void_.isPending;

  useEscapeToClose(open, onClose);

  if (!open) return null;

  const noteOk = kind === 'void' ? note.trim().length >= 10 : true;
  const disabled = !noteOk || isPending;

  const submit = async () => {
    setError(null);
    try {
      if (kind === 'retry') {
        await retry.mutateAsync({
          payoutId,
          body: note.trim() ? { resolution_note: note.trim() } : {},
        });
      } else {
        await void_.mutateAsync({
          payoutId,
          body: { resolution_note: note.trim() },
        });
      }
      onSuccess?.();
      setNote('');
      onClose();
    } catch (e) {
      setError((e as Error).message ?? 'Action failed.');
    }
  };

  const isRetry = kind === 'retry';

  return (
    <div
      role="dialog"
      aria-modal="true"
      aria-label={isRetry ? 'Retry payout' : 'Void payout'}
      className="fixed inset-0 z-50 flex items-center justify-center bg-slate-900/50 p-4"
    >
      <div className="w-full max-w-md rounded-lg bg-white p-6 shadow-xl">
        <h2 className="text-lg font-semibold text-slate-900">
          {isRetry ? 'Retry payout' : 'Void payout'}
        </h2>
        <p className="mt-1 text-xs text-slate-500">
          Payout <span className="font-mono">{payoutId.slice(0, 8)}</span>
        </p>

        {isRetry && failureReason && (
          <p
            className="mt-3 rounded-md bg-slate-50 p-3 text-sm text-slate-600"
            data-testid="admin-payout-action-failure-reason"
          >
            <span className="block text-xs font-medium text-slate-500">
              Previous attempt failed
            </span>
            <span className="italic">{failureReason}</span>
          </p>
        )}

        <label className="mt-4 block">
          <span className="text-sm font-medium text-slate-700">
            Resolution note{' '}
            {isRetry ? (
              <span className="text-slate-400">(optional)</span>
            ) : (
              <span className="text-slate-500">(≥ 10 chars, required)</span>
            )}
          </span>
          <textarea
            data-testid="admin-payout-action-note"
            value={note}
            onChange={(e) => setNote(e.target.value)}
            rows={4}
            maxLength={2000}
            className="mt-1 block w-full rounded-md border border-slate-300 p-2 text-sm"
          />
        </label>

        {error && (
          <p
            className="mt-2 text-sm text-red-600"
            data-testid="admin-payout-action-error"
          >
            {error}
          </p>
        )}

        <div className="mt-4 flex justify-end gap-2">
          <button
            type="button"
            onClick={onClose}
            className="rounded-md border border-slate-300 px-4 py-2 text-sm text-slate-700 hover:bg-slate-50"
          >
            Cancel
          </button>
          <button
            type="button"
            onClick={submit}
            disabled={disabled}
            data-testid="admin-payout-action-submit"
            className={`rounded-md px-4 py-2 text-sm font-medium text-white disabled:cursor-not-allowed disabled:opacity-60 ${
              isRetry
                ? 'bg-slate-900 hover:bg-slate-800'
                : 'bg-rose-700 hover:bg-rose-800'
            }`}
          >
            {isPending
              ? isRetry
                ? 'Retrying…'
                : 'Voiding…'
              : isRetry
                ? 'Retry'
                : 'Void'}
          </button>
        </div>
      </div>
    </div>
  );
}
