/**
 * Service discovery helpers for the Web UI dashboard.
 *
 * The gateway can surface a single "services" list so operators can see:
 * - which channel adapters are configured vs connected
 * - which automation subsystems are enabled (cron, webhooks, gmail, etc.)
 */

import type { ChannelRegistry } from '../../channels/index.js';
import type { Config } from '../../config/index.js';

export type ServiceType = 'channel' | 'automation' | 'tool';

// Channel adapters expose: disconnected|connecting|connected|error.
// For config-driven subsystems we additionally use:
// - configured: enabled in config, runtime status not tracked at this layer
// - not_configured: disabled / missing config
export type ServiceStatus =
  | 'disconnected'
  | 'connecting'
  | 'connected'
  | 'error'
  | 'configured'
  | 'not_configured';

export interface ServiceInfo {
  name: string;
  type: ServiceType;
  status: ServiceStatus;
  description: string;
  itemCount?: number;
  error?: string;
  metadata?: Record<string, unknown>;
}

/**
 * Discover all services from config and channel registry.
 *
 * Returns configured channels and detects potential services from config
 * that may not yet be registered (e.g., gcal configured but no adapter created).
 */
export function discoverServices(
  config: Config,
  channelRegistry: ChannelRegistry,
): ServiceInfo[] {
  const services: ServiceInfo[] = [];

  const registeredChannels = channelRegistry.list();

  const channelConfigs: Array<{ key: keyof Config; name: string; description: string }> = [
    { key: 'telegram', name: 'telegram', description: 'Telegram bot' },
    { key: 'discord', name: 'discord', description: 'Discord bot' },
    { key: 'slack', name: 'slack', description: 'Slack app' },
    { key: 'whatsapp', name: 'whatsapp', description: 'WhatsApp gateway' },
    { key: 'matrix', name: 'matrix', description: 'Matrix bot' },
  ];

  for (const { key, name, description } of channelConfigs) {
    const configured = Boolean((config as unknown as Record<string, unknown>)[String(key)]);
    const registered = registeredChannels.find(c => c.name === name);

    if (!configured) {
      services.push({ name, type: 'channel', status: 'not_configured', description });
      continue;
    }

    if (registered) {
      services.push({ name, type: 'channel', status: registered.status as ServiceStatus, description });
      continue;
    }

    // Config present but adapter not registered (or gateway running without it).
    services.push({ name, type: 'channel', status: 'disconnected', description });
  }

  // Web search (tooling subsystem)
  services.push({
    name: 'web_search',
    type: 'tool',
    status: 'configured',
    description: 'Web search provider',
    metadata: {
      provider: config.web_search?.provider ?? 'brave',
      endpoint: config.web_search?.endpoint,
      max_results: config.web_search?.max_results,
    },
  });

  // Audio transcription (tooling subsystem)
  const audioEnabled = Boolean(config.audio?.enabled);
  services.push({
    name: 'audio_transcription',
    type: 'tool',
    status: audioEnabled ? 'configured' : 'not_configured',
    description: 'Audio transcription',
    metadata: {
      provider: config.audio?.provider?.type,
      endpoint: config.audio?.provider?.endpoint,
      model: config.audio?.provider?.model,
    },
  });

  // Docker sandboxing (tooling subsystem)
  services.push({
    name: 'sandbox',
    type: 'tool',
    status: config.sandbox?.enabled ? 'configured' : 'not_configured',
    description: 'Docker sandbox for high-risk tool execution',
    metadata: {
      enabled: config.sandbox?.enabled ?? false,
      image: config.sandbox?.image,
      network: config.sandbox?.network,
    },
  });

  const automation = config.automation;

  const automationConfigs: Array<{ enabled: boolean; name: string; description: string; itemCount?: number }> = [
    { enabled: automation.cron.length > 0, name: 'cron', description: 'Cron scheduler', itemCount: automation.cron.length },
    { enabled: automation.webhooks.length > 0, name: 'webhooks', description: 'Webhook handler', itemCount: automation.webhooks.length },
    { enabled: automation.gmail?.enabled ?? false, name: 'gmail', description: 'Gmail watcher' },
    { enabled: automation.heartbeat?.enabled ?? false, name: 'heartbeat', description: 'Heartbeat monitor' },
    { enabled: automation.gcal?.enabled ?? false, name: 'gcal', description: 'Google Calendar' },
    { enabled: automation.gdocs?.enabled ?? false, name: 'gdocs', description: 'Google Docs' },
    { enabled: automation.gdrive?.enabled ?? false, name: 'gdrive', description: 'Google Drive' },
    { enabled: automation.gtasks?.enabled ?? false, name: 'gtasks', description: 'Google Tasks' },
  ];

  for (const auto of automationConfigs) {
    services.push({
      name: auto.name,
      type: 'automation',
      status: auto.enabled ? 'configured' : 'not_configured',
      description: auto.description,
      ...(auto.itemCount !== undefined ? { itemCount: auto.itemCount } : {}),
    });
  }

  services.push({
    name: 'mcp',
    type: 'automation',
    status: config.mcp.servers.length > 0 ? 'configured' : 'not_configured',
    description: 'MCP servers',
    metadata: { serverCount: config.mcp.servers.length },
  });

  return services;
}
