/**
 * Lazy loading engine for tool packs.
 * Detects user intent and dynamically loads relevant packs.
 * Uses MCP tools/list_changed to notify clients of new tools.
 */

import type { TwilioClient } from './client.js';
import type { ToolRegistry, RegisteredTool } from './tool-registry.js';

export interface PackDefinition {
  name: string;
  description: string;
  keywords: string[];
  loadTools: (client: TwilioClient) => RegisteredTool[];
}

export class LazyLoader {
  private packs = new Map<string, PackDefinition>();
  private registry: ToolRegistry;
  private client: TwilioClient;

  constructor(registry: ToolRegistry, client: TwilioClient) {
    this.registry = registry;
    this.client = client;
  }

  /** Register a pack definition (doesn't load tools yet) */
  registerPack(pack: PackDefinition): void {
    this.packs.set(pack.name, pack);
  }

  /** Get all available pack definitions (for twilio_explore) */
  getAvailablePacks(): Array<{ name: string; description: string; loaded: boolean }> {
    return Array.from(this.packs.values()).map(p => ({
      name: p.name,
      description: p.description,
      loaded: this.registry.isPackActive(p.name),
    }));
  }

  /** Load a specific pack by name */
  loadPack(packName: string): { loaded: boolean; tools: string[] } {
    if (this.registry.isPackActive(packName)) {
      const existing = this.registry.getByPack(packName);
      return { loaded: true, tools: existing.map(t => t.name) };
    }

    const pack = this.packs.get(packName);
    if (!pack) {
      return { loaded: false, tools: [] };
    }

    const tools = pack.loadTools(this.client);
    this.registry.activatePack(packName, tools);
    return { loaded: true, tools: tools.map(t => t.name) };
  }

  /** Unload a pack */
  unloadPack(packName: string): void {
    this.registry.deactivatePack(packName);
  }

  /**
   * Detect which pack(s) should be loaded based on a user query/intent.
   * Returns pack names that match the intent.
   */
  detectPacks(query: string): string[] {
    const lower = query.toLowerCase();
    const matches: Array<{ name: string; score: number }> = [];

    for (const [name, pack] of this.packs) {
      if (this.registry.isPackActive(name)) continue; // Already loaded

      let score = 0;
      for (const keyword of pack.keywords) {
        if (lower.includes(keyword.toLowerCase())) {
          score += 1;
        }
      }
      if (score > 0) {
        matches.push({ name, score });
      }
    }

    return matches
      .sort((a, b) => b.score - a.score)
      .map(m => m.name);
  }

  /** Auto-load packs based on detected intent and return what was loaded */
  autoLoad(query: string): string[] {
    const packNames = this.detectPacks(query);
    const loaded: string[] = [];

    for (const name of packNames) {
      const result = this.loadPack(name);
      if (result.loaded) {
        loaded.push(name);
      }
    }

    return loaded;
  }
}

// Pack keyword definitions for intent detection
export const PACK_KEYWORDS: Record<string, string[]> = {
  messaging: [
    'sms', 'mms', 'text', 'message', 'campaign', 'bulk', 'template',
    'whatsapp', 'send message', 'auto-respond', 'auto respond', 'schedule',
    'broadcast', 'notification', 'alert message',
  ],
  voice: [
    'call', 'ivr', 'phone tree', 'voicemail', 'recording', 'conference',
    'dial', 'ring', 'voice', 'twiml', 'greeting', 'hold music',
    'transcribe', 'speech', 'call center',
  ],
  intelligence: [
    'lookup', 'carrier', 'fraud', 'scam', 'sim swap', 'identity',
    'validate number', 'phone intel', 'risk', 'caller name', 'line type',
    'deep scan', 'batch validate',
  ],
  verify: [
    'otp', '2fa', 'two-factor', 'verification', 'verify', 'authenticate',
    'one-time', 'passcode', 'totp', 'sna', 'silent network',
  ],
  numbers: [
    'buy number', 'purchase number', 'phone number', 'provision',
    'toll-free', 'short code', 'local number', 'area code',
    'release number', 'number inventory', 'port number',
  ],
  studio: [
    'flow', 'workflow', 'studio', 'automation', 'trigger', 'webhook',
    'drag and drop', 'builder', 'auto-responder', 'bot', 'chatbot',
    'deploy function', 'serverless',
  ],
  'contact-center': [
    'queue', 'agent', 'worker', 'taskrouter', 'routing', 'flex',
    'contact center', 'call center', 'shift', 'schedule agent',
    'supervisor', 'escalation',
  ],
  conversations: [
    'conversation', 'inbox', 'multi-channel', 'omnichannel', 'thread',
    'participant', 'chat', 'unified',
  ],
  analytics: [
    'usage', 'cost', 'billing', 'spend', 'analytics', 'report',
    'monitor', 'alert', 'error', 'health', 'anomaly', 'budget',
  ],
  serverless: [
    'function', 'deploy', 'serverless', 'asset', 'environment',
    'variable', 'hosting', 'runtime',
  ],
  compliance: [
    'compliance', 'a2p', '10dlc', 'trust', 'registration', 'brand',
    'campaign registration', 'ein', 'tcr',
  ],
};
