import { describe, it, expect } from "vitest";
import { ZodError } from "zod";
import {
  listMediaUseCase,
  listMediaOutputSchema,
} from "@/application/use-cases/list-media.use-case";
import { MockMediaRepository } from "@/infrastructure/repositories/media.repository.mock";
import { mediaFactory } from "@/__factories__/media.factory";

describe("listMediaUseCase", () => {
  it("returns empty array when no media exists", async () => {
    const repo = new MockMediaRepository();
    const useCase = listMediaUseCase(repo);
    const result = await useCase({});
    expect(result).toHaveLength(0);
  });

  it("returns all media when store has items", async () => {
    const repo = new MockMediaRepository();
    await repo._store(mediaFactory.build());
    await repo._store(mediaFactory.build());

    const useCase = listMediaUseCase(repo);
    const result = await useCase({});
    expect(result).toHaveLength(2);
  });

  it("respects limit and offset options", async () => {
    const repo = new MockMediaRepository();
    for (let i = 0; i < 5; i++) {
      await repo._store(mediaFactory.build());
    }

    const useCase = listMediaUseCase(repo);
    const result = await useCase({ limit: 2, offset: 1 });
    expect(result).toHaveLength(2);
  });

  it("parses valid output without error", async () => {
    const items = [mediaFactory.build(), mediaFactory.build()];
    expect(() => listMediaOutputSchema.parse(items)).not.toThrow();
  });

  it("throws ZodError when repository returns malformed items", async () => {
    const repo = new MockMediaRepository();
    // Store a malformed object (missing required fields)
    await repo._store({ id: "bad", alt: "alt", url: "u" } as never);

    const useCase = listMediaUseCase(repo);
    await expect(useCase({})).rejects.toBeInstanceOf(ZodError);
  });
});
