import { createDbService } from '@/server/services/db.js';
import { z } from 'zod';
import * as purchaseQueries from '../../../db/queries/purchases.js';
import { sendReceipt } from '../../../email/send.js';
import { requireDecryptedUserEmail } from '../_helpers/decrypt-email.js';
import type { OutboxHandler } from '../types.js';

const payloadSchema = z.object({
  purchaseId: z.string(),
  userId: z.string(),
  dealTitle: z.string().optional(),
  amountPaid: z.string().optional(),
  qrPngUrl: z.string().optional(),
});

type Payload = z.infer<typeof payloadSchema>;

export const purchaseEmailReceipt: OutboxHandler<Payload> = {
  type: 'purchase.email_receipt',
  payloadSchema,
  async handle(ctx, payload, event) {
    const hasTestSink = ctx.ENVIRONMENT !== 'production' && Boolean(ctx.EMAIL_MOCK_DB);
    if (!ctx.RESEND_API_KEY && !hasTestSink) {
      if (ctx.strict !== false) throw new Error('[outbox] RESEND_API_KEY not configured');
      console.warn(
        JSON.stringify({
          event: 'outbox_secret_missing',
          secret: 'RESEND_API_KEY',
          outboxId: event.id,
        }),
      );
      return;
    }

    const db = createDbService({ DATABASE_URL: ctx.DATABASE_URL });

    const purchase = await purchaseQueries.findEnrichedById(db, payload.purchaseId);
    if (!purchase) throw new Error(`[outbox] purchase not found: ${payload.purchaseId}`);

    const toEmail = await requireDecryptedUserEmail(ctx, payload.userId, 'purchase.email_receipt');
    // Only the documented non-strict missing-PII_KEY deploy-window skip reaches
    // here; an unresolvable recipient with the key present throws inside the helper.
    if (!toEmail) return;

    const result = await sendReceipt(
      {
        RESEND_API_KEY: ctx.RESEND_API_KEY ?? '',
        RESEND_FROM_EMAIL: ctx.RESEND_FROM_EMAIL ?? '',
        // Forward the non-prod mock-sink bindings so resend.ts captures to D1
        // instead of really sending on preview (mirrors marketing mEnv()).
        ENVIRONMENT: ctx.ENVIRONMENT,
        EMAIL_MOCK_DB: ctx.EMAIL_MOCK_DB,
      },
      {
        to: toEmail,
        transactionId: payload.purchaseId,
        dealTitle: payload.dealTitle ?? purchase.dealTitle ?? '',
        businessName: purchase.vendorName,
        amountPaid: payload.amountPaid ?? purchase.amountPaid ?? '0',
        paymentMethod: { last4: '????', brand: 'CARD' },
        dateIso: purchase.createdAt.toISOString(),
      },
    );

    if (!result.success) throw new Error(`[outbox] sendReceipt failed: ${result.error}`);
  },
};
