import { AppError } from "@/core/errors/app-error";
import { encrypt } from "@/shared/infra/crypto/encryption";
import { DomainsRepository } from "@/modules/domains/repositories/domains-repository";
import { updateSenderSchema } from "../dtos/update-sender-schema";
import { PublicSender, SendersRepository } from "../repositories/senders-repository";

interface UpdateSenderUseCaseRequest {
  id: string;
  userId: string;
  body: unknown;
}

interface UpdateSenderUseCaseResponse {
  sender: PublicSender;
}

export class UpdateSenderUseCase {
  constructor(
    private sendersRepository: SendersRepository,
    private domainsRepository: DomainsRepository
  ) {}

  async execute({ id, userId, body }: UpdateSenderUseCaseRequest): Promise<UpdateSenderUseCaseResponse> {
    const existingSender = await this.sendersRepository.findById(id);

    if (existingSender?.userId !== userId) {
      throw AppError.notFound("Remetente não encontrado");
    }

    const data = updateSenderSchema.parse(body);

    if (data.provider === "SMTP") {
      const encryptedPass = data.smtpPass ? encrypt(data.smtpPass) : (existingSender.smtpPass ?? undefined);

      const sender = await this.sendersRepository.update(id, {
        name: data.name,
        fromEmail: data.fromEmail,
        provider: "SMTP",
        smtpHost: data.smtpHost,
        smtpPort: data.smtpPort,
        smtpUser: data.smtpUser,
        encryptedPass,
      });

      return { sender };
    }

    const domain = await this.domainsRepository.findById(data.domainId);
    if (domain?.userId !== userId) {
      throw AppError.badRequest("Domínio não encontrado");
    }
    if (domain.verificationStatus !== "VERIFIED") {
      throw AppError.badRequest("O domínio precisa estar verificado no SES antes de ser usado como remetente");
    }

    const sender = await this.sendersRepository.update(id, {
      name: data.name,
      fromEmail: data.fromEmail,
      provider: "SES",
      domainId: data.domainId,
    });

    return { sender };
  }
}
