import { api, type ApiError } from '@/api';
import { toast } from 'sonner';
import { errMessage } from '@/lib/utils';

/**
 * Create a manual payment, treating the server's "duplicate suspected" (409) as a
 * question rather than an error. The deliberate manual-add path must never
 * *silently* drop a legitimately-identical second payment (same bill, date,
 * amount) — losing a real payment is itself a money-integrity bug. So the server
 * returns `409 DUPLICATE_SUSPECTED` instead of silently deduping, and here we
 * surface an "add anyway?" toast; confirming resends with `allow_duplicate`.
 *
 * `onSuccess` runs after any *real* creation — immediate OR confirmed-retry — so
 * callers put their toast/refresh/close there. Any non-duplicate error re-throws
 * for the caller's existing `catch`.
 */
export async function createPaymentOrConfirm(
  payload: Record<string, unknown>,
  onSuccess: () => void | Promise<void>,
): Promise<void> {
  const create = async (allowDuplicate: boolean) => {
    await api.createPayment(allowDuplicate ? { ...payload, allow_duplicate: true } : payload);
    await onSuccess();
  };
  try {
    await create(false);
  } catch (err) {
    const e = err as ApiError;
    if (e?.status === 409 && e?.code === 'DUPLICATE_SUSPECTED') {
      toast.warning('A matching payment already exists for this bill, date, and amount.', {
        description: 'Add it anyway?',
        action: {
          label: 'Add anyway',
          onClick: () => {
            create(true).catch(retryErr => toast.error(errMessage(retryErr, 'Failed to add payment')));
          },
        },
      });
      return; // handled — not an error the caller should re-toast
    }
    throw err;
  }
}
