import type { WrikeClient } from '../clients/wrike.js';
import type { WrikeTask, CreateTaskRequest, UpdateTaskRequest } from '../types/index.js';

export function createTaskTools(client: WrikeClient) {
  return {
    // List tasks
    wrike_list_tasks: {
      name: 'wrike_list_tasks',
      description: 'List all tasks with optional filters (folder, status, assignee, date ranges, etc.)',
      inputSchema: {
        type: 'object',
        properties: {
          folderId: { type: 'string', description: 'Filter by folder ID' },
          descendants: { type: 'boolean', description: 'Include tasks from subfolders' },
          status: { type: 'string', description: 'Filter by status (Active, Completed, Deferred, Cancelled)' },
          importance: { type: 'string', description: 'Filter by importance (High, Normal, Low)' },
          responsibles: { type: 'array', items: { type: 'string' }, description: 'Filter by responsible user IDs' },
          authors: { type: 'array', items: { type: 'string' }, description: 'Filter by author user IDs' },
          startDateStart: { type: 'string', description: 'Start date range begin (YYYY-MM-DD)' },
          startDateEnd: { type: 'string', description: 'Start date range end (YYYY-MM-DD)' },
          dueDateStart: { type: 'string', description: 'Due date range begin (YYYY-MM-DD)' },
          dueDateEnd: { type: 'string', description: 'Due date range end (YYYY-MM-DD)' },
          updatedDateStart: { type: 'string', description: 'Updated date range begin (ISO 8601)' },
          updatedDateEnd: { type: 'string', description: 'Updated date range end (ISO 8601)' },
          fields: { type: 'array', items: { type: 'string' }, description: 'Additional fields to include' },
          limit: { type: 'number', description: 'Maximum number of tasks to return' },
        },
      },
      handler: async (params: Record<string, unknown>) => {
        const queryParams: Record<string, unknown> = {};
        
        if (params.descendants !== undefined) queryParams.descendants = params.descendants;
        if (params.status) queryParams.status = params.status;
        if (params.importance) queryParams.importance = params.importance;
        if (params.responsibles) queryParams.responsibles = params.responsibles;
        if (params.authors) queryParams.authors = params.authors;
        if (params.fields) queryParams.fields = params.fields;
        if (params.limit) queryParams.limit = params.limit;
        
        if (params.startDateStart || params.startDateEnd) {
          queryParams.scheduledDate = {
            start: params.startDateStart,
            end: params.startDateEnd,
          };
        }
        
        if (params.dueDateStart || params.dueDateEnd) {
          queryParams.dueDate = {
            start: params.dueDateStart,
            end: params.dueDateEnd,
          };
        }
        
        if (params.updatedDateStart || params.updatedDateEnd) {
          queryParams.updatedDate = {
            start: params.updatedDateStart,
            end: params.updatedDateEnd,
          };
        }
        
        const endpoint = params.folderId 
          ? `/folders/${params.folderId}/tasks`
          : '/tasks';
        
        const response = await client.get<WrikeTask>(endpoint, queryParams);
        
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(response.data, null, 2),
            },
          ],
        };
      },
    },

    // Get task by ID
    wrike_get_task: {
      name: 'wrike_get_task',
      description: 'Get a specific task by ID with full details',
      inputSchema: {
        type: 'object',
        properties: {
          taskId: { type: 'string', description: 'Task ID (required)' },
          fields: { type: 'array', items: { type: 'string' }, description: 'Additional fields to include' },
        },
        required: ['taskId'],
      },
      handler: async (params: { taskId: string; fields?: string[] }) => {
        const response = await client.get<WrikeTask>(`/tasks/${params.taskId}`, {
          fields: params.fields,
        });
        
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(response.data[0], null, 2),
            },
          ],
        };
      },
    },

    // Create task
    wrike_create_task: {
      name: 'wrike_create_task',
      description: 'Create a new task in a folder',
      inputSchema: {
        type: 'object',
        properties: {
          folderId: { type: 'string', description: 'Parent folder ID (required)' },
          title: { type: 'string', description: 'Task title (required)' },
          description: { type: 'string', description: 'Task description (HTML supported)' },
          status: { type: 'string', description: 'Task status' },
          importance: { type: 'string', enum: ['High', 'Normal', 'Low'], description: 'Task importance' },
          startDate: { type: 'string', description: 'Start date (YYYY-MM-DD)' },
          dueDate: { type: 'string', description: 'Due date (YYYY-MM-DD)' },
          responsibles: { type: 'array', items: { type: 'string' }, description: 'Responsible user IDs' },
          followers: { type: 'array', items: { type: 'string' }, description: 'Follower user IDs' },
          shareds: { type: 'array', items: { type: 'string' }, description: 'Shared folder IDs' },
          customStatus: { type: 'string', description: 'Custom status ID' },
          priority: { type: 'string', description: 'Priority (before/after task ID)' },
        },
        required: ['folderId', 'title'],
      },
      handler: async (params: { folderId: string; title: string; [key: string]: unknown }) => {
        const body: CreateTaskRequest = {
          title: params.title,
        };
        
        if (params.description) body.description = params.description as string;
        if (params.status) body.status = params.status as string;
        if (params.importance) body.importance = params.importance as 'High' | 'Normal' | 'Low';
        if (params.responsibles) body.responsibles = params.responsibles as string[];
        if (params.followers) body.followers = params.followers as string[];
        if (params.shareds) body.shareds = params.shareds as string[];
        if (params.customStatus) body.customStatus = params.customStatus as string;
        
        if (params.startDate || params.dueDate) {
          body.dates = {
            start: params.startDate as string,
            due: params.dueDate as string,
          };
        }
        
        const response = await client.post<WrikeTask>(`/folders/${params.folderId}/tasks`, body);
        
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(response.data[0], null, 2),
            },
          ],
        };
      },
    },

    // Update task
    wrike_update_task: {
      name: 'wrike_update_task',
      description: 'Update an existing task',
      inputSchema: {
        type: 'object',
        properties: {
          taskId: { type: 'string', description: 'Task ID (required)' },
          title: { type: 'string', description: 'New task title' },
          description: { type: 'string', description: 'New task description' },
          status: { type: 'string', description: 'New status' },
          importance: { type: 'string', enum: ['High', 'Normal', 'Low'], description: 'New importance' },
          startDate: { type: 'string', description: 'New start date (YYYY-MM-DD)' },
          dueDate: { type: 'string', description: 'New due date (YYYY-MM-DD)' },
          addResponsibles: { type: 'array', items: { type: 'string' }, description: 'User IDs to add as responsibles' },
          removeResponsibles: { type: 'array', items: { type: 'string' }, description: 'User IDs to remove from responsibles' },
          addFollowers: { type: 'array', items: { type: 'string' }, description: 'User IDs to add as followers' },
          removeFollowers: { type: 'array', items: { type: 'string' }, description: 'User IDs to remove from followers' },
          customStatus: { type: 'string', description: 'New custom status ID' },
          restore: { type: 'boolean', description: 'Restore from Recycle Bin' },
        },
        required: ['taskId'],
      },
      handler: async (params: { taskId: string; [key: string]: unknown }) => {
        const body: UpdateTaskRequest = {};
        
        if (params.title) body.title = params.title as string;
        if (params.description !== undefined) body.description = params.description as string;
        if (params.status) body.status = params.status as string;
        if (params.importance) body.importance = params.importance as 'High' | 'Normal' | 'Low';
        if (params.addResponsibles) body.addResponsibles = params.addResponsibles as string[];
        if (params.removeResponsibles) body.removeResponsibles = params.removeResponsibles as string[];
        if (params.addFollowers) body.addFollowers = params.addFollowers as string[];
        if (params.removeFollowers) body.removeFollowers = params.removeFollowers as string[];
        if (params.customStatus) body.customStatus = params.customStatus as string;
        if (params.restore) body.restore = params.restore as boolean;
        
        if (params.startDate || params.dueDate) {
          body.dates = {
            start: params.startDate as string,
            due: params.dueDate as string,
          };
        }
        
        const response = await client.put<WrikeTask>(`/tasks/${params.taskId}`, body);
        
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(response.data[0], null, 2),
            },
          ],
        };
      },
    },

    // Delete task
    wrike_delete_task: {
      name: 'wrike_delete_task',
      description: 'Delete a task (moves to Recycle Bin)',
      inputSchema: {
        type: 'object',
        properties: {
          taskId: { type: 'string', description: 'Task ID (required)' },
        },
        required: ['taskId'],
      },
      handler: async (params: { taskId: string }) => {
        const response = await client.delete<WrikeTask>(`/tasks/${params.taskId}`);
        
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(response.data[0], null, 2),
            },
          ],
        };
      },
    },

    // Search tasks
    wrike_search_tasks: {
      name: 'wrike_search_tasks',
      description: 'Search tasks by title, description, or custom fields',
      inputSchema: {
        type: 'object',
        properties: {
          title: { type: 'string', description: 'Search in task titles' },
          description: { type: 'string', description: 'Search in task descriptions' },
          status: { type: 'string', description: 'Filter by status' },
          importance: { type: 'string', description: 'Filter by importance' },
          limit: { type: 'number', description: 'Maximum results' },
        },
      },
      handler: async (params: Record<string, unknown>) => {
        const response = await client.get<WrikeTask>('/tasks', params);
        
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(response.data, null, 2),
            },
          ],
        };
      },
    },

    // Add dependencies
    wrike_add_dependency: {
      name: 'wrike_add_dependency',
      description: 'Add a dependency between two tasks',
      inputSchema: {
        type: 'object',
        properties: {
          taskId: { type: 'string', description: 'Task ID (successor)' },
          predecessorId: { type: 'string', description: 'Predecessor task ID' },
          relationType: { 
            type: 'string', 
            enum: ['StartToStart', 'StartToFinish', 'FinishToStart', 'FinishToFinish'],
            description: 'Dependency relation type' 
          },
        },
        required: ['taskId', 'predecessorId'],
      },
      handler: async (params: { taskId: string; predecessorId: string; relationType?: string }) => {
        const body = {
          predecessors: [params.predecessorId],
          relationType: params.relationType || 'FinishToStart',
        };
        
        const response = await client.post(`/tasks/${params.taskId}/dependencies`, body);
        
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(response.data, null, 2),
            },
          ],
        };
      },
    },

    // Get task dependencies
    wrike_get_dependencies: {
      name: 'wrike_get_dependencies',
      description: 'Get all dependencies for a task',
      inputSchema: {
        type: 'object',
        properties: {
          taskId: { type: 'string', description: 'Task ID (required)' },
        },
        required: ['taskId'],
      },
      handler: async (params: { taskId: string }) => {
        const response = await client.get(`/tasks/${params.taskId}/dependencies`);
        
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(response.data, null, 2),
            },
          ],
        };
      },
    },

    // Remove dependency
    wrike_remove_dependency: {
      name: 'wrike_remove_dependency',
      description: 'Remove a dependency between tasks',
      inputSchema: {
        type: 'object',
        properties: {
          taskId: { type: 'string', description: 'Task ID (successor)' },
          dependencyId: { type: 'string', description: 'Dependency ID to remove' },
        },
        required: ['taskId', 'dependencyId'],
      },
      handler: async (params: { taskId: string; dependencyId: string }) => {
        const response = await client.delete(`/tasks/${params.taskId}/dependencies/${params.dependencyId}`);
        
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(response.data, null, 2),
            },
          ],
        };
      },
    },
  };
}
