import { beforeEach, describe, expect, it, vi } from "vitest";
import { PermissionKey, SystemRole } from "@capakraken/shared";
import { TRPCError } from "@trpc/server";

import {
  createAssignment,
  createToolContext,
  executeTool,
} from "./assistant-tools-allocation-status-test-helpers.js";

describe("assistant allocation status tools", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("returns a stable assistant error when allocation status update cannot resolve an assignment", async () => {
    const ctx = createToolContext(
      {
        assignment: {
          findUnique: vi.fn().mockRejectedValue(
            new TRPCError({ code: "NOT_FOUND", message: "Assignment not found" }),
          ),
        },
      },
      {
        userRole: SystemRole.ADMIN,
        permissions: [PermissionKey.MANAGE_ALLOCATIONS],
      },
    );

    const result = await executeTool(
      "update_allocation_status",
      JSON.stringify({ allocationId: "assignment_missing", newStatus: "ACTIVE" }),
      ctx,
    );

    expect(JSON.parse(result.content)).toEqual({
      error: "Allocation not found with the given criteria.",
    });
  });

  it("returns stable assistant errors when allocation status updates fail during the update step", async () => {
    const assignment = createAssignment();
    const errors = [
      new TRPCError({ code: "NOT_FOUND", message: "Assignment not found" }),
      {
        code: "P2025",
        message: "Record not found",
        meta: { modelName: "Assignment" },
      },
    ] as const;

    for (const error of errors) {
      const tx = {
        assignment: {
          findUnique: vi.fn().mockResolvedValue(assignment),
          update: vi.fn().mockRejectedValue(error),
        },
        auditLog: {
          create: vi.fn(),
        },
      };
      const ctx = createToolContext(
        {
          assignment: {
            findUnique: vi.fn().mockResolvedValue(assignment),
          },
          webhook: {
            findMany: vi.fn().mockResolvedValue([]),
          },
          $transaction: vi
            .fn()
            .mockImplementation(async (callback: (inner: typeof tx) => Promise<unknown>) =>
              callback(tx),
            ),
        },
        {
          userRole: SystemRole.ADMIN,
          permissions: [PermissionKey.MANAGE_ALLOCATIONS],
        },
      );

      const result = await executeTool(
        "update_allocation_status",
        JSON.stringify({ allocationId: "assignment_1", newStatus: "ACTIVE" }),
        ctx,
      );

      expect(JSON.parse(result.content)).toEqual({
        error: "Allocation not found with the given criteria.",
      });
    }
  });
});
