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(),
    commitDispoImportBatch: vi.fn(),
    countPlanningEntries: vi.fn().mockResolvedValue({ countsByRoleId: new Map() }),
    createEstimateExport: vi.fn(),
    createEstimatePlanningHandoff: vi.fn(),
    createEstimateRevision: vi.fn(),
    assessDispoImportReadiness: vi.fn(),
    loadResourceDailyAvailabilityContexts: vi.fn().mockResolvedValue(new Map()),
    getDashboardDemand: vi.fn().mockResolvedValue([]),
    getDashboardBudgetForecast: vi.fn().mockResolvedValue([]),
    getDashboardOverview: vi.fn(),
    getDashboardSkillGapSummary: vi.fn().mockResolvedValue({
      roleGaps: [],
      totalOpenPositions: 0,
      skillSupplyTop10: [],
      resourcesByRole: [],
    }),
    getDashboardProjectHealth: vi.fn().mockResolvedValue([]),
    getDashboardPeakTimes: vi.fn().mockResolvedValue([]),
    getDashboardTopValueResources: vi.fn().mockResolvedValue([]),
    getEstimateById: vi.fn(),
    listAssignmentBookings: vi.fn().mockResolvedValue([]),
    stageDispoImportBatch: vi.fn(),
    submitEstimateVersion: vi.fn(),
    updateEstimateDraft: vi.fn(),
  };
});

vi.mock("../ai-client.js", async (importOriginal) => {
  const actual = await importOriginal<typeof import("../ai-client.js")>();
  return {
    ...actual,
    createDalleClient: vi.fn(() => ({
      images: {
        generate: vi.fn().mockResolvedValue({
          data: [{ b64_json: "ZmFrZQ==" }],
        }),
      },
    })),
    loggedAiCall: vi.fn(async (_provider, _model, _promptLength, fn) => fn()),
  };
});

import {
  createToolContext,
  executeTool,
} from "./assistant-tools-project-media-test-helpers.js";

describe("assistant project cover generation tools", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("routes project cover generation through the real project router path", async () => {
    const projectFindUnique = vi.fn()
      .mockResolvedValueOnce({
        id: "project_1",
        name: "Project One",
        shortCode: "PROJ-1",
        status: "ACTIVE",
        orderType: "CHARGEABLE",
        allocationType: "INT",
        budgetCents: 0,
        winProbability: 100,
        startDate: new Date("2026-05-01T00:00:00.000Z"),
        endDate: new Date("2026-06-30T00:00:00.000Z"),
        responsiblePerson: "Peter Parker",
        client: null,
        utilizationCategory: null,
        _count: { assignments: 0, estimates: 0 },
      })
      .mockResolvedValueOnce({
        id: "project_1",
        name: "Project One",
        client: { name: "Wayne Enterprises" },
      });
    const projectUpdate = vi.fn().mockResolvedValue({
      id: "project_1",
      coverImageUrl: "data:image/png;base64,ZmFrZQ==",
    });
    const ctx = createToolContext(
      {
        project: {
          findUnique: projectFindUnique,
          update: projectUpdate,
        },
        assignment: {
          findMany: vi.fn().mockResolvedValue([]),
        },
        systemSettings: {
          findUnique: vi.fn().mockResolvedValue({
            id: "singleton",
            imageProvider: "dalle",
            aiProvider: "openai",
            azureOpenAiApiKey: "sk-test",
            azureOpenAiDeployment: "gpt-4o-mini",
          }),
        },
      },
      {
        userRole: SystemRole.ADMIN,
        permissions: [PermissionKey.MANAGE_PROJECTS],
      },
    );

    const result = await executeTool(
      "generate_project_cover",
      JSON.stringify({ projectId: "project_1", prompt: "Blue studio lighting" }),
      ctx,
    );

    expect(projectUpdate).toHaveBeenCalledWith({
      where: { id: "project_1" },
      data: { coverImageUrl: "data:image/png;base64,ZmFrZQ==" },
    });
    expect(projectFindUnique).toHaveBeenCalledWith({
      where: { id: "project_1" },
      select: expect.objectContaining({
        id: true,
        shortCode: true,
        name: true,
        status: true,
        responsiblePerson: true,
        startDate: true,
        endDate: true,
      }),
    });
    expect(JSON.parse(result.content)).toEqual(
      expect.objectContaining({
        success: true,
        message: 'Generated cover art for project "Project One"',
      }),
    );
  });
});
