import { createKyselyMock } from "@tailor-platform/sdk/vitest";
import { describe, expect, it } from "vitest";
import type { Namespace } from "../generated/kysely-tailordb";
import { activeDepartment, inactiveDepartment } from "../testing/fixtures";
import { run } from "./getDepartment";

describe("getDepartment", () => {
  it("returns department when found by id", async () => {
    const mock = createKyselyMock<Namespace["main-db"]>();
    mock.enqueueResults([activeDepartment]);

    const result = await run(mock.db, { id: activeDepartment.id });

    expect(result.ok).toBe(true);
    if (result.ok) {
      expect(result.value.department).toEqual(activeDepartment);
    }
    expect(mock.selects).toHaveLength(1);
    expect(mock.selects[0].parameters).toContain(activeDepartment.id);
    expect(mock.selects[0].sql).toMatch(/"id"/);
  });

  it("returns department when found by code and companyId", async () => {
    const mock = createKyselyMock<Namespace["main-db"]>();
    mock.enqueueResults([activeDepartment]);

    const result = await run(mock.db, {
      code: activeDepartment.code,
      companyId: activeDepartment.companyId,
    });

    expect(result.ok).toBe(true);
    if (result.ok) {
      expect(result.value.department).toEqual(activeDepartment);
    }
    expect(mock.selects).toHaveLength(1);
    expect(mock.selects[0].parameters).toContain(activeDepartment.code);
    expect(mock.selects[0].parameters).toContain(activeDepartment.companyId);
    expect(mock.selects[0].sql).toMatch(/"code"/);
    expect(mock.selects[0].sql).toMatch(/"companyId"/);
  });

  it("returns null when department not found by id", async () => {
    const mock = createKyselyMock<Namespace["main-db"]>();
    mock.enqueueResults([]);

    const result = await run(mock.db, { id: "nonexistent-id" });

    expect(result.ok).toBe(true);
    if (result.ok) {
      expect(result.value.department).toBeNull();
    }
  });

  it("returns null when department not found by code", async () => {
    const mock = createKyselyMock<Namespace["main-db"]>();
    mock.enqueueResults([]);

    const result = await run(mock.db, {
      code: "NONEXISTENT",
      companyId: activeDepartment.companyId,
    });

    expect(result.ok).toBe(true);
    if (result.ok) {
      expect(result.value.department).toBeNull();
    }
  });

  it("returns ACTIVE department", async () => {
    const mock = createKyselyMock<Namespace["main-db"]>();
    mock.enqueueResults([activeDepartment]);

    const result = await run(mock.db, { id: activeDepartment.id });

    expect(result.ok).toBe(true);
    if (result.ok) {
      expect(result.value.department!.status).toBe("ACTIVE");
    }
  });

  it("returns INACTIVE department", async () => {
    const mock = createKyselyMock<Namespace["main-db"]>();
    mock.enqueueResults([inactiveDepartment]);

    const result = await run(mock.db, { id: inactiveDepartment.id });

    expect(result.ok).toBe(true);
    if (result.ok) {
      expect(result.value.department!.status).toBe("INACTIVE");
    }
  });
});
