import { beforeEach, describe, expect, it } from "vitest";
import { InMemoryCampaignsRepository } from "@/modules/campaigns/repositories/in-memory-campaigns-repository";
import { InMemoryContactListsRepository } from "@/modules/contacts/repositories/in-memory-contact-lists-repository";
import { InMemoryContactsRepository } from "@/modules/contacts/repositories/in-memory-contacts-repository";
import { InMemoryTagsRepository } from "@/modules/contacts/repositories/in-memory-tags-repository";
import { InMemoryDomainsRepository } from "@/modules/domains/repositories/in-memory-domains-repository";
import { InMemorySendersRepository } from "@/modules/senders/repositories/in-memory-senders-repository";
import { GlobalSearchUseCase } from "./global-search-use-case";

describe("GlobalSearchUseCase", () => {
  let contactsRepository: InMemoryContactsRepository;
  let campaignsRepository: InMemoryCampaignsRepository;
  let contactListsRepository: InMemoryContactListsRepository;
  let tagsRepository: InMemoryTagsRepository;
  let domainsRepository: InMemoryDomainsRepository;
  let sendersRepository: InMemorySendersRepository;
  let sut: GlobalSearchUseCase;

  beforeEach(() => {
    contactsRepository = new InMemoryContactsRepository();
    campaignsRepository = new InMemoryCampaignsRepository();
    contactListsRepository = new InMemoryContactListsRepository();
    tagsRepository = new InMemoryTagsRepository();
    domainsRepository = new InMemoryDomainsRepository();
    sendersRepository = new InMemorySendersRepository();
    sut = new GlobalSearchUseCase(
      contactsRepository,
      campaignsRepository,
      contactListsRepository,
      tagsRepository,
      domainsRepository,
      sendersRepository
    );
  });

  it("retorna vazio para queries menores que 2 caracteres", async () => {
    const { results } = await sut.execute({ query: "a", userId: "user-1" });
    expect(results).toEqual([]);
  });

  it("retorna resultados de múltiplos tipos que combinam com a query", async () => {
    await contactsRepository.create({ email: "ana@example.com", name: "Ana Souza" });
    await campaignsRepository.create({
      title: "Campanha Ana",
      subject: "Assunto",
      htmlBody: "<p>Corpo</p>",
      senderId: "sender-1",
      createdById: "user-1",
    });
    await domainsRepository.create("ana-domain.com", "user-1");

    const { results } = await sut.execute({ query: "ana", userId: "user-1" });

    const types = results.map((result) => result.type);
    expect(types).toContain("contact");
    expect(types).toContain("campaign");
    expect(types).toContain("domain");
  });

  it("isola campanhas, domínios e remetentes por userId", async () => {
    await campaignsRepository.create({
      title: "Campanha do outro usuário",
      subject: "Assunto",
      htmlBody: "<p>Corpo</p>",
      senderId: "sender-1",
      createdById: "other-user",
    });

    const { results } = await sut.execute({ query: "campanha", userId: "user-1" });

    expect(results.some((result) => result.type === "campaign")).toBe(false);
  });
});
