import { NextRequest } from "next/server";

import { PrismaCampaignLogsRepository } from "@/modules/campaigns/repositories/prisma-campaign-logs-repository";
import { PrismaContactsRepository } from "@/modules/contacts/repositories/prisma-contacts-repository";
import { PrismaSuppressedEmailsRepository } from "@/modules/suppression/repositories/prisma-suppressed-emails-repository";
import { PrismaEmailEventsRepository } from "@/modules/ses-webhooks/repositories/prisma-email-events-repository";
import { SesSuppressionProviderImpl } from "@/modules/ses-webhooks/providers/ses-suppression-provider-impl";
import { HandleSesNotificationUseCase } from "@/modules/ses-webhooks/use-cases/handle-ses-notification-use-case";
import { snsEnvelopeSchema } from "@/modules/ses-webhooks/dtos/sns-envelope-schema";
import { verifySnsMessage } from "@/modules/ses-webhooks/entities/verify-sns-signature";

/** Callback servidor-a-servidor da AWS (SNS) — não usa sessão de usuário.
 * Trata tanto a confirmação de assinatura do tópico SNS quanto as notificações
 * de eventos do SES (send/delivery/bounce/complaint/open/click). */
export async function POST(request: NextRequest) {
  const body = await request.json();

  const parsedEnvelope = snsEnvelopeSchema.safeParse(body);
  if (!parsedEnvelope.success) {
    return new Response("Payload inválido", { status: 400 });
  }

  const envelope = parsedEnvelope.data;

  try {
    await verifySnsMessage(envelope);
  } catch {
    return new Response("Assinatura inválida", { status: 400 });
  }

  if (envelope.Type === "SubscriptionConfirmation") {
    if (envelope.SubscribeURL) {
      await fetch(envelope.SubscribeURL);
    }
    return new Response("OK", { status: 200 });
  }

  if (envelope.Type === "Notification") {
    let rawMessage: unknown;
    try {
      rawMessage = JSON.parse(envelope.Message);
    } catch {
      return new Response("Mensagem inválida", { status: 400 });
    }

    const useCase = new HandleSesNotificationUseCase(
      new PrismaCampaignLogsRepository(),
      new PrismaContactsRepository(),
      new PrismaSuppressedEmailsRepository(),
      new PrismaEmailEventsRepository(),
      new SesSuppressionProviderImpl()
    );
    await useCase.execute({ rawMessage });
  }

  return new Response("OK", { status: 200 });
}
