import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { CallToolRequestSchema } from '@modelcontextprotocol/sdk/types.js';
import { ConfigManager } from '../../config/config-manager.js';
import { IssueTracker } from './issue-tracker.js';

let configManager: ConfigManager;
let issueTracker: IssueTracker;

export async function setupIssueTrackingTools(server: Server, config?: ConfigManager) {
  configManager = config || new ConfigManager();
  issueTracker = new IssueTracker(configManager);
  await issueTracker.init();

  server.setRequestHandler(CallToolRequestSchema, async (request) => {
    const { name, arguments: args } = request.params;

    if (!args) {
      throw new Error('No arguments provided');
    }

    switch (name) {
      case 'create_issue': {
        const {
          type,
          title,
          description,
          priority = 'medium',
          createdBy = 'user',
          labels,
          affectedModules,
          assignedTo
        } = args as any;

        try {
          const issue = await issueTracker.createIssue({
            type,
            title,
            description,
            priority,
            createdBy,
            labels,
            affectedModules,
            assignedTo
          });

          return {
            content: [
              {
                type: 'text',
                text: `✅ Issue created successfully!

🎫 **Issue #${issue.id}**
📋 **Title**: ${issue.title}
🏷️ **Type**: ${issue.type}
🎯 **Priority**: ${issue.priority}
👤 **Created by**: ${issue.createdBy}
${issue.assignedTo ? `👥 **Assigned to**: ${issue.assignedTo}` : ''}

📝 **Description**:
${issue.description}

${issue.labels.length > 0 ? `🏷️ **Labels**: ${issue.labels.join(', ')}` : ''}
${issue.affectedModules.length > 0 ? `📦 **Modules**: ${issue.affectedModules.join(', ')}` : ''}

💡 Track this issue with:
\`get_issue issueId="${issue.id}"\``
              }
            ],
            structured: {
              issue,
              created: true
            }
          };
        } catch (error) {
          return {
            content: [
              {
                type: 'text',
                text: `❌ Failed to create issue: ${(error as Error).message}`
              }
            ]
          };
        }
      }

      case 'update_issue': {
        const { issueId, ...updates } = args as any;

        try {
          const issue = await issueTracker.updateIssue(issueId, updates);

          return {
            content: [
              {
                type: 'text',
                text: `✅ Issue updated!

🎫 **Issue #${issue.id}**
📋 **Status**: ${issue.status}
🎯 **Priority**: ${issue.priority}
🕐 **Updated**: ${new Date(issue.updatedAt).toLocaleString()}

${updates.resolution ? `✅ **Resolution**: ${updates.resolution}` : ''}`
              }
            ],
            structured: {
              issue,
              updated: true
            }
          };
        } catch (error) {
          return {
            content: [
              {
                type: 'text',
                text: `❌ Failed to update issue: ${(error as Error).message}`
              }
            ]
          };
        }
      }

      case 'search_issues': {
        const filter = args as any;

        try {
          const issues = await issueTracker.searchIssues(filter);

          if (issues.length === 0) {
            return {
              content: [
                {
                  type: 'text',
                  text: '📭 No issues found matching your criteria.'
                }
              ]
            };
          }

          const groupedByStatus = issues.reduce((acc, issue) => {
            if (!acc[issue.status]) acc[issue.status] = [];
            acc[issue.status].push(issue);
            return acc;
          }, {} as Record<string, typeof issues>);

          return {
            content: [
              {
                type: 'text',
                text: `📋 Found ${issues.length} issue(s)

${Object.entries(groupedByStatus).map(([status, statusIssues]) => `
## ${status.toUpperCase()} (${statusIssues.length})
${statusIssues.map(issue => 
  `- [${issue.priority}] **${issue.title}** (#${issue.id})
  ${issue.type} | ${issue.assignedTo ? `Assigned: ${issue.assignedTo}` : 'Unassigned'}${issue.labels.length > 0 ? ` | ${issue.labels.join(', ')}` : ''}`
).join('\n')}`).join('\n')}

💡 View details with: \`get_issue issueId="<id>"\``
              }
            ],
            structured: {
              issues,
              count: issues.length
            }
          };
        } catch (error) {
          return {
            content: [
              {
                type: 'text',
                text: `❌ Failed to search issues: ${(error as Error).message}`
              }
            ]
          };
        }
      }

      case 'add_comment': {
        const { issueId, content, author = 'user' } = args as any;

        try {
          const comment = await issueTracker.addComment(issueId, {
            author,
            content
          });

          return {
            content: [
              {
                type: 'text',
                text: `💬 Comment added to issue #${issueId}

👤 **${comment.author}** at ${new Date(comment.createdAt).toLocaleString()}:
${comment.content}`
              }
            ],
            structured: {
              comment,
              added: true
            }
          };
        } catch (error) {
          return {
            content: [
              {
                type: 'text',
                text: `❌ Failed to add comment: ${(error as Error).message}`
              }
            ]
          };
        }
      }

      case 'issue_stats': {
        const filter = args as any;

        try {
          const stats = await issueTracker.getIssueStats(filter);

          return {
            content: [
              {
                type: 'text',
                text: `📊 Issue Statistics

**Total Issues**: ${stats.total}

📈 **By Type**:
${Object.entries(stats.byType).map(([type, count]) => 
  `- ${type}: ${count}`
).join('\n')}

📋 **By Status**:
${Object.entries(stats.byStatus).map(([status, count]) => 
  `- ${status}: ${count}`
).join('\n')}

🎯 **By Priority**:
${Object.entries(stats.byPriority).map(([priority, count]) => 
  `- ${priority}: ${count}`
).join('\n')}

⏱️ **Average Resolution Time**: ${stats.averageResolutionTime > 0 
  ? `${Math.round(stats.averageResolutionTime / (1000 * 60 * 60 * 24))} days`
  : 'N/A'}

${stats.oldestOpenIssue 
  ? `📅 **Oldest Open Issue**: #${stats.oldestOpenIssue.id} (${Math.round((Date.now() - new Date(stats.oldestOpenIssue.createdAt).getTime()) / (1000 * 60 * 60 * 24))} days old)`
  : ''}

${stats.mostActiveModule 
  ? `📦 **Most Active Module**: ${stats.mostActiveModule}`
  : ''}`
              }
            ],
            structured: {
              stats,
              generated: true
            }
          };
        } catch (error) {
          return {
            content: [
              {
                type: 'text',
                text: `❌ Failed to get stats: ${(error as Error).message}`
              }
            ]
          };
        }
      }

      default:
        return null as any;
    }
  });

  return {
    tools: [
      {
        name: 'create_issue',
        description: 'Create a new issue (bug report or feature request)',
        inputSchema: {
          type: 'object',
          properties: {
            type: {
              type: 'string',
              enum: ['bug', 'feature', 'enhancement', 'documentation', 'question'],
              description: 'Type of issue'
            },
            title: {
              type: 'string',
              description: 'Brief title for the issue'
            },
            description: {
              type: 'string',
              description: 'Detailed description of the issue'
            },
            priority: {
              type: 'string',
              enum: ['critical', 'high', 'medium', 'low'],
              default: 'medium',
              description: 'Priority level'
            },
            createdBy: {
              type: 'string',
              default: 'user',
              description: 'Who is creating this issue'
            },
            labels: {
              type: 'array',
              items: { type: 'string' },
              description: 'Labels to categorize the issue'
            },
            affectedModules: {
              type: 'array',
              items: { type: 'string' },
              description: 'Modules affected by this issue'
            },
            assignedTo: {
              type: 'string',
              description: 'Assign to someone'
            }
          },
          required: ['type', 'title', 'description']
        }
      },
      {
        name: 'update_issue',
        description: 'Update an existing issue',
        inputSchema: {
          type: 'object',
          properties: {
            issueId: {
              type: 'string',
              description: 'ID of the issue to update'
            },
            status: {
              type: 'string',
              enum: ['open', 'in-progress', 'resolved', 'closed', 'wont-fix'],
              description: 'New status'
            },
            priority: {
              type: 'string',
              enum: ['critical', 'high', 'medium', 'low'],
              description: 'New priority'
            },
            assignedTo: {
              type: 'string',
              description: 'Reassign to someone'
            },
            labels: {
              type: 'array',
              items: { type: 'string' },
              description: 'Update labels'
            },
            resolution: {
              type: 'string',
              description: 'Resolution description (for closed issues)'
            }
          },
          required: ['issueId']
        }
      },
      {
        name: 'search_issues',
        description: 'Search and filter issues',
        inputSchema: {
          type: 'object',
          properties: {
            type: {
              type: 'array',
              items: { 
                type: 'string',
                enum: ['bug', 'feature', 'enhancement', 'documentation', 'question']
              },
              description: 'Filter by issue types'
            },
            status: {
              type: 'array',
              items: { 
                type: 'string',
                enum: ['open', 'in-progress', 'resolved', 'closed', 'wont-fix']
              },
              description: 'Filter by status'
            },
            priority: {
              type: 'array',
              items: { 
                type: 'string',
                enum: ['critical', 'high', 'medium', 'low']
              },
              description: 'Filter by priority'
            },
            assignedTo: {
              type: 'string',
              description: 'Filter by assignee'
            },
            labels: {
              type: 'array',
              items: { type: 'string' },
              description: 'Filter by labels'
            },
            searchQuery: {
              type: 'string',
              description: 'Search in title, description, and comments'
            }
          },
          required: []
        }
      },
      {
        name: 'add_comment',
        description: 'Add a comment to an issue',
        inputSchema: {
          type: 'object',
          properties: {
            issueId: {
              type: 'string',
              description: 'ID of the issue'
            },
            content: {
              type: 'string',
              description: 'Comment content'
            },
            author: {
              type: 'string',
              default: 'user',
              description: 'Comment author'
            }
          },
          required: ['issueId', 'content']
        }
      },
      {
        name: 'issue_stats',
        description: 'Get issue statistics and trends',
        inputSchema: {
          type: 'object',
          properties: {
            type: {
              type: 'array',
              items: { type: 'string' },
              description: 'Filter stats by issue types'
            },
            dateRange: {
              type: 'object',
              properties: {
                start: { type: 'string' },
                end: { type: 'string' }
              },
              description: 'Date range for stats'
            }
          },
          required: []
        }
      }
    ],
    resources: []
  };
}