import { BlueprintTarget, SystemRole } from "@capakraken/shared";
import { describe, expect, it, vi } from "vitest";
import { blueprintRouter } from "../router/blueprint.js";
import { clientRouter } from "../router/client.js";
import { countryRouter } from "../router/country.js";
import { orgUnitRouter } from "../router/org-unit.js";
import { roleRouter } from "../router/role.js";
import { createCallerFactory } from "../trpc.js";

function createProtectedContext(db: Record<string, unknown>) {
  return {
    session: {
      user: { email: "user@example.com", name: "User", image: null },
      expires: "2099-01-01T00:00:00.000Z",
    },
    db: db as never,
    dbUser: {
      id: "user_1",
      systemRole: SystemRole.USER,
      permissionOverrides: null,
    },
  };
}

describe("identifier resolvers", () => {
  it("resolves blueprints via a minimal read model", async () => {
    const findUnique = vi.fn().mockResolvedValue({
      id: "bp_1",
      name: "Consulting Blueprint",
      target: BlueprintTarget.PROJECT,
      isActive: true,
    });
    const caller = createCallerFactory(blueprintRouter)(createProtectedContext({
      blueprint: {
        findUnique,
        findFirst: vi.fn(),
      },
    }));

    const result = await caller.resolveByIdentifier({ identifier: "bp_1" });

    expect(result).toEqual({
      id: "bp_1",
      name: "Consulting Blueprint",
      target: BlueprintTarget.PROJECT,
      isActive: true,
    });
    expect(findUnique).toHaveBeenCalledWith(expect.objectContaining({
      where: { id: "bp_1" },
      select: expect.objectContaining({
        id: true,
        name: true,
        target: true,
        isActive: true,
      }),
    }));
  });

  it("resolves clients by code via a minimal read model", async () => {
    const findUnique = vi.fn()
      .mockResolvedValueOnce(null)
      .mockResolvedValueOnce({
        id: "client_1",
        name: "Acme",
        code: "ACME",
        parentId: null,
        isActive: true,
      });
    const caller = createCallerFactory(clientRouter)(createProtectedContext({
      client: {
        findUnique,
        findFirst: vi.fn(),
      },
    }));

    const result = await caller.resolveByIdentifier({ identifier: "ACME" });

    expect(result).toEqual({
      id: "client_1",
      name: "Acme",
      code: "ACME",
      parentId: null,
      isActive: true,
    });
    expect(findUnique).toHaveBeenNthCalledWith(2, expect.objectContaining({
      where: { code: "ACME" },
      select: expect.objectContaining({
        id: true,
        name: true,
        code: true,
        parentId: true,
        isActive: true,
      }),
    }));
  });

  it("resolves countries by code via a minimal read model", async () => {
    const findUnique = vi.fn().mockResolvedValue(null);
    const findFirst = vi.fn().mockResolvedValue({
      id: "country_de",
      code: "DE",
      name: "Germany",
      isActive: true,
      dailyWorkingHours: 8,
    });
    const caller = createCallerFactory(countryRouter)(createProtectedContext({
      country: {
        findUnique,
        findFirst,
      },
    }));

    const result = await caller.resolveByIdentifier({ identifier: "de" });

    expect(result).toEqual({
      id: "country_de",
      code: "DE",
      name: "Germany",
      isActive: true,
      dailyWorkingHours: 8,
    });
    expect(findFirst).toHaveBeenNthCalledWith(1, expect.objectContaining({
      where: { code: { equals: "DE", mode: "insensitive" } },
      select: expect.objectContaining({
        id: true,
        code: true,
        name: true,
        isActive: true,
        dailyWorkingHours: true,
      }),
    }));
  });

  it("resolves org units by short name via a minimal read model", async () => {
    const findUnique = vi.fn().mockResolvedValue(null);
    const findFirst = vi.fn()
      .mockResolvedValueOnce(null)
      .mockResolvedValueOnce({
        id: "ou_1",
        name: "Delivery",
        shortName: "DEL",
        level: 5,
        isActive: true,
      });
    const caller = createCallerFactory(orgUnitRouter)(createProtectedContext({
      orgUnit: {
        findUnique,
        findFirst,
      },
    }));

    const result = await caller.resolveByIdentifier({ identifier: "DEL" });

    expect(result).toEqual({
      id: "ou_1",
      name: "Delivery",
      shortName: "DEL",
      level: 5,
      isActive: true,
    });
    expect(findFirst).toHaveBeenNthCalledWith(2, expect.objectContaining({
      where: { shortName: { equals: "DEL", mode: "insensitive" } },
      select: expect.objectContaining({
        id: true,
        name: true,
        shortName: true,
        level: true,
        isActive: true,
      }),
    }));
  });

  it("resolves roles without loading planning counts", async () => {
    const findUnique = vi.fn()
      .mockResolvedValueOnce(null)
      .mockResolvedValueOnce({
        id: "role_1",
        name: "Designer",
        color: "#123456",
        isActive: true,
      });
    const caller = createCallerFactory(roleRouter)(createProtectedContext({
      role: {
        findUnique,
        findFirst: vi.fn(),
      },
    }));

    const result = await caller.resolveByIdentifier({ identifier: "Designer" });

    expect(result).toEqual({
      id: "role_1",
      name: "Designer",
      color: "#123456",
      isActive: true,
    });
    expect(findUnique).toHaveBeenNthCalledWith(2, expect.objectContaining({
      where: { name: "Designer" },
      select: expect.objectContaining({
        id: true,
        name: true,
        color: true,
        isActive: true,
      }),
    }));
  });
});
