import { createDbService } from '@/server/services/db.js';
import { z } from 'zod';
import { captureCaught } from '@/server/observability/capture.server.js';
// clawbackForRefund dynamically imported at call site — kept out of cold-start graph.
import type { OutboxHandler } from '../types.js';

const payloadSchema = z.looseObject({
  purchaseId: z.string().optional(),
  chargeId: z.string().optional(),
  disputeId: z.string().optional(),
  refundAmountAgorot: z.number().int(),
  reason: z.string(),
  refundFraction: z.number().optional(),
  refundEventId: z.string().optional(),
});

type Payload = z.infer<typeof payloadSchema>;

export const referralClawback: OutboxHandler<Payload> = {
  type: 'referral.clawback',
  payloadSchema,
  async handle(ctx, payload, event) {
    const { purchaseId, chargeId, disputeId, reason } = payload;

    if (!purchaseId) {
      console.warn(
        JSON.stringify({
          event: 'referral_clawback_no_purchase',
          outboxId: event.id,
          chargeId,
          disputeId,
          reason,
        }),
      );
      captureCaught(
        new Error('[outbox] referral.clawback: no purchaseId — deferring to reconciliation'),
        {
          scope: 'outbox.referral.clawback',
          severity: 'warning',
        },
      );
      return;
    }

    const refundFraction = payload.refundFraction ?? 1;
    const refundEventId = payload.refundEventId ?? chargeId ?? disputeId ?? event.id;

    const db = createDbService({ DATABASE_URL: ctx.DATABASE_URL });
    const { clawbackForRefund } = await import('../../../referrals/service.js');
    await clawbackForRefund(db, { purchaseId, refundEventId, refundFraction });
  },
};
