import { Logger, Module } from "@nestjs/common";
import { DiscordService } from "./discord/discord.service";
import { MatrixService } from "./matrix/matrix.service";
import { MatrixRoomService } from "./matrix/matrix-room.service";
import { MatrixStreamingService } from "./matrix/matrix-streaming.service";
import { CommandParserService } from "./parser/command-parser.service";
import { StitcherModule } from "../stitcher/stitcher.module";
import { ChatProxyModule } from "../chat-proxy/chat-proxy.module";
import { PrismaModule } from "../prisma/prisma.module";
import { CHAT_PROVIDERS } from "./bridge.constants";
import type { IChatProvider } from "./interfaces";

const logger = new Logger("BridgeModule");

/**
 * Bridge Module - Chat platform integrations
 *
 * Provides integration with chat platforms (Discord, Matrix, etc.)
 * for controlling Mosaic Stack via chat commands.
 *
 * Both services are always registered as providers, but the CHAT_PROVIDERS
 * injection token only includes bridges whose environment variables are set:
 * - Discord: included when DISCORD_BOT_TOKEN is set
 * - Matrix: included when MATRIX_ACCESS_TOKEN is set
 *
 * Both bridges can run simultaneously, and no error occurs if neither is configured.
 * Consumers should inject CHAT_PROVIDERS for bridge-agnostic access to all active providers.
 *
 * CommandParserService provides shared, platform-agnostic command parsing.
 * MatrixRoomService handles workspace-to-Matrix-room mapping.
 */
@Module({
  imports: [StitcherModule, ChatProxyModule, PrismaModule],
  providers: [
    CommandParserService,
    MatrixRoomService,
    MatrixStreamingService,
    DiscordService,
    MatrixService,
    {
      provide: CHAT_PROVIDERS,
      useFactory: (discord: DiscordService, matrix: MatrixService): IChatProvider[] => {
        const providers: IChatProvider[] = [];

        if (process.env.DISCORD_BOT_TOKEN) {
          providers.push(discord);
          logger.log("Discord bridge enabled (DISCORD_BOT_TOKEN detected)");
        }

        if (process.env.MATRIX_ACCESS_TOKEN) {
          const missingVars = [
            "MATRIX_HOMESERVER_URL",
            "MATRIX_BOT_USER_ID",
            "MATRIX_WORKSPACE_ID",
          ].filter((v) => !process.env[v]);
          if (missingVars.length > 0) {
            logger.warn(
              `Matrix bridge enabled but missing: ${missingVars.join(", ")}. connect() will fail.`
            );
          }
          providers.push(matrix);
          logger.log("Matrix bridge enabled (MATRIX_ACCESS_TOKEN detected)");
        }

        if (providers.length === 0) {
          logger.warn("No chat bridges configured. Set DISCORD_BOT_TOKEN or MATRIX_ACCESS_TOKEN.");
        }

        return providers;
      },
      inject: [DiscordService, MatrixService],
    },
  ],
  exports: [
    DiscordService,
    MatrixService,
    MatrixRoomService,
    MatrixStreamingService,
    CommandParserService,
    CHAT_PROVIDERS,
  ],
})
export class BridgeModule {}
