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 - race errors", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("returns a stable assistant error when the demand project disappears before creation", async () => {
    const tx = {
      project: {
        findUnique: vi.fn().mockResolvedValue(null),
      },
      demandRequirement: {
        create: vi.fn(),
      },
      auditLog: {
        create: vi.fn(),
      },
    };
    const ctx = createToolContext(
      {
        project: {
          findUnique: vi.fn()
            .mockResolvedValueOnce(null)
            .mockResolvedValueOnce({
              id: "project_1",
              name: "Project One",
              shortCode: "PROJ-1",
              status: "ACTIVE",
              responsiblePerson: "Peter Parker",
            }),
          findFirst: vi.fn().mockResolvedValue(null),
        },
        role: {
          findUnique: vi.fn().mockResolvedValue({ id: "role_1", name: "Designer" }),
          findFirst: vi.fn().mockResolvedValue(null),
        },
        $transaction: vi.fn().mockImplementation(
          async (callback: (inner: typeof tx) => Promise<unknown>) => callback(tx),
        ),
      },
      {
        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({
      error: "Project not found with the given criteria.",
    });
  });

  it("returns a stable assistant error when the selected demand role disappears before creation", async () => {
    const tx = {
      project: {
        findUnique: vi.fn().mockResolvedValue({
          id: "project_1",
          name: "Project One",
          shortCode: "PROJ-1",
          budgetCents: 0,
        }),
      },
      demandRequirement: {
        create: vi.fn().mockRejectedValue({
          code: "P2003",
          message: "Foreign key constraint failed",
          meta: { field_name: "DemandRequirement_roleId_fkey" },
        }),
      },
      auditLog: {
        create: vi.fn(),
      },
    };
    const ctx = createToolContext(
      {
        project: {
          findUnique: vi.fn()
            .mockResolvedValueOnce(null)
            .mockResolvedValueOnce({
              id: "project_1",
              name: "Project One",
              shortCode: "PROJ-1",
              status: "ACTIVE",
              responsiblePerson: "Peter Parker",
            }),
          findFirst: vi.fn().mockResolvedValue(null),
        },
        role: {
          findUnique: vi.fn().mockResolvedValue({ id: "role_1", name: "Designer" }),
          findFirst: vi.fn().mockResolvedValue(null),
        },
        $transaction: vi.fn().mockImplementation(
          async (callback: (inner: typeof tx) => Promise<unknown>) => callback(tx),
        ),
      },
      {
        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({
      error: "Role not found with the given criteria.",
    });
  });
});
