import { forwardRef, Module } from '@nestjs/common';
import { CqrsModule } from '@nestjs/cqrs';
import { MulterModule } from '@nestjs/platform-express';
import { AnalyticsModule } from '@modules/analytics';
import { FeatureListingThrottlerGuard } from '@modules/shared';
import { AdminFeatureListingHandler } from './application/commands/admin-feature-listing/admin-feature-listing.handler';
import { BulkUpdateListingsHandler } from './application/commands/bulk-update-listings/bulk-update-listings.handler';
import { CreateListingHandler } from './application/commands/create-listing/create-listing.handler';
import { DeleteListingHandler } from './application/commands/delete-listing/delete-listing.handler';
import { FeatureListingHandler } from './application/commands/feature-listing/feature-listing.handler';
import { ModerateListingHandler } from './application/commands/moderate-listing/moderate-listing.handler';
import { PromoteFeaturedListingHandler } from './application/commands/promote-featured-listing/promote-featured-listing.handler';
import { ReportListingHandler } from './application/commands/report-listing/report-listing.handler';
import { UpdateListingHandler } from './application/commands/update-listing/update-listing.handler';
import { UpdateListingStatusHandler } from './application/commands/update-listing-status/update-listing-status.handler';
import { UploadMediaHandler } from './application/commands/upload-media/upload-media.handler';
import { ActivateFeaturedListingHandler } from './application/event-handlers/activate-featured-listing.handler';
import { RecordPriceHistoryHandler } from './application/event-handlers/record-price-history.handler';
import { GetListingHandler } from './application/queries/get-listing/get-listing.handler';
import { GetPendingModerationHandler } from './application/queries/get-pending-moderation/get-pending-moderation.handler';
import { GetPriceHistoryHandler } from './application/queries/get-price-history/get-price-history.handler';
import { GetPropertyDuplicatesHandler } from './application/queries/get-property-duplicates/get-property-duplicates.handler';
import { GetSimilarListingsHandler } from './application/queries/get-similar-listings/get-similar-listings.handler';
import { SearchListingsHandler } from './application/queries/search-listings/search-listings.handler';
import { LISTING_REPOSITORY } from './domain/repositories/listing.repository';
import { PROPERTY_REPOSITORY } from './domain/repositories/property.repository';
import { DUPLICATE_DETECTOR } from './domain/services/duplicate-detector';
import { ModerationService } from './domain/services/moderation.service';
import { PRICE_VALIDATOR } from './domain/services/price-validator';
import { FeaturedListingExpiryCronService } from './infrastructure/cron/featured-listing-expiry-cron.service';
import { ListingExpiryCronService } from './infrastructure/cron/listing-expiry-cron.service';
import { PrismaListingRepository } from './infrastructure/repositories/prisma-listing.repository';
import { PrismaPropertyRepository } from './infrastructure/repositories/prisma-property.repository';
import { MEDIA_STORAGE_SERVICE, MinioMediaStorageService } from './infrastructure/services/media-storage.service';
import { PrismaDuplicateDetector } from './infrastructure/services/prisma-duplicate-detector';
import { PrismaPriceValidator } from './infrastructure/services/prisma-price-validator';
import { ListingsController } from './presentation/controllers/listings.controller';

const CommandHandlers = [
  CreateListingHandler,
  FeatureListingHandler,
  PromoteFeaturedListingHandler,
  AdminFeatureListingHandler,
  UpdateListingHandler,
  UpdateListingStatusHandler,
  UploadMediaHandler,
  ModerateListingHandler,
  DeleteListingHandler,
  BulkUpdateListingsHandler,
  ReportListingHandler,
];

const QueryHandlers = [
  GetListingHandler,
  SearchListingsHandler,
  GetPendingModerationHandler,
  GetPriceHistoryHandler,
  GetPropertyDuplicatesHandler,
  GetSimilarListingsHandler,
];

const EventHandlers = [
  ActivateFeaturedListingHandler,
  RecordPriceHistoryHandler,
];

@Module({
  imports: [
    CqrsModule,
    forwardRef(() => AnalyticsModule),
    MulterModule.register({
      limits: { fileSize: 100 * 1024 * 1024 }, // 100 MB — per-type limits enforced by FileValidationPipe
    }),
  ],
  controllers: [ListingsController],
  providers: [
    // Repositories
    { provide: PROPERTY_REPOSITORY, useClass: PrismaPropertyRepository },
    { provide: LISTING_REPOSITORY, useClass: PrismaListingRepository },

    // Services
    { provide: DUPLICATE_DETECTOR, useClass: PrismaDuplicateDetector },
    { provide: PRICE_VALIDATOR, useClass: PrismaPriceValidator },
    ModerationService,
    { provide: MEDIA_STORAGE_SERVICE, useClass: MinioMediaStorageService },

    // CQRS
    ...CommandHandlers,
    ...QueryHandlers,
    ...EventHandlers,

    // Cron
    FeaturedListingExpiryCronService,
    ListingExpiryCronService,

    // Guards (per-route)
    FeatureListingThrottlerGuard,
  ],
  exports: [LISTING_REPOSITORY, PROPERTY_REPOSITORY],
})
export class ListingsModule {}
