import type { ChannelAdapter } from "../adapters/index.js";
import { FeishuChannel } from "../adapters/index.js";
import { WeixinChannel } from "../adapters/index.js";
import { QQChannel } from "../adapters/index.js";
import type { Gateway } from "../gateway/index.js";
import { startGatewayServer, type GatewayServer } from "../gateway/index.js";
import type { PilotConfig } from "../pilot/index.js";

export type StartPilotDeckServerOptions = {
  gateway: Gateway;
  port?: number;
  host?: string;
  staticAssetsPath?: string;
  feishu?: FeishuChannel;
  weixin?: WeixinChannel;
  qq?: QQChannel;
  /**
   * Extra channels (e.g. telegram, discord, slack) loaded via
   * `loadEnabledChannels(config.adapters)`.
   */
  channels?: ChannelAdapter[];
  /**
   * Loaded pilotdeck.yaml config — passed into channel.start() so adapters can
   * read their own section (e.g. `adapters.feishu.appId/appSecret`).
   */
  config?: PilotConfig;
};

export async function startPilotDeckServer(options: StartPilotDeckServerOptions): Promise<GatewayServer> {
  const consoleLogger = {
    info: (msg: string) => console.log(msg),
    warn: (msg: string) => console.warn(msg),
    error: (msg: string) => console.error(msg),
  };
  const baseDeps = { gateway: options.gateway, config: options.config, logger: consoleLogger };

  await options.feishu?.start(baseDeps);
  await options.weixin?.start(baseDeps);
  await options.qq?.start(baseDeps);

  if (options.channels?.length) {
    await Promise.all(
      options.channels.map((ch) =>
        ch.start(baseDeps).catch((e) => {
          console.error(`[adapters] channel ${ch.channelKey} start failed: ${e}`);
        }),
      ),
    );
  }

  return startGatewayServer({
    gateway: options.gateway,
    port: options.port,
    host: options.host,
    staticAssetsPath: options.staticAssetsPath,
    feishuWebhook: options.feishu
      ? (request, response, body) => options.feishu!.handleWebhook(request, response, body)
      : undefined,
  });
}