import { describe, it, expect, beforeEach, vi } from "vitest";
import { DomainVerificationStatus } from "@prisma/client";
import { InMemorySendersRepository } from "../repositories/in-memory-senders-repository";
import { InMemoryDomainsRepository } from "@/modules/domains/repositories/in-memory-domains-repository";
import { CreateSenderUseCase } from "./create-sender-use-case";
import { AppError } from "@/core/errors/app-error";

vi.mock("@/shared/infra/crypto/encryption", () => ({
  encrypt: vi.fn().mockReturnValue("encrypted-secret"),
}));

let sendersRepository: InMemorySendersRepository;
let domainsRepository: InMemoryDomainsRepository;
let sut: CreateSenderUseCase;

describe("Create Sender Use Case", () => {
  beforeEach(() => {
    sendersRepository = new InMemorySendersRepository();
    domainsRepository = new InMemoryDomainsRepository();
    sut = new CreateSenderUseCase(sendersRepository, domainsRepository);
  });

  it("should be able to create an SMTP sender", async () => {
    const { sender } = await sut.execute({
      userId: "user-1",
      body: {
        name: "My Sender",
        fromEmail: "sender@domain.com",
        provider: "SMTP",
        smtpHost: "smtp.domain.com",
        smtpPort: 587,
        smtpUser: "smtpuser",
        smtpPass: "pass123",
      },
    });

    expect(sender.id).toEqual(expect.any(String));
    expect(sender.fromEmail).toEqual("sender@domain.com");
  });

  it("should be able to create an SES sender linked to a verified domain", async () => {
    const domain = await domainsRepository.create("verified.com", "user-1");
    await domainsRepository.updateVerificationStatus(domain.id, DomainVerificationStatus.VERIFIED);

    const { sender } = await sut.execute({
      userId: "user-1",
      body: {
        name: "SES Sender",
        fromEmail: "sender@verified.com",
        provider: "SES",
        domainId: domain.id,
      },
    });

    expect(sender.provider).toEqual("SES");
    expect(sender.domainId).toEqual(domain.id);
  });

  it("should reject an SES sender linked to an unverified domain", async () => {
    const domain = await domainsRepository.create("pending.com", "user-1");

    await expect(
      sut.execute({
        userId: "user-1",
        body: {
          name: "SES Sender",
          fromEmail: "sender@pending.com",
          provider: "SES",
          domainId: domain.id,
        },
      })
    ).rejects.toBeInstanceOf(AppError);
  });
});
