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

import {
  createExistingAssignment,
  createToolContext,
  executeTool,
} from "./assistant-tools-timeline-shifts-test-helpers.js";

describe("assistant timeline allocation shift errors", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("returns stable allocation-not-found errors when timeline allocation persistence loses the row", async () => {
    const existingAssignment = createExistingAssignment();
    const missingDuringUpdate = {
      code: "P2025",
      message: "Record to update not found",
      meta: { modelName: "Assignment" },
    };

    const batchShiftCtx = createToolContext(
      {
        allocation: {
          findUnique: vi.fn().mockResolvedValue(null),
        },
        demandRequirement: {
          findUnique: vi.fn().mockResolvedValue(null),
        },
        assignment: {
          findUnique: vi.fn().mockResolvedValue(existingAssignment),
        },
        auditLog: {
          create: vi.fn().mockResolvedValue({}),
        },
        $transaction: vi.fn(async () => {
          throw missingDuringUpdate;
        }),
      },
      [PermissionKey.MANAGE_ALLOCATIONS, PermissionKey.USE_ASSISTANT_ADVANCED_TOOLS],
      SystemRole.MANAGER,
    );

    const batchShiftResult = await executeTool(
      "batch_shift_timeline_allocations",
      JSON.stringify({
        allocationIds: ["assignment_1"],
        daysDelta: 2,
        mode: "move",
      }),
      batchShiftCtx,
    );
    expect(JSON.parse(batchShiftResult.content)).toEqual({
      error: "Allocation not found with the given criteria.",
    });
  });

  it("returns a stable allocation-not-found error for batch timeline shifts without matches", async () => {
    const db = {
      allocation: {
        findUnique: vi.fn().mockResolvedValue(null),
      },
      demandRequirement: {
        findUnique: vi.fn().mockResolvedValue(null),
      },
      assignment: {
        findUnique: vi.fn().mockResolvedValue(null),
      },
    };
    const ctx = createToolContext(
      db,
      [PermissionKey.MANAGE_ALLOCATIONS, PermissionKey.USE_ASSISTANT_ADVANCED_TOOLS],
      SystemRole.MANAGER,
    );

    const result = await executeTool(
      "batch_shift_timeline_allocations",
      JSON.stringify({
        allocationIds: ["assignment_missing"],
        daysDelta: 2,
        mode: "move",
      }),
      ctx,
    );

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

  it("returns a stable demand-requirement-not-found error for batch timeline shifts", async () => {
    const demandRequirement = {
      id: "demand_requirement_1",
      startDate: new Date("2026-03-10"),
      endDate: new Date("2026-03-14"),
    };
    const db = {
      allocation: {
        findUnique: vi.fn().mockResolvedValue(null),
      },
      demandRequirement: {
        findUnique: vi.fn().mockResolvedValue(demandRequirement),
      },
      assignment: {
        findUnique: vi.fn().mockResolvedValue(null),
      },
      $transaction: vi.fn(async () => {
        throw new TRPCError({
          code: "NOT_FOUND",
          message: "Demand requirement not found",
        });
      }),
    };
    const ctx = createToolContext(
      db,
      [PermissionKey.MANAGE_ALLOCATIONS, PermissionKey.USE_ASSISTANT_ADVANCED_TOOLS],
      SystemRole.MANAGER,
    );

    const result = await executeTool(
      "batch_shift_timeline_allocations",
      JSON.stringify({
        allocationIds: ["demand_requirement_missing"],
        daysDelta: 3,
        mode: "move",
      }),
      ctx,
    );

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