import type { WrikeClient } from '../clients/wrike.js';
import type { WrikeFolder, CreateFolderRequest } from '../types/index.js';

export function createFolderTools(client: WrikeClient) {
  return {
    // List folders
    wrike_list_folders: {
      name: 'wrike_list_folders',
      description: 'List all folders and projects',
      inputSchema: {
        type: 'object',
        properties: {
          permalink: { type: 'string', description: 'Filter by permalink' },
          descendants: { type: 'boolean', description: 'Include subfolders' },
          project: { type: 'boolean', description: 'Filter by project folders only' },
          updatedDateStart: { type: 'string', description: 'Updated date range begin' },
          updatedDateEnd: { type: 'string', description: 'Updated date range end' },
          fields: { type: 'array', items: { type: 'string' }, description: 'Additional fields' },
        },
      },
      handler: async (params: Record<string, unknown>) => {
        const queryParams: Record<string, unknown> = {};
        
        if (params.permalink) queryParams.permalink = params.permalink;
        if (params.descendants) queryParams.descendants = params.descendants;
        if (params.project) queryParams.project = params.project;
        if (params.fields) queryParams.fields = params.fields;
        
        if (params.updatedDateStart || params.updatedDateEnd) {
          queryParams.updatedDate = {
            start: params.updatedDateStart,
            end: params.updatedDateEnd,
          };
        }
        
        const response = await client.get<WrikeFolder>('/folders', queryParams);
        
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(response.data, null, 2),
            },
          ],
        };
      },
    },

    // Get folder by ID
    wrike_get_folder: {
      name: 'wrike_get_folder',
      description: 'Get a specific folder or project by ID',
      inputSchema: {
        type: 'object',
        properties: {
          folderId: { type: 'string', description: 'Folder ID (required)' },
          fields: { type: 'array', items: { type: 'string' }, description: 'Additional fields' },
        },
        required: ['folderId'],
      },
      handler: async (params: { folderId: string; fields?: string[] }) => {
        const response = await client.get<WrikeFolder>(`/folders/${params.folderId}`, {
          fields: params.fields,
        });
        
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(response.data[0], null, 2),
            },
          ],
        };
      },
    },

    // Create folder
    wrike_create_folder: {
      name: 'wrike_create_folder',
      description: 'Create a new folder',
      inputSchema: {
        type: 'object',
        properties: {
          parentFolderId: { type: 'string', description: 'Parent folder ID (required)' },
          title: { type: 'string', description: 'Folder title (required)' },
          description: { type: 'string', description: 'Folder description' },
          shareds: { type: 'array', items: { type: 'string' }, description: 'Shared user IDs' },
        },
        required: ['parentFolderId', 'title'],
      },
      handler: async (params: { parentFolderId: string; title: string; [key: string]: unknown }) => {
        const body: CreateFolderRequest = {
          title: params.title,
        };
        
        if (params.description) body.description = params.description as string;
        if (params.shareds) body.shareds = params.shareds as string[];
        
        const response = await client.post<WrikeFolder>(`/folders/${params.parentFolderId}/folders`, body);
        
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(response.data[0], null, 2),
            },
          ],
        };
      },
    },

    // Create project
    wrike_create_project: {
      name: 'wrike_create_project',
      description: 'Create a new project (folder with project attributes)',
      inputSchema: {
        type: 'object',
        properties: {
          parentFolderId: { type: 'string', description: 'Parent folder ID (required)' },
          title: { type: 'string', description: 'Project title (required)' },
          description: { type: 'string', description: 'Project description' },
          startDate: { type: 'string', description: 'Project start date (YYYY-MM-DD)' },
          endDate: { type: 'string', description: 'Project end date (YYYY-MM-DD)' },
          status: { 
            type: 'string', 
            enum: ['Green', 'Yellow', 'Red', 'Completed', 'OnHold', 'Cancelled'],
            description: 'Project status' 
          },
          ownerIds: { type: 'array', items: { type: 'string' }, description: 'Project owner user IDs' },
          contractType: { type: 'string', enum: ['Billable', 'NonBillable'], description: 'Contract type' },
        },
        required: ['parentFolderId', 'title'],
      },
      handler: async (params: { parentFolderId: string; title: string; [key: string]: unknown }) => {
        const body: CreateFolderRequest = {
          title: params.title,
          project: {},
        };
        
        if (params.description) body.description = params.description as string;
        
        if (body.project) {
          if (params.startDate) body.project.startDate = params.startDate as string;
          if (params.endDate) body.project.endDate = params.endDate as string;
          if (params.status) body.project.status = params.status as 'Green' | 'Yellow' | 'Red' | 'Completed' | 'OnHold' | 'Cancelled';
          if (params.ownerIds) body.project.ownerIds = params.ownerIds as string[];
          if (params.contractType) body.project.contractType = params.contractType as 'Billable' | 'NonBillable';
        }
        
        const response = await client.post<WrikeFolder>(`/folders/${params.parentFolderId}/folders`, body);
        
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(response.data[0], null, 2),
            },
          ],
        };
      },
    },

    // Update folder
    wrike_update_folder: {
      name: 'wrike_update_folder',
      description: 'Update an existing folder or project',
      inputSchema: {
        type: 'object',
        properties: {
          folderId: { type: 'string', description: 'Folder ID (required)' },
          title: { type: 'string', description: 'New folder title' },
          description: { type: 'string', description: 'New folder description' },
          addShareds: { type: 'array', items: { type: 'string' }, description: 'User IDs to add to shared' },
          removeShareds: { type: 'array', items: { type: 'string' }, description: 'User IDs to remove from shared' },
          projectStatus: { 
            type: 'string', 
            enum: ['Green', 'Yellow', 'Red', 'Completed', 'OnHold', 'Cancelled'],
            description: 'Project status (for projects only)' 
          },
          restore: { type: 'boolean', description: 'Restore from Recycle Bin' },
        },
        required: ['folderId'],
      },
      handler: async (params: { folderId: string; [key: string]: unknown }) => {
        const body: Record<string, unknown> = {};
        
        if (params.title) body.title = params.title;
        if (params.description !== undefined) body.description = params.description;
        if (params.addShareds) body.addShareds = params.addShareds;
        if (params.removeShareds) body.removeShareds = params.removeShareds;
        if (params.restore) body.restore = params.restore;
        
        if (params.projectStatus) {
          body.project = { status: params.projectStatus };
        }
        
        const response = await client.put<WrikeFolder>(`/folders/${params.folderId}`, body);
        
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(response.data[0], null, 2),
            },
          ],
        };
      },
    },

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

    // Copy folder
    wrike_copy_folder: {
      name: 'wrike_copy_folder',
      description: 'Copy a folder/project to another location',
      inputSchema: {
        type: 'object',
        properties: {
          folderId: { type: 'string', description: 'Source folder ID (required)' },
          parentFolderId: { type: 'string', description: 'Destination parent folder ID (required)' },
          title: { type: 'string', description: 'New folder title' },
          copyDescriptions: { type: 'boolean', description: 'Copy descriptions' },
          copyResponsibles: { type: 'boolean', description: 'Copy responsibles' },
          copyCustomFields: { type: 'boolean', description: 'Copy custom fields' },
          copyStatuses: { type: 'boolean', description: 'Copy statuses' },
        },
        required: ['folderId', 'parentFolderId'],
      },
      handler: async (params: { folderId: string; parentFolderId: string; [key: string]: unknown }) => {
        const body: Record<string, unknown> = {
          parent: params.parentFolderId,
        };
        
        if (params.title) body.title = params.title;
        if (params.copyDescriptions !== undefined) body.copyDescriptions = params.copyDescriptions;
        if (params.copyResponsibles !== undefined) body.copyResponsibles = params.copyResponsibles;
        if (params.copyCustomFields !== undefined) body.copyCustomFields = params.copyCustomFields;
        if (params.copyStatuses !== undefined) body.copyStatuses = params.copyStatuses;
        
        const response = await client.post<WrikeFolder>(`/copy_folder/${params.folderId}`, body);
        
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(response.data[0], null, 2),
            },
          ],
        };
      },
    },

    // Get folder tree
    wrike_get_folder_tree: {
      name: 'wrike_get_folder_tree',
      description: 'Get the folder tree structure starting from a folder',
      inputSchema: {
        type: 'object',
        properties: {
          folderId: { type: 'string', description: 'Starting folder ID' },
          project: { type: 'boolean', description: 'Only include projects' },
        },
      },
      handler: async (params: { folderId?: string; project?: boolean }) => {
        const endpoint = params.folderId 
          ? `/folders/${params.folderId}` 
          : '/folders';
        
        const response = await client.get<WrikeFolder>(endpoint, {
          descendants: true,
          project: params.project,
        });
        
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(response.data, null, 2),
            },
          ],
        };
      },
    },
  };
}
