import { beforeEach, describe, expect, it, vi } from "vitest";
import { PermissionKey } from "@capakraken/shared";
import {
  createToolContext,
  executeTool,
} from "./assistant-tools-project-test-helpers.js";

describe("assistant project read tools - computation graph", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("returns a filtered project computation graph through the assistant", async () => {
    const projectRecord = {
      id: "project_1",
      name: "Gelddruckmaschine",
      shortCode: "GDM",
      budgetCents: 100_000,
      winProbability: 75,
      startDate: new Date("2026-01-05T00:00:00.000Z"),
      endDate: new Date("2026-02-28T00:00:00.000Z"),
      status: "ACTIVE",
      responsiblePerson: "Larissa Joos",
    };

    const ctx = createToolContext(
      {
        project: {
          findUnique: vi.fn().mockResolvedValue(projectRecord),
          findFirst: vi.fn(),
          findUniqueOrThrow: vi.fn().mockResolvedValue(projectRecord),
        },
        estimate: {
          findFirst: vi.fn().mockResolvedValue(null),
        },
        assignment: {
          findMany: vi.fn().mockResolvedValue([
            {
              status: "CONFIRMED",
              dailyCostCents: 4_000,
              startDate: new Date("2026-01-05T00:00:00.000Z"),
              endDate: new Date("2026-01-30T00:00:00.000Z"),
              hoursPerDay: 4,
            },
          ]),
        },
        effortRule: {
          count: vi.fn().mockResolvedValue(0),
        },
        experienceMultiplierRule: {
          count: vi.fn().mockResolvedValue(0),
        },
      },
      {
        permissions: [PermissionKey.VIEW_COSTS, PermissionKey.USE_ASSISTANT_ADVANCED_TOOLS],
      },
    );

    const result = await executeTool(
      "get_project_computation_graph",
      JSON.stringify({
        projectId: "project_1",
        domain: "BUDGET",
        includeLinks: true,
      }),
      ctx,
    );

    const parsed = JSON.parse(result.content) as {
      project: { id: string; shortCode: string; name: string };
      requestedDomain: string;
      totalNodeCount: number;
      selectedNodeCount: number;
      selectedLinkCount: number;
      nodes: Array<{ id: string; domain: string }>;
      links: Array<{ source: string; target: string }>;
      meta: { projectName: string; projectCode: string };
    };

    expect(parsed.project).toEqual({
      id: "project_1",
      shortCode: "GDM",
      name: "Gelddruckmaschine",
    });
    expect(parsed.meta).toEqual({
      projectName: "Gelddruckmaschine",
      projectCode: "GDM",
    });
    expect(parsed.requestedDomain).toBe("BUDGET");
    expect(parsed.totalNodeCount).toBeGreaterThan(parsed.selectedNodeCount);
    expect(parsed.selectedNodeCount).toBeGreaterThan(0);
    expect(parsed.selectedLinkCount).toBeGreaterThan(0);
    expect(parsed.nodes.every((node) => node.domain === "BUDGET")).toBe(true);
    expect(parsed.links.length).toBe(parsed.selectedLinkCount);
  });
});
