import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ConfigModule } from '@nestjs/config';

// Domain Services
import { CsvRateSearchService } from '@domain/services/csv-rate-search.service';

// Infrastructure Adapters
import { CsvRateLoaderAdapter } from './csv-rate-loader.adapter';
import { CsvConverterService } from './csv-converter.service';
import { TypeOrmCsvRateConfigRepository } from '@infrastructure/persistence/typeorm/repositories/typeorm-csv-rate-config.repository';
import { StorageModule } from '@infrastructure/storage/storage.module';

// Application Layer
import { CsvRateMapper } from '@application/mappers/csv-rate.mapper';
import { CsvRatesAdminController } from '@application/controllers/admin/csv-rates.controller';

// ORM Entities
import { CsvRateConfigOrmEntity } from '@infrastructure/persistence/typeorm/entities/csv-rate-config.orm-entity';

/**
 * CSV Rate Module
 *
 * Module for CSV-based rate search system
 * Registers all providers, repositories, and controllers
 *
 * Features:
 * - CSV file loading and parsing
 * - Rate search with advanced filters
 * - Admin CSV upload (ADMIN role only)
 * - Configuration management
 */
@Module({
  imports: [
    // TypeORM entities
    TypeOrmModule.forFeature([CsvRateConfigOrmEntity]),
    // Storage for MinIO/S3 support
    StorageModule,
    // Config for S3 configuration
    ConfigModule,
  ],
  providers: [
    // Infrastructure Adapters (must be before services that depend on them)
    CsvRateLoaderAdapter,
    CsvConverterService,
    TypeOrmCsvRateConfigRepository,

    // Domain Services (with factory to inject dependencies)
    {
      provide: CsvRateSearchService,
      useFactory: (
        csvRateLoader: CsvRateLoaderAdapter,
        configRepository: TypeOrmCsvRateConfigRepository
      ) => {
        // Create adapter that maps ORM entity to domain interface
        const configRepositoryAdapter = {
          async findActiveConfigs() {
            const configs = await configRepository.findActiveConfigs();
            // Map ORM entities to domain interface (null -> undefined)
            return configs.map(config => ({
              companyName: config.companyName,
              csvFilePath: config.csvFilePath,
              metadata: config.metadata === null ? undefined : config.metadata,
            }));
          },
        };
        return new CsvRateSearchService(csvRateLoader, configRepositoryAdapter);
      },
      inject: [CsvRateLoaderAdapter, TypeOrmCsvRateConfigRepository],
    },

    // Application Mappers
    CsvRateMapper,
  ],
  controllers: [
    // Admin Controllers
    CsvRatesAdminController,
  ],
  exports: [
    // Export services for use in other modules
    CsvRateSearchService,
    CsvRateLoaderAdapter,
    TypeOrmCsvRateConfigRepository,
    CsvRateMapper,
  ],
})
export class CsvRateModule {}
