import type { Config } from '../config/index.js';
import type { HookEngine } from '../hooks/index.js';
import { ChannelRegistry, TelegramAdapter, WebChatAdapter, DiscordAdapter, SlackAdapter, WhatsAppAdapter, MatrixAdapter, PairingManager } from '../channels/index.js';
import { CronScheduler, WebhookHandler, GmailWatcher } from '../automation/index.js';
import type { GatewayServer } from '../gateway/index.js';

export interface ChannelsDeps {
  config: Config;
  channelRegistry: ChannelRegistry;
  hookEngine: HookEngine;
  pairingManager?: PairingManager;
  gateway: GatewayServer;
}

export interface ChannelsResult {
  cronScheduler?: CronScheduler;
  webhookHandler?: WebhookHandler;
  gmailWatcher?: GmailWatcher;
}

export function registerChannels(deps: ChannelsDeps): ChannelsResult {
  const { config, channelRegistry, hookEngine, pairingManager, gateway } = deps;

  // Register Telegram adapter (if configured)
  if (config.telegram) {
    const telegramAdapter = new TelegramAdapter({
      botToken: config.telegram.bot_token,
      allowedChatIds: config.telegram.allowed_chat_ids,
      requireMention: config.telegram.require_mention,
      hookEngine,
      pairingManager,
    });
    channelRegistry.register(telegramAdapter);
  }

  // Register Discord adapter (if configured)
  if (config.discord) {
    const discordAdapter = new DiscordAdapter({
      botToken: config.discord.bot_token,
      allowedGuildIds: config.discord.allowed_guild_ids.length > 0 ? config.discord.allowed_guild_ids : undefined,
      allowedChannelIds: config.discord.allowed_channel_ids.length > 0 ? config.discord.allowed_channel_ids : undefined,
      requireMention: config.discord.require_mention,
      pairingManager,
    });
    channelRegistry.register(discordAdapter);
  }

  // Register Slack adapter (if configured)
  if (config.slack) {
    const slackAdapter = new SlackAdapter({
      botToken: config.slack.bot_token,
      appToken: config.slack.app_token,
      signingSecret: config.slack.signing_secret,
      allowedChannelIds: config.slack.allowed_channel_ids.length > 0 ? config.slack.allowed_channel_ids : undefined,
      requireMention: config.slack.require_mention,
      pairingManager,
    });
    channelRegistry.register(slackAdapter);
  }

  // Register WhatsApp adapter (if configured)
  if (config.whatsapp) {
    const whatsappAdapter = new WhatsAppAdapter({
      allowedNumbers: config.whatsapp.allowed_numbers.length > 0 ? config.whatsapp.allowed_numbers : undefined,
      allowedGroupIds: config.whatsapp.allowed_group_ids.length > 0 ? config.whatsapp.allowed_group_ids : undefined,
      requireMention: config.whatsapp.require_mention,
      dataDir: config.whatsapp.data_dir,
      pairingManager,
    });
    channelRegistry.register(whatsappAdapter);
  }

  // Register Matrix adapter (if configured)
  if (config.matrix) {
    const matrixAdapter = new MatrixAdapter({
      homeserverUrl: config.matrix.homeserver_url,
      accessToken: config.matrix.access_token,
      allowedRoomIds: config.matrix.allowed_room_ids.length > 0 ? config.matrix.allowed_room_ids : undefined,
      requireMention: config.matrix.require_mention,
      syncTimeoutMs: config.matrix.sync_timeout_ms,
      displayName: config.matrix.display_name,
      pairingManager,
    });
    channelRegistry.register(matrixAdapter);
  }

  // Register WebChat adapter (wraps the gateway)
  const webChatAdapter = new WebChatAdapter({ gateway });
  channelRegistry.register(webChatAdapter);

  // Register cron scheduler adapter (if any cron jobs configured)
  let cronScheduler: CronScheduler | undefined;
  if (config.automation.cron.length > 0) {
    cronScheduler = new CronScheduler(config.automation.cron, channelRegistry);
    channelRegistry.register(cronScheduler);
    console.log(`Registered ${config.automation.cron.length} cron job(s)`);
  }

  // Register webhook handler adapter (if any webhooks configured)
  let webhookHandler: WebhookHandler | undefined;
  if (config.automation.webhooks.length > 0) {
    webhookHandler = new WebhookHandler(config.automation.webhooks, channelRegistry);
    channelRegistry.register(webhookHandler);
    gateway.setWebhookHandler(webhookHandler);
    console.log(`Registered ${config.automation.webhooks.length} webhook(s)`);
  }

  // Register Gmail watcher adapter (if configured and enabled)
  let gmailWatcher: GmailWatcher | undefined;
  if (config.automation.gmail?.enabled) {
    gmailWatcher = new GmailWatcher(config.automation.gmail, channelRegistry);
    channelRegistry.register(gmailWatcher);
    gateway.setGmailHandler(gmailWatcher);
    console.log('Registered Gmail watcher');
  }

  return { cronScheduler, webhookHandler, gmailWatcher };
}
