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

describe("assistant demand create tool - success", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("routes demand creation through the real allocation router path and writes an audit log", async () => {
    const auditCreate = vi.fn().mockResolvedValue({ id: "audit_1" });
    const notificationCreate = vi.fn().mockResolvedValue({ id: "task_1" });
    const demandCreate = vi.fn().mockResolvedValue({
      id: "demand_1",
      projectId: "project_1",
      roleId: "role_1",
      role: null,
      headcount: 2,
      hoursPerDay: 6,
      percentage: 75,
      budgetCents: 0,
      status: "PROPOSED",
      metadata: {},
      startDate: new Date("2026-05-01T00:00:00.000Z"),
      endDate: new Date("2026-05-15T00:00:00.000Z"),
      project: { id: "project_1", name: "Project One", shortCode: "PROJ-1" },
      roleEntity: { id: "role_1", name: "Designer", color: "#00AAFF" },
    });
    const tx = {
      project: {
        findUnique: vi.fn().mockResolvedValue({
          id: "project_1",
          name: "Project One",
          shortCode: "PROJ-1",
          budgetCents: 0,
        }),
      },
      demandRequirement: { create: demandCreate },
      auditLog: { create: auditCreate },
    };
    const transaction = vi.fn().mockImplementation(
      async (callback: (inner: typeof tx) => Promise<unknown>) => callback(tx),
    );
    const projectFindFirst = vi.fn().mockResolvedValue({
      id: "project_1",
      name: "Project One",
      shortCode: "PROJ-1",
    });
    const projectFindUnique = vi.fn().mockResolvedValue({
      id: "project_1",
      name: "Project One",
      shortCode: "PROJ-1",
      budgetCents: 0,
    });
    const roleFindFirst = vi.fn().mockResolvedValue({ id: "role_1", name: "Designer" });
    const roleFindUnique = vi.fn().mockResolvedValue({ id: "role_1", name: "Designer" });
    const ctx = createToolContext(
      {
        project: {
          findFirst: projectFindFirst,
          findUnique: projectFindUnique,
        },
        role: {
          findFirst: roleFindFirst,
          findUnique: roleFindUnique,
        },
        assignment: {
          findMany: vi.fn().mockResolvedValue([]),
        },
        demandRequirement: {
          findMany: vi.fn().mockResolvedValue([]),
        },
        user: {
          findMany: vi.fn().mockResolvedValue([{ id: "manager_1" }]),
        },
        notification: {
          findFirst: vi.fn().mockResolvedValue(null),
          create: notificationCreate,
        },
        $transaction: transaction,
      },
      {
        userRole: SystemRole.ADMIN,
        permissions: [PermissionKey.MANAGE_ALLOCATIONS],
      },
    );

    const result = await executeTool(
      "create_demand",
      JSON.stringify({
        projectId: "PROJ-1",
        roleName: "Designer",
        headcount: 2,
        hoursPerDay: 6,
        startDate: "2026-05-01",
        endDate: "2026-05-15",
      }),
      ctx,
    );

    expect(JSON.parse(result.content)).toEqual(
      expect.objectContaining({
        success: true,
        message:
          "Created demand: Designer × 2 for Project One (PROJ-1), 6h/day, 2026-05-01 to 2026-05-15",
        demandId: "demand_1",
      }),
    );
    expect(demandCreate).toHaveBeenCalledWith(
      expect.objectContaining({
        data: expect.objectContaining({
          projectId: "project_1",
          roleId: "role_1",
          headcount: 2,
          hoursPerDay: 6,
          percentage: 75,
        }),
      }),
    );
    expect(auditCreate).toHaveBeenCalledTimes(1);
    expect(notificationCreate).toHaveBeenCalledTimes(1);
  });
});
