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

import {
  createRoleRecord,
  createToolContext,
  executeTool,
  resetRoleMutationMocks,
} from "./assistant-tools-role-mutation-test-helpers.js";

describe("assistant role create and update tools - success", () => {
  beforeEach(() => {
    resetRoleMutationMocks();
  });

  it("routes create and update role mutations through their backing router", async () => {
    const db = {
      role: {
        findUnique: vi.fn().mockImplementation(async (args?: { where?: { name?: string; id?: string } }) => {
          if (args?.where?.name === "Pipeline TD") return null;
          if (args?.where?.name === "Pipeline Lead") return null;
          if (args?.where?.id === "role_pipeline") {
            return {
              id: "role_pipeline",
              name: "Pipeline TD",
              description: "Pipeline craft",
              color: "#123456",
              isActive: true,
              _count: { resourceRoles: 0 },
              resourceRoles: [],
            };
          }
          return null;
        }),
        create: vi.fn().mockResolvedValue({
          id: "role_pipeline",
          name: "Pipeline TD",
          description: "Pipeline craft",
          color: "#123456",
          isActive: true,
          _count: { resourceRoles: 0 },
        }),
        update: vi.fn().mockResolvedValue({
          id: "role_pipeline",
          name: "Pipeline Lead",
          description: "Lead pipeline craft",
          color: "#654321",
          isActive: false,
          _count: { resourceRoles: 0 },
        }),
      },
      auditLog: {
        create: vi.fn().mockResolvedValue({ id: "audit_1" }),
      },
    };
    const ctx = createToolContext(db, {
      userRole: SystemRole.ADMIN,
      permissions: [PermissionKey.MANAGE_ROLES],
    });

    const createRoleResult = await executeTool(
      "create_role",
      JSON.stringify({ name: "Pipeline TD", description: "Pipeline craft", color: "#123456" }),
      ctx,
    );
    const updateRoleResult = await executeTool(
      "update_role",
      JSON.stringify({
        id: "role_pipeline",
        name: "Pipeline Lead",
        description: "Lead pipeline craft",
        color: "#654321",
        isActive: false,
      }),
      ctx,
    );

    expect(JSON.parse(createRoleResult.content)).toEqual(expect.objectContaining({
      success: true,
      roleId: "role_pipeline",
      message: "Created role: Pipeline TD",
    }));
    expect(JSON.parse(updateRoleResult.content)).toEqual(expect.objectContaining({
      success: true,
      roleId: "role_pipeline",
      message: "Updated role: Pipeline Lead",
    }));

    expect(db.role.create).toHaveBeenCalled();
    expect(db.role.update).toHaveBeenCalled();
    expect(db.auditLog.create).toHaveBeenCalled();
  });

  it("returns the expected assistant payloads for create and update role mutations", async () => {
    const roleRecord = createRoleRecord();
    const db = {
      role: {
        findUnique: vi.fn()
          .mockResolvedValueOnce(null)
          .mockResolvedValueOnce({ id: "role_1", name: "CG Artist", description: null, color: "#111111", isActive: true })
          .mockResolvedValueOnce(null)
          .mockResolvedValueOnce(roleRecord),
        create: vi.fn().mockResolvedValue({
          id: "role_1",
          name: "CG Artist",
          description: null,
          color: "#111111",
          isActive: true,
          _count: { resourceRoles: 0 },
        }),
        update: vi.fn().mockResolvedValue({
          id: "role_1",
          name: "Senior CG Artist",
          description: "Pipeline lead",
          color: "#222222",
          isActive: true,
          _count: { resourceRoles: 0 },
        }),
      },
      auditLog: {
        create: vi.fn().mockResolvedValue({ id: "audit_1" }),
      },
      demandRequirement: {
        groupBy: vi.fn().mockResolvedValue([]),
      },
      assignment: {
        groupBy: vi.fn().mockResolvedValue([]),
      },
    };
    const ctx = createToolContext(db, {
      userRole: SystemRole.ADMIN,
      permissions: [PermissionKey.MANAGE_ROLES],
    });

    const createRoleResult = await executeTool(
      "create_role",
      JSON.stringify({ name: "CG Artist", color: "#111111" }),
      ctx,
    );
    const updateRoleResult = await executeTool(
      "update_role",
      JSON.stringify({
        id: "role_1",
        name: "Senior CG Artist",
        description: "Pipeline lead",
        color: "#222222",
      }),
      ctx,
    );

    expect(JSON.parse(createRoleResult.content)).toEqual(expect.objectContaining({
      success: true,
      message: "Created role: CG Artist",
    }));
    expect(JSON.parse(updateRoleResult.content)).toEqual(expect.objectContaining({
      success: true,
      message: "Updated role: Senior CG Artist",
    }));
  });
});
