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

vi.mock("@capakraken/application", async (importOriginal) => {
  const actual = await importOriginal<typeof import("@capakraken/application")>();
  return {
    ...actual,
    approveEstimateVersion: vi.fn(),
    cloneEstimate: vi.fn(),
    createEstimateExport: vi.fn(),
    createEstimatePlanningHandoff: vi.fn(),
    createEstimateRevision: vi.fn(),
    getDashboardBudgetForecast: vi.fn().mockResolvedValue([]),
    getDashboardPeakTimes: vi.fn().mockResolvedValue([]),
    getEstimateById: vi.fn(),
    listAssignmentBookings: vi.fn().mockResolvedValue([]),
    submitEstimateVersion: vi.fn(),
    updateEstimateDraft: vi.fn(),
  };
});

import { executeTool } from "../router/assistant-tools.js";
import {
  createToolContext,
  resetEstimateToolMocks,
} from "./assistant-tools-estimate-test-helpers.js";

const managerOptions = {
  userRole: SystemRole.MANAGER,
  permissions: [PermissionKey.MANAGE_PROJECTS],
} as const;

describe("assistant estimate commercial terms errors", () => {
  beforeEach(() => {
    resetEstimateToolMocks();
  });

  it("returns a stable error when update_estimate_commercial_terms cannot resolve a version", async () => {
    const ctx = createToolContext(
      {
        estimate: {
          findUnique: vi.fn().mockResolvedValue(null),
        },
      },
      managerOptions,
    );

    const result = await executeTool(
      "update_estimate_commercial_terms",
      JSON.stringify({
        estimateId: "est_1",
        terms: {},
      }),
      ctx,
    );

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

  it("returns a stable error when update_estimate_commercial_terms targets a non-working version", async () => {
    const ctx = createToolContext(
      {
        estimate: {
          findUnique: vi.fn().mockResolvedValue({
            id: "est_1",
            versions: [{ id: "ver_1", status: "APPROVED" }],
          }),
        },
      },
      managerOptions,
    );

    const result = await executeTool(
      "update_estimate_commercial_terms",
      JSON.stringify({
        estimateId: "est_1",
        terms: {},
      }),
      ctx,
    );

    expect(JSON.parse(result.content)).toEqual({
      error: "Commercial terms can only be edited on working versions.",
    });
  });

  it("returns a stable error when update_estimate_commercial_terms input is invalid", async () => {
    const ctx = createToolContext({}, managerOptions);
    const result = await executeTool(
      "update_estimate_commercial_terms",
      JSON.stringify({
        estimateId: "est_1",
        terms: {
          contingencyPercent: -1,
        },
      }),
      ctx,
    );

    expect(JSON.parse(result.content)).toEqual({
      error: "Commercial terms input is invalid.",
    });
  });

  it("returns a stable error when update_estimate_commercial_terms loses the version during persistence", async () => {
    const ctx = createToolContext(
      {
        estimate: {
          findUnique: vi.fn().mockResolvedValue({
            id: "est_1",
            versions: [{ id: "ver_working", status: "WORKING" }],
          }),
        },
        estimateVersion: {
          update: vi.fn().mockRejectedValue({
            code: "P2025",
            message: "Record to update not found",
            meta: { modelName: "EstimateVersion" },
          }),
        },
      },
      managerOptions,
    );

    const result = await executeTool(
      "update_estimate_commercial_terms",
      JSON.stringify({
        estimateId: "est_1",
        terms: {},
      }),
      ctx,
    );

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

  it("returns a stable error when get_estimate_commercial_terms cannot resolve a version", async () => {
    const ctx = createToolContext(
      {
        estimate: {
          findUnique: vi.fn().mockResolvedValue(null),
        },
      },
      {
        userRole: SystemRole.CONTROLLER,
      },
    );

    const result = await executeTool(
      "get_estimate_commercial_terms",
      JSON.stringify({ estimateId: "est_missing" }),
      ctx,
    );

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