'use client';

/**
 * AdminRefundDialog — two-step approve → execute refund flow.
 *
 * Step 1 (form): admin sets amount override (optional), clicks "Approve".
 *   POST /api/refunds/:id/approve → shows breakdown.
 * Step 2 (confirm): admin reviews breakdown, clicks "Execute" to commit.
 *   POST /api/refunds/:id/execute → done.
 */

import { useRef, useState } from 'react';
import { useT } from '@/lib/i18n/react';
import { getCsrfToken } from '@/lib/csrf';
import {
  AlertDialog,
  AlertDialogContent,
  AlertDialogTitle,
  AlertDialogDescription,
  AlertDialogAction,
  AlertDialogCancel,
} from '@/components/ui/overlays/AlertDialog';
import { FormField } from '@/components/ui/primitives/FormField';
import { Input } from '@/components/ui/primitives/Input';
import { Stack } from '@/components/ui/layout/Stack';
import { InlineNotice } from '@/components/ui/feedback/InlineNotice';
import { refundApproveResponseSchema, refundExecuteResponseSchema } from '@/server/schemas/refund';
import { formatAgorotPlain, formatShekelFloat } from '@/lib/money';
import {
  getActionIdempotencyKey,
  resetActionIdempotencyKey,
} from '@/lib/stable-action-idempotency';

export interface AdminRefundDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  /** Case ID — used by parent for invalidation after execute. */
  caseId: string;
  /** Purchase ID — used as `:id` param in /api/refunds/:id/approve and /execute. */
  purchaseId: string;
  /** Maximum refund amount in cents (for display / default). */
  maxAmountCents: number;
  /** Called after execute completes successfully. */
  onSuccess: () => void;
}

type Step = 'form' | 'approved' | 'done';

interface ApproveResult {
  refundAmount: string;
  breakdown: {
    customerRefund: number;
    platformShare: number;
    vendorShare: number;
  };
  message: string;
}

export function AdminRefundDialog({
  open,
  onOpenChange,
  purchaseId,
  maxAmountCents,
  onSuccess,
}: AdminRefundDialogProps) {
  const t = useT('admin');
  const ts = t('support') as unknown as Record<string, string>;

  const [step, setStep] = useState<Step>('form');
  const [amountOverride, setAmountOverride] = useState('');
  const [approveResult, setApproveResult] = useState<ApproveResult | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const refundEventId = useRef<string | null>(null);

  function reset() {
    setStep('form');
    setAmountOverride('');
    setApproveResult(null);
    setError(null);
    setLoading(false);
    resetActionIdempotencyKey(refundEventId);
  }

  function handleOpenChange(o: boolean) {
    if (!o) reset();
    onOpenChange(o);
  }

  async function handleApprove() {
    setLoading(true);
    setError(null);
    try {
      const csrf = getCsrfToken();
      const body: Record<string, string> = {};
      if (amountOverride.trim()) body['amount'] = amountOverride.trim();

      const res = await fetch(`/api/refunds/${purchaseId}/approve`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'x-csrf-token': csrf,
        },
        body: JSON.stringify(body),
      });
      const json: unknown = await res.json();
      const parsed = refundApproveResponseSchema.safeParse(json);
      if (!parsed.success) {
        const errMsg = (json as { error?: string })?.error ?? ts.refund_error_generic ?? null;
        setError(errMsg);
        return;
      }
      setApproveResult(parsed.data);
      setStep('approved');
    } catch (err) {
      setError(err instanceof Error ? err.message : String(err));
    } finally {
      setLoading(false);
    }
  }

  async function handleExecute() {
    if (!approveResult) return;
    setLoading(true);
    setError(null);
    try {
      const csrf = getCsrfToken();
      const res = await fetch(`/api/refunds/${purchaseId}/execute`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'x-csrf-token': csrf,
          'Idempotency-Key': getActionIdempotencyKey(refundEventId),
        },
        body: JSON.stringify({
          purchaseId,
          amount: approveResult.refundAmount,
        }),
      });
      const json: unknown = await res.json();
      const parsed = refundExecuteResponseSchema.safeParse(json);
      if (!parsed.success) {
        const errMsg = (json as { error?: string })?.error ?? ts.refund_error_generic ?? null;
        setError(errMsg);
        return;
      }
      setStep('done');
      onSuccess();
      onOpenChange(false);
      reset();
    } catch (err) {
      setError(err instanceof Error ? err.message : String(err));
    } finally {
      setLoading(false);
    }
  }

  const maxAmountFormatted = formatAgorotPlain(maxAmountCents);

  return (
    <AlertDialog open={open} onOpenChange={handleOpenChange}>
      <AlertDialogContent>
        {step === 'form' && (
          <>
            <AlertDialogTitle>{ts.action_issue_refund}</AlertDialogTitle>
            <AlertDialogDescription>{ts.refund_dialog_body}</AlertDialogDescription>
            {error && <InlineNotice tone="danger" title={error} className="mt-2" />}
            <Stack gap="3" className="mt-3">
              <FormField label={ts.refund_amount_override_label ?? ''}>
                <Input
                  type="text"
                  inputMode="decimal"
                  value={amountOverride}
                  onChange={(e) => setAmountOverride(e.target.value)}
                  placeholder={`0.00 – ${maxAmountFormatted}`}
                  dir="ltr"
                />
              </FormField>
            </Stack>
            <AlertDialogCancel disabled={loading}>{ts.kb_cancel}</AlertDialogCancel>
            <AlertDialogAction onClick={handleApprove} disabled={loading} aria-busy={loading}>
              {loading ? ts.action_approve_refund_loading : ts.action_approve_refund}
            </AlertDialogAction>
          </>
        )}

        {step === 'approved' && approveResult && (
          <>
            <AlertDialogTitle>{ts.refund_approved_title}</AlertDialogTitle>
            <AlertDialogDescription>{ts.refund_approved_body}</AlertDialogDescription>
            {error && <InlineNotice tone="danger" title={error} className="mt-2" />}
            <Stack gap="2" className="mt-3 text-sm">
              <p>
                <strong>{ts.refund_amount_label}:</strong>{' '}
                {formatShekelFloat(approveResult.refundAmount)}
              </p>
              <p>
                <strong>{ts.refund_customer_share}:</strong>{' '}
                {formatShekelFloat(approveResult.breakdown.customerRefund)}
              </p>
              <p>
                <strong>{ts.refund_platform_share}:</strong>{' '}
                {formatShekelFloat(approveResult.breakdown.platformShare)}
              </p>
              <p>
                <strong>{ts.refund_vendor_share}:</strong>{' '}
                {formatShekelFloat(approveResult.breakdown.vendorShare)}
              </p>
              {approveResult.message && (
                <p className="text-text-secondary italic">{approveResult.message}</p>
              )}
            </Stack>
            <AlertDialogCancel disabled={loading} onClick={() => setStep('form')}>
              {ts.refund_back}
            </AlertDialogCancel>
            <AlertDialogAction onClick={handleExecute} disabled={loading} aria-busy={loading}>
              {loading ? ts.action_execute_refund_loading : ts.action_execute_refund}
            </AlertDialogAction>
          </>
        )}
      </AlertDialogContent>
    </AlertDialog>
  );
}
