/**
 * SpeechModule
 *
 * NestJS module for speech-to-text (STT) and text-to-speech (TTS) services.
 * Provides a provider abstraction layer with graceful fallback for TTS tiers.
 *
 * TTS providers are created dynamically based on configuration:
 * - default: Kokoro-FastAPI (CPU, always available)
 * - premium: Chatterbox (GPU, voice cloning)
 * - fallback: Piper via OpenedAI Speech (ultra-lightweight CPU)
 *
 * Imports:
 * - ConfigModule.forFeature(speechConfig) for speech configuration
 * - AuthModule for WebSocket authentication
 * - PrismaModule for workspace membership queries
 *
 * Providers:
 * - SpeechService: High-level speech operations with provider selection
 * - SpeechGateway: WebSocket gateway for streaming transcription (Issue #397)
 * - TTS_PROVIDERS: Map<SpeechTier, ITTSProvider> populated by factory based on config
 *
 * Exports:
 * - SpeechService for use by other modules (e.g., controllers, brain)
 *
 * Issue #389, #390, #391, #397
 */

import { Module, type OnModuleInit, Logger } from "@nestjs/common";
import { ConfigModule, ConfigService } from "@nestjs/config";
import {
  speechConfig,
  validateSpeechConfig,
  isSttEnabled,
  type SpeechConfig,
} from "./speech.config";
import { SpeechService } from "./speech.service";
import { SpeechController } from "./speech.controller";
import { SpeechGateway } from "./speech.gateway";
import { STT_PROVIDER, TTS_PROVIDERS } from "./speech.constants";
import { SpeachesSttProvider } from "./providers/speaches-stt.provider";
import { createTTSProviders } from "./providers/tts-provider.factory";
import { AuthModule } from "../auth/auth.module";
import { PrismaModule } from "../prisma/prisma.module";

@Module({
  imports: [ConfigModule.forFeature(speechConfig), AuthModule, PrismaModule],
  controllers: [SpeechController],
  providers: [
    SpeechService,
    SpeechGateway,
    // STT provider: conditionally register SpeachesSttProvider when STT is enabled
    ...(isSttEnabled()
      ? [
          {
            provide: STT_PROVIDER,
            useClass: SpeachesSttProvider,
          },
        ]
      : []),
    {
      provide: TTS_PROVIDERS,
      useFactory: (configService: ConfigService) => {
        const config = configService.get<SpeechConfig>("speech");
        if (!config) {
          return new Map();
        }
        return createTTSProviders(config);
      },
      inject: [ConfigService],
    },
  ],
  exports: [SpeechService],
})
export class SpeechModule implements OnModuleInit {
  private readonly logger = new Logger(SpeechModule.name);

  onModuleInit(): void {
    // Validate configuration at startup (fail fast)
    validateSpeechConfig();
    this.logger.log("Speech module initialized");
  }
}
