/**
 * Pure policy functions — zero IO.
 *
 * isOfferMatchingAsk: determines whether a vendor offer satisfies the customer ask.
 * shouldAutoExecute: composed gate for automatic refund execution.
 */

import type { caseOfferOutcomeEnum } from '@/server/db/schema.js';

export type CaseOfferOutcome = (typeof caseOfferOutcomeEnum.enumValues)[number];

export interface AskLike {
  outcome: CaseOfferOutcome;
  amountCents: number | null;
}

export interface OfferLike {
  outcome: CaseOfferOutcome;
  amountCents: number | null;
}

const REFUND_OUTCOMES = new Set<CaseOfferOutcome>(['refund_full', 'refund_partial']);

/**
 * True when the vendor offer outcome+amount ≥ customer ask, and offer is not deny.
 *
 * Rules:
 * - deny offer → never match
 * - refund outcomes: offer amount must be ≥ ask amount (over-grants are accepted)
 * - replacement ask vs replacement offer → match
 * - mixed outcome classes → no match
 */
export function isOfferMatchingAsk(ask: AskLike, offer: OfferLike): boolean {
  if (offer.outcome === 'deny') return false;

  if (REFUND_OUTCOMES.has(ask.outcome) && REFUND_OUTCOMES.has(offer.outcome)) {
    const askAmt = ask.amountCents ?? 0;
    const offerAmt = offer.amountCents ?? 0;
    return offerAmt >= askAmt;
  }

  if (ask.outcome === 'replacement' && offer.outcome === 'replacement') return true;

  return false;
}

/** Composed decision: match-AND-not-deny */
export function shouldAutoExecute(ask: AskLike, offer: OfferLike): boolean {
  return isOfferMatchingAsk(ask, offer);
}
