import { describe, it, expect, beforeEach } from "vitest";
import { InMemoryCampaignsRepository } from "../repositories/in-memory-campaigns-repository";
import { InMemoryCampaignLogsRepository } from "../repositories/in-memory-campaign-logs-repository";
import { GetCampaignsSummaryByUserUseCase } from "./get-campaigns-summary-by-user-use-case";

let campaignsRepository: InMemoryCampaignsRepository;
let campaignLogsRepository: InMemoryCampaignLogsRepository;
let sut: GetCampaignsSummaryByUserUseCase;

describe("Get Campaigns Summary By User Use Case", () => {
  beforeEach(() => {
    campaignsRepository = new InMemoryCampaignsRepository();
    campaignLogsRepository = new InMemoryCampaignLogsRepository();
    sut = new GetCampaignsSummaryByUserUseCase(campaignsRepository, campaignLogsRepository);
  });

  it("should sum log counts by status only across campaigns belonging to the given user", async () => {
    const ownCampaignA = await campaignsRepository.create({
      title: "A",
      subject: "A",
      htmlBody: "<p>A</p>",
      createdById: "user-1",
    });
    const ownCampaignB = await campaignsRepository.create({
      title: "B",
      subject: "B",
      htmlBody: "<p>B</p>",
      createdById: "user-1",
    });
    const otherUserCampaign = await campaignsRepository.create({
      title: "C",
      subject: "C",
      htmlBody: "<p>C</p>",
      createdById: "user-2",
    });

    const successLog = await campaignLogsRepository.upsertPending(ownCampaignA.id, "contact-1");
    await campaignLogsRepository.markSuccess(successLog.id);

    const failedLog = await campaignLogsRepository.upsertPending(ownCampaignA.id, "contact-2");
    await campaignLogsRepository.markFailed(failedLog.id, "boom");

    await campaignLogsRepository.upsertPending(ownCampaignB.id, "contact-3");

    const otherSuccessLog = await campaignLogsRepository.upsertPending(otherUserCampaign.id, "contact-4");
    await campaignLogsRepository.markSuccess(otherSuccessLog.id);

    const { summary } = await sut.execute({ userId: "user-1" });

    expect(summary).toEqual({
      campaignsCount: 2,
      total: 3,
      success: 1,
      failed: 1,
      pending: 1,
    });
  });

  it("should return zeroed counts when the user has no campaigns", async () => {
    const { summary } = await sut.execute({ userId: "user-without-campaigns" });

    expect(summary).toEqual({
      campaignsCount: 0,
      total: 0,
      success: 0,
      failed: 0,
      pending: 0,
    });
  });
});
