import type { PaymentsFinalizeEffect } from './effects.js';
import type { DealId, OrderId, OrderLineId, UserId } from '@/server/platform-seams/ids.js';

export type PaymentsFinalizeCtxId = string & {
  readonly __brand: 'PaymentsFinalizeCtxId';
};

export const asPaymentsFinalizeCtxId = (value: string): PaymentsFinalizeCtxId =>
  value as PaymentsFinalizeCtxId;

export interface PaymentsFinalizeContext {
  ctxId: PaymentsFinalizeCtxId;
  paymentStatus: string;
  purchaseId: OrderLineId;
  orderId?: OrderId;
  dealId?: DealId;
  userId?: UserId;
  stripeFeeAgorot: number | null;
  providerPaymentId: string;
}

export type DecideResult =
  | { ok: true; alreadyFinalized: boolean; effects: PaymentsFinalizeEffect[] }
  | {
      ok: false;
      error: 'MISSING_ORDER_ID';
      ctxId: PaymentsFinalizeCtxId;
      message: string;
    };

const FINALIZED_STATUSES = new Set([
  'fulfilled',
  'completed',
  'unfulfillable',
  'partially_refunded',
  'refunded',
]);

export function decide(ctx: PaymentsFinalizeContext): DecideResult {
  const feeEffects: PaymentsFinalizeEffect[] = ctx.orderId
    ? [
        {
          kind: 'persist-stripe-fee',
          orderId: ctx.orderId,
          stripeFeeAgorot: ctx.stripeFeeAgorot,
          providerPaymentId: ctx.providerPaymentId,
        },
      ]
    : [];

  if (!ctx.orderId) {
    return {
      ok: false,
      error: 'MISSING_ORDER_ID',
      ctxId: ctx.ctxId,
      message: `No order resolved for purchase ${ctx.purchaseId} (${ctx.providerPaymentId})`,
    };
  }

  const effects: PaymentsFinalizeEffect[] = [
    {
      kind: 'consume-inventory-reservations',
      holderRefs: [ctx.purchaseId, ctx.providerPaymentId],
    },
    {
      kind: 'confirm-purchase',
      purchaseId: ctx.purchaseId,
      userId: ctx.userId,
      dealId: ctx.dealId,
    },
  ];

  if (ctx.dealId) {
    effects.push({ kind: 'check-sold-out', dealId: ctx.dealId });
  }

  effects.push({ kind: 'dispatch-outbox' }, ...feeEffects, {
    kind: 'mark-order-paid',
    orderId: ctx.orderId,
    providerPaymentId: ctx.providerPaymentId,
  });

  return {
    ok: true,
    alreadyFinalized: FINALIZED_STATUSES.has(ctx.paymentStatus),
    effects,
  };
}
