/**
 * Components Discovery MCP Tool
 *
 * This tool discovers and categorizes all available components from the main llms.txt file.
 * It supports multiple output formats: raw, parsed, and summary.
 */

import { z } from 'zod';
import { config } from '../config.js';
import { fetchGitLabFileContentSafe, GitLabError } from '../services/gitlabClient.js';

/**
 * Schema for components discovery tool parameters
 */
export const componentsDiscoverySchema = z.object({});

export type ComponentsDiscoveryParams = z.infer<typeof componentsDiscoverySchema>;

/**
 * Interface for parsed component information
 */
interface ParsedComponent {
  name: string;
  type: 'component' | 'guide' | 'documentation' | 'tutorial' | 'other';
  path: string;
}

/**
 * Interface for parsed components data
 */
interface ParsedComponentsData {
  totalComponents: number;
  componentsByType: Record<string, number>;
  components: ParsedComponent[];
}

/**
 * Parses llms.txt content and categorizes components
 */
function parseComponentsContent(content: string): ParsedComponentsData {
  const lines = content.split('\n')
    .map(line => line.trim())
    .filter(line => line && !line.startsWith('#') && !line.startsWith('//'));

  const components: ParsedComponent[] = lines.map(line => {
    const name = line.split('/').pop() || line;
    let type: ParsedComponent['type'] = 'other';

    if (line.includes('/guide') || line.startsWith('guide/')) {
      type = 'guide';
    } else if (line.includes('/docs') || line.includes('/documentation') || line.endsWith('.md')) {
      type = 'documentation';
    } else if (line.includes('/tutorial') || line.startsWith('tutorial/')) {
      type = 'tutorial';
    } else if (!line.includes('/') || line.split('/').length <= 2) {
      type = 'component';
    }

    return {
      name,
      type,
      path: line
    };
  });

  const componentsByType: Record<string, number> = {};
  components.forEach(comp => {
    componentsByType[comp.type] = (componentsByType[comp.type] || 0) + 1;
  });

  return {
    totalComponents: components.length,
    componentsByType,
    components
  };
}

/**
 * Formats content as JSON data
 */
function formatOutput(content: string, sourceUrl?: string): string {
  const source = sourceUrl || config.llmsTxtUrl || config.urls.mainLlms;
  const parsed = parseComponentsContent(content);

  // Always return JSON format
  return JSON.stringify({
    source,
    totalComponents: parsed.totalComponents,
    componentsByType: parsed.componentsByType,
    components: parsed.components
  }, null, 2);
}

/**
 * Interface for gitlab-mcp instruction
 */
interface GitLabMcpInstruction {
  action_type: 'mcp_call';
  tool_name: string;
  parameters: {
    project_id: string;
    file_path: string;
    ref: string;
  };
}

/**
 * Components Discovery MCP Tool Implementation
 */
export async function componentsDiscoveryTool(): Promise<{ content: Array<{ type: 'text'; text: string }>; isError?: boolean }> {
  try {
    // Mode 1: Direct fetch mode (when LLMS_TXT_URL is configured)
    if (config.llmsTxtUrl) {
      console.log(`Fetching components list from: ${config.llmsTxtUrl}`);

      // Fetch content from the configured URL
      const content = await fetchGitLabFileContentSafe(config.llmsTxtUrl);

      // Format the output as JSON
      const formattedOutput = formatOutput(content, config.llmsTxtUrl);

      return {
        content: [{
          type: 'text',
          text: formattedOutput
        }]
      };
    }

    // Mode 2: gitlab-mcp instruction mode (when GITLAB_PROJECT_ID and LLMS_TXT_FILE are configured)
    if (config.llmsTxtProjectId) {

      console.log(`Generating gitlab-mcp instruction for project: ${config.llmsTxtProjectId}, file: ${config.llmsTxtFile}`);

      // Generate JSON instruction for LLM to call gitlab-mcp
      const instruction: GitLabMcpInstruction = {
        action_type: 'mcp_call',
        tool_name: 'get_file_contents',
        parameters: {
          project_id: config.llmsTxtProjectId, // Already URL-encoded as per PRD
          file_path: config.llmsTxtFile,
          ref: 'main' // Default branch
        }
      };

      const instructionOutput = `# Components Discovery - GitLab MCP Instruction

To retrieve the components list, please call the gitlab-mcp server with the following instruction:

\`\`\`json
${JSON.stringify(instruction, null, 2)}
\`\`\`

**Instructions for LLM:**
1. Use the above JSON instruction to call the gitlab-mcp server
2. Call the \`get_file_contents\` tool with the provided parameters
3. The response will contain the components list (llms.txt content)

**Configuration:**
- Project ID: \`${config.llmsTxtProjectId}\`
- File Path: \`${config.llmsTxtFile}\`
- Branch: \`main\``;

      return {
        content: [{
          type: 'text',
          text: instructionOutput
        }]
      };
    }

    // Configuration error: neither mode is properly configured
    throw new Error('Configuration error: Either LLMS_TXT_URL or both GITLAB_PROJECT_ID and LLMS_TXT_FILE must be configured');

  } catch (error) {
    console.error('Components discovery failed:', error);

    let errorMessage = 'Unknown error occurred';
    let statusInfo = '';

    if (error instanceof GitLabError) {
      errorMessage = `GitLab Error: ${error.message}`;
      if (error.statusCode) {
        statusInfo = `\n**Status Code:** ${error.statusCode}`;
      }
      if (error.url) {
        statusInfo += `\n**URL:** ${error.url}`;
      }
    } else if (error instanceof Error) {
      errorMessage = `Error: ${error.message}`;
    } else {
      errorMessage = `Error: ${String(error)}`;
    }

    const errorResponse = `# Error: Components Discovery Failed

${errorMessage}${statusInfo}

**Suggestions:**
- Check your network connection
- Verify the GitLab URL is accessible: ${config.llmsTxtUrl || config.urls.mainLlms}
- Ensure you have proper authentication if the repository is private
- Check if the llms.txt file exists at the specified location

**Configuration:**
- Mode: ${config.llmsTxtUrl ? 'Direct fetch' : 'GitLab MCP instruction'}
- LLMS_TXT_URL: ${config.llmsTxtUrl || 'Not configured'}
- GITLAB_PROJECT_ID: ${config.llmsTxtProjectId || 'Not configured'}
- LLMS_TXT_FILE: ${config.llmsTxtFile || 'Not configured'}

- Authentication: ${config.auth.gitlabToken ? 'Configured' : 'Not configured'}`;

    return {
      content: [{
        type: 'text',
        text: errorResponse
      }],
      isError: true
    };
  }
}