/**
 * Item Tools for Monday.com MCP Server
 * Tools for managing items and subitems: list, get, create, update, delete, move, duplicate, archive
 */

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

// Zod Schemas
const ListItemsSchema = z.object({
  board_id: z.string().describe("Board ID"),
  limit: z.number().min(1).max(100).optional().describe("Number of items to return"),
  page: z.number().min(1).optional().describe("Page number for pagination"),
  cursor: z.string().optional().describe("Cursor for pagination"),
  ids: z.array(z.string()).optional().describe("Filter by specific item IDs"),
  newest_first: z.boolean().optional().describe("Sort by newest first"),
});

const GetItemSchema = z.object({
  item_id: z.string().describe("Item ID"),
});

const CreateItemSchema = z.object({
  board_id: z.string().describe("Board ID"),
  group_id: z.string().optional().describe("Group ID to create item in"),
  item_name: z.string().describe("Name of the new item"),
  column_values: z.record(z.any()).optional().describe("Column values as JSON object (keys are column IDs)"),
  create_labels_if_missing: z.boolean().optional().describe("Create labels if they don't exist"),
});

const UpdateItemSchema = z.object({
  board_id: z.string().describe("Board ID"),
  item_id: z.string().describe("Item ID to update"),
  column_values: z.record(z.any()).describe("Column values to update (keys are column IDs)"),
});

const DeleteItemSchema = z.object({
  item_id: z.string().describe("Item ID to delete"),
});

const MoveItemToGroupSchema = z.object({
  item_id: z.string().describe("Item ID to move"),
  group_id: z.string().describe("Target group ID"),
});

const MoveItemToBoardSchema = z.object({
  item_id: z.string().describe("Item ID to move"),
  board_id: z.string().describe("Target board ID"),
  group_id: z.string().describe("Target group ID in the new board"),
});

const DuplicateItemSchema = z.object({
  board_id: z.string().describe("Board ID"),
  item_id: z.string().describe("Item ID to duplicate"),
  with_updates: z.boolean().optional().describe("Include updates in duplicate"),
});

const ArchiveItemSchema = z.object({
  item_id: z.string().describe("Item ID to archive"),
});

const CreateSubitemSchema = z.object({
  parent_item_id: z.string().describe("Parent item ID"),
  item_name: z.string().describe("Name of the new subitem"),
  column_values: z.record(z.any()).optional().describe("Column values for the subitem"),
});

const ListSubitemsSchema = z.object({
  parent_item_id: z.string().describe("Parent item ID"),
});

const ClearItemUpdatesSchema = z.object({
  item_id: z.string().describe("Item ID to clear updates from"),
});

const ChangeItemNameSchema = z.object({
  board_id: z.string().describe("Board ID"),
  item_id: z.string().describe("Item ID"),
  new_name: z.string().describe("New name for the item"),
});

/**
 * Get all item tools
 */
export function getTools(_client: MondayClient): Tool[] {
  return [
    {
      name: "monday_list_items",
      description: "List items from a board. Supports cursor-based pagination, filtering by IDs, and sorting. Use cursor from previous response for next page.",
      inputSchema: {
        type: "object",
        properties: {
          board_id: { type: "string", description: "Board ID" },
          limit: { type: "number", description: "Number of items to return (default: 25, max: 100)" },
          page: { type: "number", description: "Page number for pagination" },
          cursor: { type: "string", description: "Cursor from previous response for pagination" },
          ids: { type: "array", items: { type: "string" }, description: "Filter by specific item IDs" },
          newest_first: { type: "boolean", description: "Sort by newest first" },
        },
        required: ["board_id"],
      },
    },
    {
      name: "monday_get_item",
      description: "Get a single item by ID with full details including all column values, subitems, and metadata.",
      inputSchema: {
        type: "object",
        properties: {
          item_id: { type: "string", description: "Item ID" },
        },
        required: ["item_id"],
      },
    },
    {
      name: "monday_create_item",
      description: "Create a new item in a board. Optionally specify group and column values. Column values must match the column type (e.g., {text: 'value'} for text columns).",
      inputSchema: {
        type: "object",
        properties: {
          board_id: { type: "string", description: "Board ID" },
          group_id: { type: "string", description: "Group ID to create item in" },
          item_name: { type: "string", description: "Name of the new item" },
          column_values: { type: "object", description: "Column values as JSON object (keys are column IDs)" },
          create_labels_if_missing: { type: "boolean", description: "Create labels if they don't exist" },
        },
        required: ["board_id", "item_name"],
      },
    },
    {
      name: "monday_update_item",
      description: "Update multiple column values for an item in a single request. More efficient than changing values one by one.",
      inputSchema: {
        type: "object",
        properties: {
          board_id: { type: "string", description: "Board ID" },
          item_id: { type: "string", description: "Item ID to update" },
          column_values: { type: "object", description: "Column values to update (keys are column IDs)" },
        },
        required: ["board_id", "item_id", "column_values"],
      },
    },
    {
      name: "monday_delete_item",
      description: "Permanently delete an item. This action cannot be undone.",
      inputSchema: {
        type: "object",
        properties: {
          item_id: { type: "string", description: "Item ID to delete" },
        },
        required: ["item_id"],
      },
    },
    {
      name: "monday_move_item_to_group",
      description: "Move an item to a different group within the same board.",
      inputSchema: {
        type: "object",
        properties: {
          item_id: { type: "string", description: "Item ID to move" },
          group_id: { type: "string", description: "Target group ID" },
        },
        required: ["item_id", "group_id"],
      },
    },
    {
      name: "monday_move_item_to_board",
      description: "Move an item to a different board and group. The item will be removed from the source board.",
      inputSchema: {
        type: "object",
        properties: {
          item_id: { type: "string", description: "Item ID to move" },
          board_id: { type: "string", description: "Target board ID" },
          group_id: { type: "string", description: "Target group ID in the new board" },
        },
        required: ["item_id", "board_id", "group_id"],
      },
    },
    {
      name: "monday_duplicate_item",
      description: "Duplicate an item within the same board. Optionally include updates/comments.",
      inputSchema: {
        type: "object",
        properties: {
          board_id: { type: "string", description: "Board ID" },
          item_id: { type: "string", description: "Item ID to duplicate" },
          with_updates: { type: "boolean", description: "Include updates in duplicate" },
        },
        required: ["board_id", "item_id"],
      },
    },
    {
      name: "monday_archive_item",
      description: "Archive an item. Archived items can be restored later.",
      inputSchema: {
        type: "object",
        properties: {
          item_id: { type: "string", description: "Item ID to archive" },
        },
        required: ["item_id"],
      },
    },
    {
      name: "monday_create_subitem",
      description: "Create a subitem (child item) under a parent item. Subitems have their own column values.",
      inputSchema: {
        type: "object",
        properties: {
          parent_item_id: { type: "string", description: "Parent item ID" },
          item_name: { type: "string", description: "Name of the new subitem" },
          column_values: { type: "object", description: "Column values for the subitem" },
        },
        required: ["parent_item_id", "item_name"],
      },
    },
    {
      name: "monday_list_subitems",
      description: "List all subitems of a parent item.",
      inputSchema: {
        type: "object",
        properties: {
          parent_item_id: { type: "string", description: "Parent item ID" },
        },
        required: ["parent_item_id"],
      },
    },
    {
      name: "monday_clear_item_updates",
      description: "Clear all updates (comments/activity) from an item.",
      inputSchema: {
        type: "object",
        properties: {
          item_id: { type: "string", description: "Item ID to clear updates from" },
        },
        required: ["item_id"],
      },
    },
    {
      name: "monday_change_item_name",
      description: "Change the name of an item.",
      inputSchema: {
        type: "object",
        properties: {
          board_id: { type: "string", description: "Board ID" },
          item_id: { type: "string", description: "Item ID" },
          new_name: { type: "string", description: "New name for the item" },
        },
        required: ["board_id", "item_id", "new_name"],
      },
    },
  ];
}

/**
 * Execute item tool
 */
export async function executeItemTool(
  client: MondayClient,
  toolName: string,
  args: any
): Promise<any> {
  switch (toolName) {
    case "monday_list_items": {
      const params = ListItemsSchema.parse(args);
      return await client.getItems(params.board_id, params);
    }

    case "monday_get_item": {
      const params = GetItemSchema.parse(args);
      return await client.getItem(params.item_id);
    }

    case "monday_create_item": {
      const params = CreateItemSchema.parse(args);
      return await client.createItem(params);
    }

    case "monday_update_item": {
      const params = UpdateItemSchema.parse(args);
      const jsonValue = JSON.stringify(JSON.stringify(params.column_values));
      const query = `
        mutation {
          change_multiple_column_values(
            board_id: ${params.board_id}
            item_id: ${params.item_id}
            column_values: ${jsonValue}
          ) {
            id
            name
            column_values {
              id
              text
              value
            }
          }
        }
      `;
      return await (client as any).query(query);
    }

    case "monday_delete_item": {
      const params = DeleteItemSchema.parse(args);
      const query = `
        mutation {
          delete_item(item_id: ${params.item_id}) {
            id
          }
        }
      `;
      return await (client as any).query(query);
    }

    case "monday_move_item_to_group": {
      const params = MoveItemToGroupSchema.parse(args);
      const query = `
        mutation {
          move_item_to_group(
            item_id: ${params.item_id}
            group_id: "${params.group_id}"
          ) {
            id
            group {
              id
              title
            }
          }
        }
      `;
      return await (client as any).query(query);
    }

    case "monday_move_item_to_board": {
      const params = MoveItemToBoardSchema.parse(args);
      const query = `
        mutation {
          move_item_to_board(
            item_id: ${params.item_id}
            board_id: ${params.board_id}
            group_id: "${params.group_id}"
          ) {
            id
            board {
              id
              name
            }
            group {
              id
              title
            }
          }
        }
      `;
      return await (client as any).query(query);
    }

    case "monday_duplicate_item": {
      const params = DuplicateItemSchema.parse(args);
      let mutationArgs = [`board_id: ${params.board_id}`, `item_id: ${params.item_id}`];
      if (params.with_updates !== undefined) {
        mutationArgs.push(`with_updates: ${params.with_updates}`);
      }
      const query = `
        mutation {
          duplicate_item(${mutationArgs.join(", ")}) {
            id
            name
          }
        }
      `;
      return await (client as any).query(query);
    }

    case "monday_archive_item": {
      const params = ArchiveItemSchema.parse(args);
      const query = `
        mutation {
          archive_item(item_id: ${params.item_id}) {
            id
            state
          }
        }
      `;
      return await (client as any).query(query);
    }

    case "monday_create_subitem": {
      const params = CreateSubitemSchema.parse(args);
      let mutationArgs = [
        `parent_item_id: ${params.parent_item_id}`,
        `item_name: "${params.item_name}"`,
      ];
      if (params.column_values) {
        const jsonValue = JSON.stringify(JSON.stringify(params.column_values));
        mutationArgs.push(`column_values: ${jsonValue}`);
      }
      const query = `
        mutation {
          create_subitem(${mutationArgs.join(", ")}) {
            id
            name
            board {
              id
            }
          }
        }
      `;
      return await (client as any).query(query);
    }

    case "monday_list_subitems": {
      const params = ListSubitemsSchema.parse(args);
      const query = `
        query {
          items(ids: [${params.parent_item_id}]) {
            subitems {
              id
              name
              board {
                id
                name
              }
              column_values {
                id
                text
                value
                type
              }
            }
          }
        }
      `;
      const result = await (client as any).query(query);
      return result.data.items[0]?.subitems || [];
    }

    case "monday_clear_item_updates": {
      const params = ClearItemUpdatesSchema.parse(args);
      const query = `
        mutation {
          clear_item_updates(item_id: ${params.item_id}) {
            id
          }
        }
      `;
      return await (client as any).query(query);
    }

    case "monday_change_item_name": {
      const params = ChangeItemNameSchema.parse(args);
      const query = `
        mutation {
          change_multiple_column_values(
            board_id: ${params.board_id}
            item_id: ${params.item_id}
            column_values: "{\\"name\\":\\"${params.new_name}\\"}"
          ) {
            id
            name
          }
        }
      `;
      return await (client as any).query(query);
    }

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