import { ToolResult } from './types.js';

/**
 * MCP Response format expected by the SDK
 */
export interface MCPResponse {
  [key: string]: unknown;
  content: Array<{
    type: string;
    text: string;
  }>;
  structured?: any;
}

/**
 * Simplified MCP Tool Response Schema
 */
export interface MCPToolResponse<T = any> {
  status: 'success' | 'error' | 'partial';
  message: string;
  data?: T;
  metadata?: {
    operation: string;
    timestamp: string;
    dataType?: string;
    relatedTools?: string[];
  };
  error?: {
    code: string;
    category: 'validation' | 'system' | 'permission' | 'resource' | 'execution';
    details?: any;
    suggestions?: string[];
  };
  warnings?: string[];
}

/**
 * Convert our internal ToolResult format to MCP SDK format with new schema
 */
export function convertToolResultToMCP<T>(result: ToolResult<T>, operation?: string): MCPResponse {
  // Check if data already follows the new MCPToolResponse format
  if (result.success && result.data && typeof result.data === 'object' && 
      'status' in result.data && 'message' in result.data) {
    // Data is already in MCPToolResponse format
    const response = result.data as MCPToolResponse;
    return {
      content: [
        {
          type: 'text',
          text: JSON.stringify(response, null, 2)
        }
      ],
      structured: response
    };
  }

  // Convert legacy format to new schema
  const timestamp = new Date().toISOString();
  
  if (result.success) {
    const response: MCPToolResponse<T> = {
      status: 'success',
      message: formatSuccessMessage(result.data, operation),
      data: result.data,
      metadata: {
        operation: operation || 'unknown',
        timestamp,
        ...getOperationMetadata(operation, result.data)
      }
    };
    
    return {
      content: [
        {
          type: 'text',
          text: JSON.stringify(response, null, 2)
        }
      ],
      structured: response
    };
  } else {
    const response: MCPToolResponse = {
      status: 'error',
      message: result.error?.message || 'An unknown error occurred',
      error: {
        code: result.error?.code || 'UNKNOWN_ERROR',
        category: result.error?.category || 'system',
        details: result.error?.details,
        suggestions: result.error?.suggestions
      },
      metadata: {
        operation: operation || 'unknown',
        timestamp
      }
    };
    
    return {
      content: [
        {
          type: 'text',
          text: JSON.stringify(response, null, 2)
        }
      ],
      structured: response
    };
  }
}

/**
 * Format success data as a readable string
 */
function formatSuccessMessage(data: any, operation?: string): string {
  if (data === null || data === undefined) {
    return '✅ Operation completed successfully';
  }

  if (typeof data === 'string') {
    return data;
  }

  if (typeof data === 'number' || typeof data === 'boolean') {
    return String(data);
  }

  // Check if data has a message property for better formatting
  if (data && typeof data === 'object' && 'message' in data) {
    return data.message;
  }

  // For complex objects, provide a summary instead of full JSON
  if (data && typeof data === 'object') {
    const summary = formatDataSummary(data, operation);
    if (summary) {
      return summary;
    }
  }

  // For objects and arrays, pretty print as JSON
  try {
    return JSON.stringify(data, null, 2);
  } catch (error) {
    return '✅ Operation completed successfully (data available in structured field)';
  }
}

/**
 * Format complex data as a human-readable summary
 */
function formatDataSummary(data: any, operation?: string): string | null {
  // Handle list responses
  if (data.stories && Array.isArray(data.stories)) {
    const count = data.stories.length;
    const summary = data.summary;
    return `✅ Retrieved ${count} user ${count === 1 ? 'story' : 'stories'}${
      summary ? `\n\nSummary:\n${JSON.stringify(summary, null, 2)}` : ''
    }`;
  }

  if (data.sprints && Array.isArray(data.sprints)) {
    return `✅ Retrieved ${data.sprints.length} sprint(s)`;
  }

  if (data.epics && Array.isArray(data.epics)) {
    return `✅ Retrieved ${data.epics.length} epic(s)`;
  }

  if (data.boards && Array.isArray(data.boards)) {
    return `✅ Retrieved ${data.boards.length} kanban board(s)`;
  }

  if (data.tasks && Array.isArray(data.tasks)) {
    return `✅ Retrieved ${data.tasks.length} task(s)`;
  }

  // Handle single entity responses based on operation
  if (data.sprint && data.sprint.id) {
    const verb = getOperationVerb(operation);
    return `✅ ${verb} sprint "${data.sprint.name}" (ID: ${data.sprint.id})${
      data.nextSteps ? '\n\nNext steps:\n' + data.nextSteps.map((s: string) => `• ${s}`).join('\n') : ''
    }`;
  }

  if (data.story && data.story.id) {
    const verb = getOperationVerb(operation);
    return `✅ ${verb} user story "${data.story.title}" (ID: ${data.story.id})${
      data.nextSteps ? '\n\nNext steps:\n' + data.nextSteps.map((s: string) => `• ${s}`).join('\n') : ''
    }`;
  }

  if (data.epic && data.epic.id) {
    const verb = getOperationVerb(operation);
    return `✅ ${verb} epic "${data.epic.title}" (ID: ${data.epic.id})`;
  }

  // Handle board responses
  if (data.board && data.board.id) {
    const verb = getOperationVerb(operation);
    return `✅ ${verb} kanban board "${data.board.name}" (ID: ${data.board.id})`;
  }

  // Handle task responses
  if (data.task && data.task.id) {
    const verb = getOperationVerb(operation);
    return `✅ ${verb} task "${data.task.title}" (ID: ${data.task.id})`;
  }

  // Handle specific agile operations
  if (operation === 'update_story_status' && data.oldStatus && data.newStatus) {
    return `✅ Updated story status from "${data.oldStatus}" to "${data.newStatus}"${
      data.storyId ? ` (ID: ${data.storyId})` : ''
    }`;
  }
  
  if (operation === 'add_story_to_sprint' && data.message) {
    return `✅ ${data.message}`;
  }
  
  if (operation === 'assign_story' && data.storyId && data.assignee) {
    return `✅ Assigned story to ${data.assignee}${data.storyTitle ? ` - "${data.storyTitle}"` : ''}`;
  }
  
  if (operation === 'block_story' && data.blocker) {
    return `✅ Blocked story "${data.blocker.storyTitle || data.blocker.storyId}" - ${data.blocker.reason}`;
  }
  
  if (operation === 'complete_sprint' && data.sprint) {
    return `✅ Completed sprint "${data.sprint.name}" with ${data.completedStories || 0} stories done`;
  }

  // Handle generic update responses
  if (data.updated && typeof data.updated === 'object') {
    const type = data.updated.type || 'item';
    const id = data.updated.id;
    return `✅ Updated ${type}${id ? ` (ID: ${id})` : ''}`;
  }
  
  // Handle update responses with entity data
  if (data.updated === true && (data.story || data.epic || data.sprint || data.task || data.board)) {
    const entity = data.story || data.epic || data.sprint || data.task || data.board;
    const entityType = data.story ? 'story' : data.epic ? 'epic' : data.sprint ? 'sprint' : data.task ? 'task' : 'board';
    const title = entity.title || entity.name || entity.id;
    return `✅ Updated ${entityType} "${title}"${entity.id ? ` (ID: ${entity.id})` : ''}`;
  }

  // Handle deletion responses
  if (data.deleted) {
    return `✅ Deleted successfully`;
  }

  // Handle other responses with a result count
  const keys = Object.keys(data);
  if (keys.length === 1 && Array.isArray(data[keys[0]])) {
    const items = data[keys[0]];
    return `✅ Retrieved ${items.length} ${keys[0]}`;
  }

  return null;
}

/**
 * Format error information as a readable string
 */
function formatErrorMessage(error?: any): string {
  if (!error) {
    return '❌ An unknown error occurred';
  }

  const parts: string[] = [];
  
  // Add main error message
  parts.push(`❌ Error: ${error.message || 'Unknown error'}`);
  
  // Add error code if available
  if (error.code) {
    parts.push(`Code: ${error.code}`);
  }
  
  // Add category if available
  if (error.category) {
    parts.push(`Category: ${error.category}`);
  }
  
  // Add suggestions if available
  if (error.suggestions && Array.isArray(error.suggestions) && error.suggestions.length > 0) {
    parts.push('\nSuggestions:');
    error.suggestions.forEach((suggestion: string, index: number) => {
      parts.push(`${index + 1}. ${suggestion}`);
    });
  }
  
  return parts.join('\n');
}

/**
 * Create a simple MCP response with just text
 */
export function createMCPTextResponse(text: string): MCPResponse {
  return {
    content: [
      {
        type: 'text',
        text: text
      }
    ]
  };
}

/**
 * Create an MCP error response
 */
export function createMCPErrorResponse(message: string, details?: any): MCPResponse {
  return {
    content: [
      {
        type: 'text',
        text: `❌ Error: ${message}`
      }
    ],
    structured: details
  };
}

/**
 * Helper to create a standardized success response
 */
export function createMCPSuccessResponse<T>(
  message: string,
  data: T,
  metadata: {
    operation: string;
    dataType?: string;
    relatedTools?: string[];
  }
): MCPToolResponse<T> {
  return {
    status: 'success',
    message,
    data,
    metadata: {
      ...metadata,
      timestamp: new Date().toISOString()
    }
  };
}

/**
 * Helper to create a standardized error response
 */
export function createMCPErrorResponseV2(
  message: string,
  error: {
    code: string;
    category: 'validation' | 'system' | 'permission' | 'resource' | 'execution';
    details?: any;
    suggestions?: string[];
  },
  operation: string
): MCPToolResponse {
  return {
    status: 'error',
    message,
    error,
    metadata: {
      operation,
      timestamp: new Date().toISOString()
    }
  };
}

/**
 * Get appropriate verb for an operation
 */
function getOperationVerb(operation?: string): string {
  if (!operation) return 'Processed';
  
  // Check for specific operation types
  if (operation.startsWith('create_')) return 'Created';
  if (operation.startsWith('get_')) return 'Retrieved';
  if (operation.startsWith('list_')) return 'Listed';
  if (operation.startsWith('update_')) return 'Updated';
  if (operation.startsWith('delete_')) return 'Deleted';
  if (operation.startsWith('add_')) return 'Added';
  if (operation.startsWith('remove_')) return 'Removed';
  if (operation.startsWith('move_')) return 'Moved';
  if (operation.startsWith('assign_')) return 'Assigned';
  if (operation.startsWith('complete_')) return 'Completed';
  if (operation.startsWith('close_')) return 'Closed';
  if (operation.startsWith('block_')) return 'Blocked';
  if (operation.startsWith('split_')) return 'Split';
  if (operation.startsWith('link_')) return 'Linked';
  if (operation.startsWith('generate_')) return 'Generated';
  if (operation.startsWith('validate_')) return 'Validated';
  if (operation.startsWith('analyze_')) return 'Analyzed';
  
  // Default
  return 'Processed';
}

/**
 * Get operation-specific metadata based on tool name and data
 */
function getOperationMetadata(operation?: string, data?: any): { dataType?: string; relatedTools?: string[] } {
  if (!operation) return {};
  
  // Agile management tools
  if (operation.includes('sprint')) {
    if (operation === 'create_agile_sprint') {
      return {
        dataType: 'sprint',
        relatedTools: ['add_story_to_sprint', 'list_stories', 'get_sprint_stats']
      };
    }
    if (operation === 'list_agile_sprints') {
      return {
        dataType: 'sprint_list',
        relatedTools: ['get_sprint', 'create_agile_sprint', 'get_sprint_stats']
      };
    }
  }
  
  if (operation.includes('story')) {
    if (operation === 'create_user_story') {
      return {
        dataType: 'story',
        relatedTools: ['add_story_to_sprint', 'update_story_status', 'list_stories']
      };
    }
    if (operation === 'list_stories') {
      return {
        dataType: 'story_list',
        relatedTools: ['create_user_story', 'get_story', 'update_story_status']
      };
    }
  }
  
  if (operation.includes('epic')) {
    if (operation === 'create_epic') {
      return {
        dataType: 'epic',
        relatedTools: ['list_epics', 'create_user_story', 'update_epic']
      };
    }
    if (operation === 'list_epics') {
      return {
        dataType: 'epic_list',
        relatedTools: ['create_epic', 'get_epic', 'update_epic']
      };
    }
  }
  
  // Task management tools
  if (operation.includes('board')) {
    if (operation === 'create_kanban_board') {
      return {
        dataType: 'board',
        relatedTools: ['create_kanban_task', 'get_kanban_board', 'list_boards']
      };
    }
    if (operation === 'list_boards') {
      return {
        dataType: 'board_list',
        relatedTools: ['create_kanban_board', 'get_kanban_board', 'get_kanban_analytics']
      };
    }
  }
  
  if (operation.includes('task')) {
    if (operation === 'create_kanban_task') {
      return {
        dataType: 'task',
        relatedTools: ['move_kanban_task', 'update_task', 'get_tasks']
      };
    }
    if (operation === 'get_tasks' || operation === 'list_tasks') {
      return {
        dataType: 'task_list',
        relatedTools: ['create_kanban_task', 'update_task', 'move_kanban_task']
      };
    }
  }
  
  // Memory management
  if (operation.includes('memory')) {
    if (operation === 'store_memory') {
      return {
        dataType: 'memory',
        relatedTools: ['search_memories', 'get_memory', 'get_memory_stats']
      };
    }
    if (operation === 'search_memories') {
      return {
        dataType: 'memory_list',
        relatedTools: ['store_memory', 'get_memory', 'get_memory_stats']
      };
    }
  }
  
  // Business management
  if (operation.includes('business')) {
    if (operation === 'generate_business_plan') {
      return {
        dataType: 'business_plan',
        relatedTools: ['analyze_market', 'competitor_research', 'financial_projections']
      };
    }
    if (operation === 'perform_business_review') {
      return {
        dataType: 'business_review',
        relatedTools: ['track_startup_metrics', 'generate_business_plan', 'startup_assessment']
      };
    }
  }
  
  // Default metadata
  return {
    dataType: 'generic_response'
  };
}
