/**
 * CartCheckout pure decider.
 *
 * PURITY CONTRACT (enforced by _purity-check.sh cart-checkout):
 *   - No imports from '@/server/db'
 *   - No imports from 'do-client'
 *   - No imports from 'outbox-producer'
 *   - No imports from '@/server/payments'
 *   - No imports from '@/server/storage'
 *   - No imports from '@/server/email'
 *   - No imports from '@/server/push'
 *   - No Date.now() calls (caller provides `at` via event)
 *   - No crypto.randomUUID() calls
 *
 * Transition table:
 *
 *   BATCH_VALIDATING + lines_validated(empty)   → rejected (EMPTY_CART)
 *
 *   BATCH_VALIDATING + lines_validated(any stale)
 *     → rejected (STALE_ITEMS) — payload carries removed[] + updated[].
 *
 *   BATCH_VALIDATING + lines_validated(all_ok)  → ACCEPTED
 *     effects: [reserve-line × N, clear-cart]
 *
 * Per-line PENDING→COMPLETED finalization delegates to the W1 purchase
 * machine via the orchestrator AFTER `applyEffects` returns (the cart
 * checkout decider is not the place to model individual purchase lifecycle).
 *
 * Non-state-machine work (cart-line query w/ FOR UPDATE, stock clamping,
 * QR token gen, R2 upload, multi-vendor charge, paymentMethod lookup) stays
 * in the workflow orchestrator.
 */

import type { CartCheckoutEvent, ValidatedCartLine, CartLineState } from './events.js';
import type { CartCheckoutEffect } from './effects.js';
import { applyQtyTier } from '@/server/pricing/qty-tier.js';
import { formatAgorotPlain, splitCommission } from '@/lib/money.js';

// ─── State type ───────────────────────────────────────────────────────────────

export type CartCheckoutState = 'BATCH_VALIDATING' | 'ACCEPTED';

// ─── Context ─────────────────────────────────────────────────────────────────

export interface CartCheckoutContext {
  state: CartCheckoutState;
}

// ─── Result type ─────────────────────────────────────────────────────────────

export interface StaleSplit {
  removed: { dealId: string; reason: 'expired' | 'inactive' | 'sold_out' }[];
  updated: { dealId: string; reason: 'qty_clamped'; availableQty: number }[];
}

export type DecideResult =
  | { ok: true; nextState: CartCheckoutState; effects: CartCheckoutEffect[] }
  | { ok: false; error: 'EMPTY_CART' | 'STALE_ITEMS'; stale?: StaleSplit };

// ─── Decider ─────────────────────────────────────────────────────────────────

function classifyStale(line: ValidatedCartLine): StaleSplit['removed'][number] | null {
  if (line.lineState === 'EXPIRED') return { dealId: line.dealId, reason: 'expired' };
  if (line.lineState === 'INACTIVE') return { dealId: line.dealId, reason: 'inactive' };
  if (line.lineState === 'SOLD_OUT') return { dealId: line.dealId, reason: 'sold_out' };
  return null;
}

function classifyUpdated(line: ValidatedCartLine): StaleSplit['updated'][number] | null {
  if (line.lineState === 'QTY_CLAMPED') {
    return { dealId: line.dealId, reason: 'qty_clamped', availableQty: line.clampedQty };
  }
  return null;
}

export function decide(ctx: CartCheckoutContext, event: CartCheckoutEvent): DecideResult {
  if (ctx.state !== 'BATCH_VALIDATING') {
    return { ok: false, error: 'STALE_ITEMS' };
  }

  if (event.lines.length === 0) {
    return { ok: false, error: 'EMPTY_CART' };
  }

  const removed: StaleSplit['removed'] = [];
  const updated: StaleSplit['updated'] = [];

  for (const line of event.lines) {
    const r = classifyStale(line);
    if (r) removed.push(r);
    const u = classifyUpdated(line);
    if (u) updated.push(u);
  }

  if (removed.length > 0 || updated.length > 0) {
    return { ok: false, error: 'STALE_ITEMS', stale: { removed, updated } };
  }

  const effects: CartCheckoutEffect[] = [];
  for (const line of event.lines) {
    const unitAgorot = Math.round(parseFloat(line.discountedPrice) * 100);
    const { lineTotalAgorot } = applyQtyTier(unitAgorot, line.qty, line.qtyTiers ?? []);
    const amountPaid = formatAgorotPlain(lineTotalAgorot);
    const { commission: commissionAmount, vendor: vendorAmount } = splitCommission(
      amountPaid,
      line.commissionRate,
    );
    effects.push({
      kind: 'reserve-line',
      dealId: line.dealId,
      dealSkuId: line.dealSkuId,
      vendorId: line.vendorId,
      dealTitle: line.dealTitle,
      qty: line.qty,
      amountPaid,
      commissionAmount,
      vendorAmount,
      expiresAt: line.expiresAt,
      idempotencyKey: `${event.idempotencyKey}:${line.dealId}`,
    });
  }

  effects.push({ kind: 'clear-cart', userId: event.userId });

  return { ok: true, nextState: 'ACCEPTED', effects };
}

export type { CartLineState };
