import { beforeEach, describe, expect, it, vi } from "vitest";
import { SystemRole } from "@capakraken/shared";
import {
  createToolContext,
  executeTool,
  withUserLookup,
} from "./assistant-tools-task-workflow-test-helpers.js";

describe("assistant task workflow tools - assignment", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("assigns a task through the real router path and returns invalidate metadata", async () => {
    const db = withUserLookup(
      {
        notification: {
          findUnique: vi.fn().mockResolvedValue({
            id: "task_9",
            category: "TASK",
            assigneeId: "user_2",
          }),
          update: vi.fn().mockResolvedValue({
            id: "task_9",
            category: "TASK",
            assigneeId: "user_4",
          }),
        },
      },
      "user_mgr",
    );
    const ctx = createToolContext(db, SystemRole.MANAGER);

    const result = await executeTool(
      "assign_task",
      JSON.stringify({ id: "task_9", assigneeId: "user_4" }),
      ctx,
    );

    expect(db.notification.findUnique).toHaveBeenCalledWith({
      where: { id: "task_9" },
    });
    expect(db.notification.update).toHaveBeenCalledWith({
      where: { id: "task_9" },
      data: { assigneeId: "user_4" },
    });
    expect(result.action).toEqual({ type: "invalidate", scope: ["notification"] });
    expect(result.data).toEqual(
      expect.objectContaining({
        success: true,
        taskId: "task_9",
        message: "Assigned task task_9 to user_4.",
        task: expect.objectContaining({
          id: "task_9",
          assigneeId: "user_4",
        }),
      }),
    );
  });

  it("returns a stable assistant error when assigning a non-task notification", async () => {
    const ctx = createToolContext(
      withUserLookup({
        notification: {
          findUnique: vi.fn().mockResolvedValue({
            id: "notification_1",
            category: "NOTIFICATION",
          }),
        },
      }),
      SystemRole.MANAGER,
    );

    const result = await executeTool(
      "assign_task",
      JSON.stringify({ id: "notification_1", assigneeId: "user_2" }),
      ctx,
    );

    expect(JSON.parse(result.content)).toEqual({
      error: "Only tasks and approvals can be assigned.",
    });
  });

  it("returns a stable assistant error when assigning a task to a missing assignee", async () => {
    const ctx = createToolContext(
      withUserLookup({
        notification: {
          findUnique: vi.fn().mockResolvedValue({
            id: "task_1",
            category: "TASK",
          }),
          update: vi.fn().mockRejectedValue({
            code: "P2003",
            message: "Foreign key constraint failed",
            meta: { field_name: "Notification_assigneeId_fkey" },
          }),
        },
      }),
      SystemRole.MANAGER,
    );

    const result = await executeTool(
      "assign_task",
      JSON.stringify({ id: "task_1", assigneeId: "user_missing" }),
      ctx,
    );

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