/**
 * Enhanced Intent Analyzer
 * Analyzes user input to determine intent and select appropriate tools
 * Inspired by ReAct pattern and agent intent analysis
 */

class IntentAnalyzer {
  constructor(config = {}) {
    this.tools = config.tools || [];
    this.history = config.history || [];
    this.patterns = this.loadPatterns();
    this.context = {
      previousCommands: [],
      currentDirectory: process.cwd(),
      preferences: {}
    };
  }

  /**
   * Load command patterns for intent detection
   */
  loadPatterns() {
    return {
      // Shell command patterns
      shell: [
        /^(ls|ll|la|dir)\b/,
        /^(cd|pwd)\b/,
        /^(cat|less|more|head|tail)\b/,
        /^(echo|printf)\b/,
        /^(grep|rg|ag|ack)\b/,
        /^(find|locate)\b/,
        /^(npm|yarn|pnpm|pip|pip3|cargo|go)\b/,
        /^(git|gh)\b/,
        /^(curl|wget)\b/,
        /^(ssh|scp|rsync)\b/,
        /^(docker|podman)\b/,
        /^(node|python|python3|ruby|bash|sh|zsh)\s/,
        /^(make|cmake|ninja)\b/,
        /^(test|npm test|pytest)\b/,
        /^(build|npm build|webpack|vite)\b/
      ],

      // File operation patterns
      file: [
        /^(read|open|view|show)\s+(?:file\s+)?['"]?[\w\-./]/,
        /^(write|create|save)\s+(?:file\s+)?['"]?[\w\-./]/,
        /^(delete|remove|rm)\s+(?:file\s+)?['"]?[\w\-./]/,
        /^(copy|cp|move|mv)\s+(?:file\s+)?['"]?[\w\-./]/,
        /^(list|ls|dir)\s+(?:files?\s+)?(?:in\s+)?['"]?[\w\-./]/,
        /\.(txt|md|js|ts|py|html|css|json|yaml|yml|xml)$/,
        /^edit\s+['"]?[\w\-./]/
      ],

      // Code execution patterns
      code: [
        /^run\s+(?:code|script|python|node)\b/,
        /^execute\s+(?:code|python|javascript)\b/,
        /^eval\b/,
        /^(python|python3|node)\s+-c/,
        /^(python|python3|node)\s+\S+\.py$/
      ],

      // Web search patterns
      web: [
        /^(search|google|bing)\b/,
        /^(lookup|find)\s+(?:on\s+(?:web|google|internet))/,
        /^what\s+is\b/,
        /^how\s+to\b/,
        /^explain\b/
      ]
    };
  }

  /**
   * Register available tools
   */
  setTools(tools) {
    this.tools = tools;
    return this;
  }

  /**
   * Update context
   */
  updateContext(updates) {
    Object.assign(this.context, updates);
    return this;
  }

  /**
   * Analyze input and determine intent
   *
   * @param {string} input - User input
   * @returns {IntentResult} Analysis result
   */
  analyze(input) {
    const trimmed = input.trim();

    // Check for empty input
    if (!trimmed) {
      return {
        intent: 'unknown',
        confidence: 0,
        tool: null,
        parameters: {},
        reasoning: 'Empty input'
      };
    }

    // Analyze patterns
    const patternResult = this.analyzePatterns(trimmed);
    if (patternResult.confidence > 0.7) {
      return patternResult;
    }

    // Analyze keywords
    const keywordResult = this.analyzeKeywords(trimmed);
    if (keywordResult.confidence > 0.5) {
      return keywordResult;
    }

    // Use context/history
    const contextResult = this.analyzeContext(trimmed);
    if (contextResult.confidence > 0.4) {
      return contextResult;
    }

    // Default to shell command
    return {
      intent: 'shell',
      confidence: 0.3,
      tool: 'shell',
      parameters: { command: trimmed },
      reasoning: 'Default to shell execution'
    };
  }

  /**
   * Analyze based on known patterns
   */
  analyzePatterns(input) {
    const lower = input.toLowerCase();

    for (const [intent, patterns] of Object.entries(this.patterns)) {
      for (const pattern of patterns) {
        if (pattern.test(input)) {
          return this.buildIntentResult(intent, input, 0.9, 'Pattern match');
        }
      }
    }

    return { confidence: 0 };
  }

  /**
   * Analyze based on keywords
   */
  analyzeKeywords(input) {
    const keywords = {
      shell: ['execute', 'run', 'command', 'terminal', 'shell', 'bash'],
      file: ['file', 'folder', 'directory', 'read', 'write', 'create'],
      code: ['code', 'script', 'function', 'class'],
      web: ['search', 'find', 'google', 'lookup', 'internet', 'web']
    };

    const lower = input.toLowerCase();
    let bestMatch = { intent: null, score: 0 };

    for (const [intent, kwList] of Object.entries(keywords)) {
      const score = kwList.reduce((acc, kw) => {
        return acc + (lower.includes(kw) ? 1 : 0);
      }, 0);

      if (score > bestMatch.score) {
        bestMatch = { intent, score };
      }
    }

    if (bestMatch.score > 0) {
      const confidence = Math.min(0.6, bestMatch.score * 0.2);
      return this.buildIntentResult(bestMatch.intent, input, confidence, 'Keyword match');
    }

    return { confidence: 0 };
  }

  /**
   * Analyze based on context and history
   */
  analyzeContext(input) {
    // Check if this is a continuation
    const lastCommand = this.context.previousCommands[
      this.context.previousCommands.length - 1
    ];

    if (lastCommand) {
      // Continuation of previous command
      if (input.startsWith('&&') || input.startsWith('||') || input.startsWith('|')) {
        return {
          intent: 'shell',
          confidence: 0.8,
          tool: 'shell',
          parameters: { command: `${lastCommand.command} ${input}` },
          reasoning: 'Command continuation'
        };
      }

      // Repeat previous command
      if (input === '!!' || input === 'again') {
        return {
          intent: lastCommand.intent,
          confidence: 0.7,
          tool: lastCommand.tool,
          parameters: lastCommand.parameters,
          reasoning: 'Repeat previous command'
        };
      }

      // Reference to previous output
      if (input.includes('previous') || input.includes('last')) {
        return {
          intent: lastCommand.intent,
          confidence: 0.6,
          tool: lastCommand.tool,
          parameters: lastCommand.parameters,
          reasoning: 'Reference to previous command'
        };
      }
    }

    return { confidence: 0 };
  }

  /**
   * Build intent result based on detected intent
   */
  buildIntentResult(intent, input, confidence, reasoning) {
    const toolMap = {
      shell: 'shell',
      file: 'file',
      code: 'shell', // Code execution uses shell
      web: 'web_search' // Hypothetical web tool
    };

    const parameters = this.extractParameters(intent, input);

    return {
      intent,
      confidence,
      tool: toolMap[intent] || 'shell',
      parameters,
      reasoning
    };
  }

  /**
   * Extract parameters based on intent
   */
  extractParameters(intent, input) {
    switch (intent) {
      case 'shell':
        return { command: input };

      case 'file':
        return this.extractFileParameters(input);

      case 'code':
        return { command: input };

      case 'web':
        return { query: input.replace(/^(search|google|bing)\s+/i, '') };

      default:
        return { command: input };
    }
  }

  /**
   * Extract file operation parameters
   */
  extractFileParameters(input) {
    const lower = input.toLowerCase();

    // Detect operation
    let operation = 'read';
    if (lower.startsWith('write') || lower.startsWith('create') || lower.startsWith('save')) {
      operation = 'write';
    } else if (lower.startsWith('delete') || lower.startsWith('remove')) {
      operation = 'delete';
    } else if (lower.startsWith('copy') || lower.startsWith('cp')) {
      operation = 'copy';
    } else if (lower.startsWith('move') || lower.startsWith('mv')) {
      operation = 'move';
    } else if (lower.startsWith('list') || lower.startsWith('ls')) {
      operation = 'list';
    }

    // Extract path
    const pathMatch = input.match(/['"]?([\w\-./\\]+)['"]?/);
    const path = pathMatch ? pathMatch[1] : '';

    return { operation, path };
  }

  /**
   * Get suggestions based on context
   */
  getSuggestions(input) {
    const suggestions = [];

    // Command history suggestions
    if (input.length > 0) {
      const matching = this.context.previousCommands
        .filter(cmd => cmd.command && cmd.command.startsWith(input))
        .slice(0, 5)
        .map(cmd => cmd.command);

      suggestions.push(...matching);
    }

    // Common commands
    if (!input) {
      suggestions.push(
        'ls -la',
        'pwd',
        'git status',
        'npm install',
        'npm test'
      );
    }

    return suggestions;
  }

  /**
   * Learn from executed commands
   */
  learn(command, result) {
    this.context.previousCommands.push({
      command,
      result,
      timestamp: Date.now()
    });

    // Keep only last 100 commands
    if (this.context.previousCommands.length > 100) {
      this.context.previousCommands.shift();
    }

    return this;
  }
}

/**
 * Intent Result Structure
 */
class IntentResult {
  constructor(result) {
    this.intent = result.intent || 'unknown';
    this.confidence = result.confidence || 0;
    this.tool = result.tool || null;
    this.parameters = result.parameters || {};
    this.reasoning = result.reasoning || '';
  }

  isValid() {
    return this.confidence > 0.3 && this.tool;
  }

  toJSON() {
    return {
      intent: this.intent,
      confidence: this.confidence,
      tool: this.tool,
      parameters: this.parameters,
      reasoning: this.reasoning
    };
  }
}

module.exports = {
  IntentAnalyzer,
  IntentResult
};
