import { Module } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { PrismaService } from './persistence/prisma/prisma.service';
import { SnapshotRepository } from './persistence/repositories/snapshot.repository';
import { PostgresBackupHandler } from './backup/postgres-backup.handler';
import { MpcPostgresBackupHandler } from './backup/mpc-postgres-backup.handler';
import { RedisBackupHandler } from './backup/redis-backup.handler';
import { KafkaBackupHandler } from './backup/kafka-backup.handler';
import { ZookeeperBackupHandler } from './backup/zookeeper-backup.handler';
import { MinioBackupHandler } from './backup/minio-backup.handler';
import { UploadsBackupHandler } from './backup/uploads-backup.handler';
import { MinioStorageAdapter } from './storage/minio-storage.adapter';
import { LocalStorageAdapter } from './storage/local-storage.adapter';
import { SnapshotGateway } from '@/api/gateways/snapshot.gateway';
import { BackupHandler, BACKUP_HANDLER_TOKEN } from '@/domain/interfaces/backup-handler.interface';
import { BackupTarget } from '@/domain/enums';

@Module({
  providers: [
    PrismaService,
    SnapshotRepository,
    MinioStorageAdapter,
    LocalStorageAdapter,
    SnapshotGateway,
    // 各备份 handler
    PostgresBackupHandler,
    MpcPostgresBackupHandler,
    RedisBackupHandler,
    KafkaBackupHandler,
    ZookeeperBackupHandler,
    MinioBackupHandler,
    UploadsBackupHandler,
    // 备份 handler Map 注入
    {
      provide: BACKUP_HANDLER_TOKEN,
      useFactory: (
        configService: ConfigService,
        pg: PostgresBackupHandler,
        mpcPg: MpcPostgresBackupHandler,
        redis: RedisBackupHandler,
        kafka: KafkaBackupHandler,
        zk: ZookeeperBackupHandler,
        minio: MinioBackupHandler,
        uploads: UploadsBackupHandler,
      ) => {
        const availableTargets = configService
          .get<string>('AVAILABLE_TARGETS', '')
          .split(',')
          .map((t) => t.trim())
          .filter(Boolean);

        const allHandlers = [pg, mpcPg, redis, kafka, zk, minio, uploads];
        const handlerMap = new Map<BackupTarget, BackupHandler>();

        for (const handler of allHandlers) {
          if (availableTargets.includes(handler.target as string)) {
            handlerMap.set(handler.target, handler);
          }
        }

        return handlerMap;
      },
      inject: [
        ConfigService,
        PostgresBackupHandler,
        MpcPostgresBackupHandler,
        RedisBackupHandler,
        KafkaBackupHandler,
        ZookeeperBackupHandler,
        MinioBackupHandler,
        UploadsBackupHandler,
      ],
    },
  ],
  exports: [
    PrismaService,
    SnapshotRepository,
    MinioStorageAdapter,
    LocalStorageAdapter,
    SnapshotGateway,
    BACKUP_HANDLER_TOKEN,
  ],
})
export class InfrastructureModule {}
