import { createDbService } from '@/server/services/db.js';
import { z } from 'zod';
import { eq } from 'drizzle-orm';
import { users } from '../../../db/schema.js';
import { signUnsubscribeToken } from '../../../email/marketing-token.js';
import { sendBuyerWeeklyDigest } from '../../../email/send.js';
import { recordTriggered } from '../../../db/queries/marketing.js';
import { decryptUserEmail } from '../_helpers/decrypt-email.js';
import type { OutboxHandler } from '../types.js';

const dealSummarySchema = z.object({
  title: z.string(),
  slug: z.string(),
  priceAgorot: z.number(),
  originalPriceAgorot: z.number(),
});

const payloadSchema = z.object({
  userId: z.string(),
  deals: z.array(dealSummarySchema).optional().default([]),
  weekStr: z.string().optional().default(''),
});

type Payload = z.infer<typeof payloadSchema>;

export const buyerDigestWeekly: OutboxHandler<Payload> = {
  type: 'buyer.digest.weekly',
  payloadSchema,
  async handle(ctx, payload, event) {
    if (!ctx.RESEND_API_KEY || !ctx.RESEND_MARKETING_FROM_EMAIL) {
      console.warn(
        JSON.stringify({
          event: 'outbox_secret_missing',
          secret: 'RESEND_MARKETING_FROM_EMAIL',
          outboxId: event.id,
        }),
      );
      return;
    }

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

    const [userRow] = await db
      .select({ notifPrefs: users.notifPrefs })
      .from(users)
      .where(eq(users.id, payload.userId))
      .limit(1);

    if (userRow?.notifPrefs?.marketing?.all !== true) return;

    const toEmail = await decryptUserEmail(ctx, payload.userId);
    if (!toEmail) {
      console.warn(JSON.stringify({ event: 'outbox_email_decrypt_failed', outboxId: event.id }));
      return;
    }

    const siteUrl = ctx.PUBLIC_SITE_URL ?? 'https://multi.deal';
    const unsubscribeUrl = await signUnsubscribeToken(payload.userId, ctx.JWT_SECRET!, siteUrl);

    const mEnv = {
      RESEND_API_KEY: ctx.RESEND_API_KEY,
      RESEND_MARKETING_FROM_EMAIL: ctx.RESEND_MARKETING_FROM_EMAIL,
    };

    const result = await sendBuyerWeeklyDigest(mEnv, {
      to: toEmail,
      deals: payload.deals,
      weekStr: payload.weekStr,
      siteUrl,
      unsubscribeUrl,
      locale: 'he',
    });

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

    await recordTriggered(db, payload.userId, 'buyer.digest.weekly');
  },
};
