import { Domain, Sender } from "@prisma/client";
import { AppError } from "@/core/errors/app-error";
import { SendersRepository } from "@/modules/senders/repositories/senders-repository";
import { sanitizeHtml } from "../entities/sanitize-html";
import { buildEmailContent } from "../entities/build-email-content";
import { sendTestCampaignSchema } from "../dtos/send-test-campaign-schema";
import { MailProvider } from "../providers/mail-provider";

interface SendTestCampaignUseCaseRequest {
  userId: string;
  body: unknown;
}

interface SendTestCampaignUseCaseResponse {
  success: true;
  messageId?: string;
}

export class SendTestCampaignUseCase {
  constructor(
    private sendersRepository: SendersRepository,
    private mailProviderFactory: (sender: Sender & { domain?: Domain | null }) => MailProvider
  ) {}

  async execute({
    userId,
    body,
  }: SendTestCampaignUseCaseRequest): Promise<SendTestCampaignUseCaseResponse> {
    const data = sendTestCampaignSchema.parse(body);

    const sender = await this.sendersRepository.findByIdWithDomain(data.senderId);
    if (!sender || sender.userId !== userId) {
      throw AppError.notFound("Remetente não encontrado");
    }

    const mailProvider = this.mailProviderFactory(sender);
    // Mesma regra do envio real: só injetamos nosso pixel para provedores sem tracking nativo
    // (ver `build-email-content.ts`), senão o SES contaria a abertura em dobro.
    const trackingToken = sender.provider === "SES" ? undefined : "test-send";
    const content = buildEmailContent(sanitizeHtml(data.htmlBody), "test-send", trackingToken);

    const result = await mailProvider.send({
      sender,
      to: data.testEmail,
      subject: `[TESTE] ${data.subject}`,
      html: content.html,
      text: content.text,
      headers: content.headers,
    });

    if (!result.success) {
      throw AppError.badRequest(result.errorMessage ?? "Não foi possível enviar o e-mail de teste");
    }

    return { success: true, messageId: result.messageId };
  }
}
