/**
 * Group Tools for Monday.com MCP Server
 * Tools for managing groups: list, create, update, delete, duplicate, move item to group
 */

import { z } from "zod";
import { Tool } from "@modelcontextprotocol/sdk/types.js";
import { MondayClient } from "../clients/monday.js";

// Zod Schemas
const ListGroupsSchema = z.object({
  board_id: z.string().describe("Board ID"),
});

const GetGroupSchema = z.object({
  board_id: z.string().describe("Board ID"),
  group_id: z.string().describe("Group ID"),
});

const CreateGroupSchema = z.object({
  board_id: z.string().describe("Board ID"),
  group_name: z.string().describe("Name of the new group"),
  group_color: z.string().optional().describe("Group color (hex or color name)"),
  position_relative_method: z.enum(["before_at", "after_at"]).optional().describe("Position relative to another group"),
  relative_to: z.string().optional().describe("Group ID to position relative to"),
});

const UpdateGroupSchema = z.object({
  board_id: z.string().describe("Board ID"),
  group_id: z.string().describe("Group ID to update"),
  group_attribute: z.enum(["title", "color", "position"]).describe("Attribute to update"),
  new_value: z.string().describe("New value for the attribute"),
});

const DeleteGroupSchema = z.object({
  board_id: z.string().describe("Board ID"),
  group_id: z.string().describe("Group ID to delete"),
});

const DuplicateGroupSchema = z.object({
  board_id: z.string().describe("Board ID"),
  group_id: z.string().describe("Group ID to duplicate"),
  add_to_top: z.boolean().optional().describe("Add duplicated group to top of board"),
  group_title: z.string().optional().describe("Title for the duplicated group"),
});

const ArchiveGroupSchema = z.object({
  board_id: z.string().describe("Board ID"),
  group_id: z.string().describe("Group ID to archive"),
});

/**
 * Get all group tools
 */
export function getTools(_client: MondayClient): Tool[] {
  return [
    {
      name: "monday_list_groups",
      description: "List all groups in a board with their IDs, titles, colors, and item counts.",
      inputSchema: {
        type: "object",
        properties: {
          board_id: { type: "string", description: "Board ID" },
        },
        required: ["board_id"],
      },
    },
    {
      name: "monday_get_group",
      description: "Get details for a specific group including all items in that group.",
      inputSchema: {
        type: "object",
        properties: {
          board_id: { type: "string", description: "Board ID" },
          group_id: { type: "string", description: "Group ID" },
        },
        required: ["board_id", "group_id"],
      },
    },
    {
      name: "monday_create_group",
      description: "Create a new group in a board. Optionally specify color and position relative to another group.",
      inputSchema: {
        type: "object",
        properties: {
          board_id: { type: "string", description: "Board ID" },
          group_name: { type: "string", description: "Name of the new group" },
          group_color: { type: "string", description: "Group color (hex or color name)" },
          position_relative_method: { type: "string", enum: ["before_at", "after_at"], description: "Position relative to another group" },
          relative_to: { type: "string", description: "Group ID to position relative to" },
        },
        required: ["board_id", "group_name"],
      },
    },
    {
      name: "monday_update_group",
      description: "Update a group's title, color, or position.",
      inputSchema: {
        type: "object",
        properties: {
          board_id: { type: "string", description: "Board ID" },
          group_id: { type: "string", description: "Group ID to update" },
          group_attribute: { type: "string", enum: ["title", "color", "position"], description: "Attribute to update" },
          new_value: { type: "string", description: "New value for the attribute" },
        },
        required: ["board_id", "group_id", "group_attribute", "new_value"],
      },
    },
    {
      name: "monday_delete_group",
      description: "Delete a group from a board. Items in the group will be moved to another group or deleted.",
      inputSchema: {
        type: "object",
        properties: {
          board_id: { type: "string", description: "Board ID" },
          group_id: { type: "string", description: "Group ID to delete" },
        },
        required: ["board_id", "group_id"],
      },
    },
    {
      name: "monday_duplicate_group",
      description: "Duplicate a group including all items. Optionally specify a new title.",
      inputSchema: {
        type: "object",
        properties: {
          board_id: { type: "string", description: "Board ID" },
          group_id: { type: "string", description: "Group ID to duplicate" },
          add_to_top: { type: "boolean", description: "Add duplicated group to top of board" },
          group_title: { type: "string", description: "Title for the duplicated group" },
        },
        required: ["board_id", "group_id"],
      },
    },
    {
      name: "monday_archive_group",
      description: "Archive a group. Archived groups can be restored later.",
      inputSchema: {
        type: "object",
        properties: {
          board_id: { type: "string", description: "Board ID" },
          group_id: { type: "string", description: "Group ID to archive" },
        },
        required: ["board_id", "group_id"],
      },
    },
  ];
}

/**
 * Execute group tool
 */
export async function executeGroupTool(
  client: MondayClient,
  toolName: string,
  args: any
): Promise<any> {
  switch (toolName) {
    case "monday_list_groups": {
      const params = ListGroupsSchema.parse(args);
      const board = await client.getBoard(params.board_id);
      return board.groups || [];
    }

    case "monday_get_group": {
      const params = GetGroupSchema.parse(args);
      const query = `
        query {
          boards(ids: [${params.board_id}]) {
            groups(ids: ["${params.group_id}"]) {
              id
              title
              color
              position
              archived
              items {
                id
                name
                state
              }
            }
          }
        }
      `;
      const result = await (client as any).query(query);
      const groups = result.data.boards[0]?.groups || [];
      if (groups.length === 0) {
        throw new Error(`Group ${params.group_id} not found in board ${params.board_id}`);
      }
      return groups[0];
    }

    case "monday_create_group": {
      const params = CreateGroupSchema.parse(args);
      return await client.createGroup(params);
    }

    case "monday_update_group": {
      const params = UpdateGroupSchema.parse(args);
      const query = `
        mutation {
          update_group(
            board_id: ${params.board_id}
            group_id: "${params.group_id}"
            group_attribute: ${params.group_attribute}
            new_value: "${params.new_value}"
          ) {
            id
            title
            color
          }
        }
      `;
      return await (client as any).query(query);
    }

    case "monday_delete_group": {
      const params = DeleteGroupSchema.parse(args);
      const query = `
        mutation {
          delete_group(
            board_id: ${params.board_id}
            group_id: "${params.group_id}"
          ) {
            id
          }
        }
      `;
      return await (client as any).query(query);
    }

    case "monday_duplicate_group": {
      const params = DuplicateGroupSchema.parse(args);
      let mutationArgs = [
        `board_id: ${params.board_id}`,
        `group_id: "${params.group_id}"`,
      ];
      if (params.add_to_top !== undefined) {
        mutationArgs.push(`add_to_top: ${params.add_to_top}`);
      }
      if (params.group_title) {
        mutationArgs.push(`group_title: "${params.group_title}"`);
      }

      const query = `
        mutation {
          duplicate_group(${mutationArgs.join(", ")}) {
            id
            title
          }
        }
      `;
      return await (client as any).query(query);
    }

    case "monday_archive_group": {
      const params = ArchiveGroupSchema.parse(args);
      const query = `
        mutation {
          archive_group(
            board_id: ${params.board_id}
            group_id: "${params.group_id}"
          ) {
            id
            archived
          }
        }
      `;
      return await (client as any).query(query);
    }

    default:
      throw new Error(`Unknown group tool: ${toolName}`);
  }
}
