import type { Config } from '../config/index.js';
import type { Lifecycle } from './lifecycle.js';
import type { AudioTranscriptionConfig } from '../models/media.js';
import { HookEngine } from '../hooks/index.js';
import { ToolRegistry, ToolExecutor, ToolPolicy, allBuiltinTools, createWebSearchTools, createProcessTools, ProcessManager, BrowserManager, createBrowserTools, createAudioTranscribeTool } from '../tools/index.js';

export interface ToolsDeps {
  config: Config;
  lifecycle: Lifecycle;
  hookEngine: HookEngine;
}

export interface ToolsResult {
  toolRegistry: ToolRegistry;
  toolExecutor: ToolExecutor;
  browserManager?: BrowserManager;
}

export function initTools(deps: ToolsDeps): ToolsResult {
  const { config, lifecycle, hookEngine } = deps;

  // Initialize tool registry and register all builtin tools
  const toolRegistry = new ToolRegistry();
  for (const tool of allBuiltinTools) {
    toolRegistry.register(tool);
  }

  // Register web search tool if configured with credentials
  if (config.web_search.api_key || config.web_search.endpoint) {
    for (const tool of createWebSearchTools({
      provider: config.web_search.provider,
      apiKey: config.web_search.api_key,
      endpoint: config.web_search.endpoint,
      fallbackEndpoint: config.web_search.fallback_endpoint,
      maxResults: config.web_search.max_results,
    })) {
      toolRegistry.register(tool);
    }
  }

  // Initialize process manager and register process tools
  const processManager = new ProcessManager({
    maxConcurrent: config.process.max_concurrent,
    maxRuntimeMinutes: config.process.max_runtime_minutes,
    bufferSize: config.process.buffer_size,
  });

  for (const tool of createProcessTools(processManager)) {
    toolRegistry.register(tool);
  }

  lifecycle.onShutdown(async () => {
    await processManager.shutdown();
    console.log('Process manager stopped');
  });

  // Register audio transcription tool if configured
  if (config.audio?.enabled && config.audio.provider) {
    const audioConfig: AudioTranscriptionConfig = {
      endpoint: config.audio.provider.endpoint,
      apiKey: config.audio.provider.api_key,
      model: config.audio.provider.model,
    };
    const audioTool = createAudioTranscribeTool(audioConfig);
    toolRegistry.register(audioTool);
    console.log(`Audio transcription enabled (type=${config.audio.provider.type}, endpoint=${audioConfig.endpoint})`);
  }

  // Initialize browser manager and register browser tools (if enabled)
  const browserToolNames = ['browser.navigate', 'browser.screenshot', 'browser.click', 'browser.type', 'browser.content', 'browser.eval', 'browser.evaluate'];
  let browserManager: BrowserManager | undefined;
  if (config.browser?.enabled) {
    const manager = new BrowserManager({
      executablePath: config.browser.executable_path,
      wsEndpoint: config.browser.ws_endpoint,
      headless: config.browser.headless,
      maxPages: config.browser.max_pages,
      defaultTimeout: config.browser.default_timeout,
    });
    browserManager = manager;

    for (const tool of createBrowserTools(manager)) {
      toolRegistry.register(tool);
    }
    console.log(`Browser tools enabled (headless=${config.browser.headless})`);

    lifecycle.onShutdown(async () => {
      await manager.shutdown();
      console.log('Browser manager stopped');
    });
  } else {
    console.log('Browser tools disabled (set browser.enabled=true to register browser.* tools)');
  }

  const toolExecutor = new ToolExecutor(toolRegistry, hookEngine, {
    sensitiveMode: config.agents.sensitive_mode,
    immutableDenylist: config.agents.immutable_denylist.map((rule) => ({
      tool: rule.tool,
      argsPattern: rule.args_pattern,
      reason: rule.reason,
    })),
  });

  // Initialize tool policy from config
  const toolPolicy = new ToolPolicy(config.tools);
  toolRegistry.setPolicy(toolPolicy);

  const effectiveProfile = toolPolicy.getEffectiveProfile();
  if (effectiveProfile !== 'full') {
    console.log(`Tool policy: profile=${effectiveProfile}, deny=[${config.tools.deny.join(', ')}]`);
  }

  if (config.browser?.enabled) {
    const allNames = toolRegistry.list().map((tool) => tool.name);
    const allowed = toolPolicy.resolveAllowedNames(allNames);
    const availableBrowserTools = browserToolNames.filter((name) => allowed.has(name));
    if (availableBrowserTools.length === 0) {
      console.log('Browser tools are registered but blocked by tool policy (use tools.profile=coding/full or tools.allow).');
    } else {
      console.log(`Browser tools available after policy: ${availableBrowserTools.join(', ')}`);
    }
  }

  return { toolRegistry, toolExecutor, browserManager };
}
