/**
 * tool-bridge.js
 * Service to execute MCP tools from the UI
 * MVP1: Auto-injects context from ContextStore, removes hardcoded defaults
 */

import contextStore from '../stores/context-store.js';

class ToolBridge {
  constructor() {
    this.apiBase = '/api';
    this.toolCache = new Map();
    this.context = null; // Deprecated - use contextStore instead
  }

  /**
   * MVP1: Get execution context from ContextStore
   * NO DEFAULTS - throws if project not selected
   * @returns {object} Context with projectId, teamId, userId
   */
  getContext() {
    const mcpContext = contextStore.getMCPContext();

    // Validate required context
    if (!mcpContext.project_id) {
      throw new Error('No project selected. Please select a project from the header.');
    }

    return {
      projectId: mcpContext.project_id,
      teamId: mcpContext.team_id,
      userId: mcpContext.user_id,
      capabilities: mcpContext.capabilities
    };
  }

  /**
   * Set execution context (DEPRECATED - use contextStore.setProject/setTeam instead)
   * @param {string} projectId - Project ID
   * @param {string} userId - User ID
   */
  setContext(projectId, userId) {
    console.warn('[ToolBridge] setContext is deprecated. Use contextStore.setProject() instead');
    contextStore.setProject(projectId);
    this.context = { projectId, userId };
  }

  /**
   * MVP1: Execute an MCP tool with auto-context injection
   * Implements interceptor pattern with standardized error handling
   * @param {string} toolName - MCP tool name (e.g., 'dss_extract_tokens')
   * @param {object} params - Tool parameters
   * @returns {Promise<any>} Tool execution result
   */
  async executeTool(toolName, params = {}) {
    console.log(`[ToolBridge] Executing tool: ${toolName}`, params);

    try {
      // Auto-inject context from ContextStore
      const context = this.getContext();

      // Wrap parameters with auto-injected context
      const payload = {
        project_id: context.projectId,
        team_id: context.teamId,
        user_id: context.userId,
        arguments: params,
        _client_timestamp: Date.now() // For debugging
      };

      const response = await fetch(`${this.apiBase}/mcp/tools/${toolName}/execute`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(payload)
      });

      // Standardized error handling
      if (!response.ok) {
        // Handle specific HTTP status codes
        if (response.status === 502) {
          throw new Error('MCP Server Offline - Please check backend connection');
        }
        if (response.status === 404) {
          throw new Error(`Tool not found: ${toolName}`);
        }

        const errorText = await response.text();
        let errorMessage;

        try {
          const errorJson = JSON.parse(errorText);
          errorMessage = errorJson.message || errorJson.detail || `Tool execution failed: ${response.statusText}`;
        } catch (e) {
          errorMessage = `Tool execution failed: ${response.status} - ${errorText}`;
        }

        throw new Error(errorMessage);
      }

      const result = await response.json();
      console.log(`[ToolBridge] Tool ${toolName} completed:`, result);

      return result;
    } catch (error) {
      console.error(`[ToolBridge] Tool ${toolName} failed:`, error);

      // Re-throw with enhanced error message if it's a context error
      if (error.message.includes('No project selected')) {
        throw new Error(`${error.message}\n\nTool: ${toolName}`);
      }

      throw error;
    }
  }

  /**
   * Get list of available MCP tools
   * @returns {Promise<Array>} Array of tool definitions
   */
  async getAvailableTools() {
    if (this.toolCache.has('all')) {
      return this.toolCache.get('all');
    }

    try {
      const response = await fetch(`${this.apiBase}/mcp/tools`);
      if (!response.ok) {
        throw new Error(`Failed to fetch tools: ${response.statusText}`);
      }

      const tools = await response.json();
      this.toolCache.set('all', tools);
      return tools;
    } catch (error) {
      console.error('[ToolBridge] Failed to fetch available tools:', error);
      return [];
    }
  }

  /**
   * Get tool definition by name
   * @param {string} toolName - MCP tool name
   * @returns {Promise<object|null>} Tool definition
   */
  async getToolDefinition(toolName) {
    const tools = await this.getAvailableTools();
    return tools.find(tool => tool.name === toolName) || null;
  }

  /**
   * Execute dss_extract_tokens tool
   */
  async extractTokens(path, sources = ['css', 'scss', 'tailwind', 'json']) {
    return this.executeTool('dss_extract_tokens', { path, sources });
  }

  /**
   * Execute dss_generate_theme tool
   */
  async generateTheme(format, tokens = null, themeName = 'default') {
    return this.executeTool('dss_generate_theme', {
      format,
      tokens,
      theme_name: themeName
    });
  }

  /**
   * Execute dss_sync_figma tool
   */
  async syncFigma(fileKey) {
    return this.executeTool('dss_sync_figma', { file_key: fileKey });
  }

  /**
   * Execute dss_resolve_token tool
   */
  async resolveToken(manifestPath, tokenPath, forceRefresh = false) {
    return this.executeTool('dss_resolve_token', {
      manifest_path: manifestPath,
      token_path: tokenPath,
      force_refresh: forceRefresh
    });
  }

  /**
   * Execute dss_get_resolved_context tool
   */
  async getResolvedContext(manifestPath, debug = false, forceRefresh = false) {
    return this.executeTool('dss_get_resolved_context', {
      manifest_path: manifestPath,
      debug,
      force_refresh: forceRefresh
    });
  }

  /**
   * Execute browser_get_logs tool
   */
  async getBrowserLogs(level = 'all', limit = 100) {
    return this.executeTool('browser_get_logs', { level, limit });
  }

  /**
   * Execute browser_get_errors tool
   */
  async getBrowserErrors(limit = 50) {
    return this.executeTool('browser_get_errors', { limit });
  }

  /**
   * Execute browser_accessibility_audit tool
   */
  async runAccessibilityAudit(selector = null) {
    return this.executeTool('browser_accessibility_audit', { selector });
  }

  /**
   * Execute browser_performance tool
   */
  async getPerformanceMetrics() {
    return this.executeTool('browser_performance');
  }

  /**
   * Execute devtools_screenshot tool
   */
  async takeScreenshot(fullPage = false, selector = null) {
    return this.executeTool('devtools_screenshot', { full_page: fullPage, selector });
  }

  /**
   * Execute devtools_query_dom tool
   */
  async queryDOM(selector) {
    return this.executeTool('devtools_query_dom', { selector });
  }

  /**
   * Execute devtools_network_requests tool
   */
  async getNetworkRequests(filterUrl = null, limit = 50) {
    return this.executeTool('devtools_network_requests', {
      filter_url: filterUrl,
      limit
    });
  }

  /**
   * Execute dss_audit_components tool
   */
  async auditComponents(path) {
    return this.executeTool('dss_audit_components', { path });
  }

  /**
   * Execute dss_find_quick_wins tool
   */
  async findQuickWins(path) {
    return this.executeTool('dss_find_quick_wins', { path });
  }

  /**
   * Execute dss_get_status tool
   */
  async getDSSStatus(format = 'json') {
    return this.executeTool('dss_get_status', { format });
  }

  /**
   * Execute dss_list_themes tool
   */
  async listThemes() {
    return this.executeTool('dss_list_themes');
  }

  /**
   * Execute browser_dom_snapshot tool
   */
  async getDOMSnapshot() {
    return this.executeTool('browser_dom_snapshot');
  }

  /**
   * Execute devtools_console_logs tool
   */
  async getConsoleLogs(level = 'all', limit = 100, clear = false) {
    return this.executeTool('devtools_console_logs', { level, limit, clear });
  }

  /**
   * Get token information from Context Compiler
   */
  async getTokens(manifestPath) {
    return this.getResolvedContext(manifestPath, false, false);
  }

  /**
   * Clear browser console logs
   */
  async clearConsoleLogs() {
    return this.executeTool('devtools_console_logs', { clear: true, limit: 0 });
  }
}

// Singleton instance
const toolBridge = new ToolBridge();

export default toolBridge;
