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 { sendReEngagement } 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(),
  tone: z.enum(['30d', '60d', '90d']),
  deals: z.array(dealSummarySchema).optional().default([]),
});

type Payload = z.infer<typeof payloadSchema>;

async function handleReengagement(
  ctx: Parameters<OutboxHandler<Payload>['handle']>[0],
  payload: Payload,
  event: Parameters<OutboxHandler<Payload>['handle']>[2],
): Promise<void> {
  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 triggerKey = `buyer.reengagement.${payload.tone}`;

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

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

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

  await recordTriggered(db, payload.userId, triggerKey);
}

export const buyerReengagement30d: OutboxHandler<Payload> = {
  type: 'buyer.reengagement.30d',
  payloadSchema,
  handle: handleReengagement,
};

export const buyerReengagement60d: OutboxHandler<Payload> = {
  type: 'buyer.reengagement.60d',
  payloadSchema,
  handle: handleReengagement,
};

export const buyerReengagement90d: OutboxHandler<Payload> = {
  type: 'buyer.reengagement.90d',
  payloadSchema,
  handle: handleReengagement,
};
