import { Domain } from "@prisma/client";
import { env } from "@/config/env";
import { AppError } from "@/core/errors/app-error";
import { createDomainSchema } from "../dtos/create-domain-schema";
import { DomainsRepository } from "../repositories/domains-repository";
import { SesIdentityProvider } from "../providers/ses-identity-provider";
import { buildDnsRecords } from "../entities/build-dns-records";

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

interface CreateDomainUseCaseResponse {
  domain: Domain;
}

export class CreateDomainUseCase {
  constructor(
    private domainsRepository: DomainsRepository,
    private sesIdentityProvider: SesIdentityProvider
  ) {}

  async execute({ userId, body }: CreateDomainUseCaseRequest): Promise<CreateDomainUseCaseResponse> {
    const parsed = createDomainSchema.safeParse(body);

    if (!parsed.success) {
      throw AppError.badRequest("Domínio inválido");
    }

    const cleanDomain = parsed.data.domain;

    let targetDomain = await this.domainsRepository.findByDomainName(cleanDomain);
    if (!targetDomain) {
      targetDomain = await this.domainsRepository.create(cleanDomain, userId);
    }

    const mailFromDomain = `mail.${cleanDomain}`;
    const identity = await this.sesIdentityProvider.createIdentity(cleanDomain);
    await this.sesIdentityProvider.putMailFromAttributes(cleanDomain, mailFromDomain);

    const dkimRecords = buildDnsRecords({
      domain: cleanDomain,
      dkimTokens: identity.dkimTokens,
      mailFromDomain,
    });

    const region = env.awsRegion || "us-east-1";

    const domain = await this.domainsRepository.updateSesIdentity(targetDomain.id, {
      dkimRecords,
      mailFromDomain,
      mailFromMxRecord: `10 feedback-smtp.${region}.amazonses.com`,
      sesIdentityArn: identity.sesIdentityArn,
    });

    return { domain };
  }
}

