import { describe, it, expect, beforeEach, vi } from "vitest";
import { Prisma } from "@prisma/client";
import { InMemorySendersRepository } from "../repositories/in-memory-senders-repository";
import { DeleteSenderUseCase } from "./delete-sender-use-case";
import { AppError } from "@/core/errors/app-error";

let sendersRepository: InMemorySendersRepository;
let sut: DeleteSenderUseCase;

describe("Delete Sender Use Case", () => {
  beforeEach(() => {
    sendersRepository = new InMemorySendersRepository();
    sut = new DeleteSenderUseCase(sendersRepository);
  });

  it("should be able to delete a sender", async () => {
    const created = await sendersRepository.create({
      name: "Sender",
      fromEmail: "sender@example.com",
      smtpHost: "smtp.com",
      smtpPort: 587,
      smtpUser: "user",
      provider: "SMTP",
      userId: "user-1",
      encryptedPass: "enc-pass",
    });

    const result = await sut.execute({ id: created.id, userId: "user-1" });

    expect(result.success).toBe(true);
    expect(sendersRepository.items).toHaveLength(0);
  });

  it("should not allow deleting another user's sender", async () => {
    const created = await sendersRepository.create({
      name: "Sender",
      fromEmail: "sender@example.com",
      smtpHost: "smtp.com",
      smtpPort: 587,
      smtpUser: "user",
      provider: "SMTP",
      userId: "user-1",
      encryptedPass: "enc-pass",
    });

    await expect(sut.execute({ id: created.id, userId: "user-2" })).rejects.toBeInstanceOf(AppError);
    expect(sendersRepository.items).toHaveLength(1);
  });

  it("should throw a friendly AppError when the sender is linked to campaigns", async () => {
    const created = await sendersRepository.create({
      name: "Sender",
      fromEmail: "sender@example.com",
      smtpHost: "smtp.com",
      smtpPort: 587,
      smtpUser: "user",
      provider: "SMTP",
      userId: "user-1",
      encryptedPass: "enc-pass",
    });

    vi.spyOn(sendersRepository, "delete").mockRejectedValueOnce(
      new Prisma.PrismaClientKnownRequestError("Foreign key constraint failed", {
        code: "P2003",
        clientVersion: "test",
      })
    );

    await expect(sut.execute({ id: created.id, userId: "user-1" })).rejects.toBeInstanceOf(AppError);
  });
});
