import { forwardRef, Module } from '@nestjs/common';
import { CqrsModule } from '@nestjs/cqrs';
import { ListingsModule } from '@modules/listings';
import { ProjectsModule } from '@modules/projects';
import { GenerateReportHandler } from './application/commands/generate-report/generate-report.handler';
import { TrackEventHandler } from './application/commands/track-event/track-event.handler';
import { UpdateMarketIndexHandler } from './application/commands/update-market-index/update-market-index.handler';
import { ListingCreatedModerationHandler } from './application/event-handlers/listing-created-moderation.handler';
import { BatchValuationHandler } from './application/queries/batch-valuation/batch-valuation.handler';
import { IndustrialValuationHandler } from './application/queries/industrial-valuation/industrial-valuation.handler';
import { GetDistrictStatsHandler } from './application/queries/get-district-stats/get-district-stats.handler';
import { GetHeatmapHandler } from './application/queries/get-heatmap/get-heatmap.handler';
import { GetListingAiAdviceHandler } from './application/queries/get-listing-ai-advice/get-listing-ai-advice.handler';
import { GetListingVolumeWardHandler } from './application/queries/get-listing-volume-ward/get-listing-volume-ward.handler';
import { GetMarketReportHandler } from './application/queries/get-market-report/get-market-report.handler';
import { GetMarketHistoryHandler } from './application/queries/get-market-history/get-market-history.handler';
import { GetMarketSnapshotHandler } from './application/queries/get-market-snapshot/get-market-snapshot.handler';
import { GetPriceMoversHandler } from './application/queries/get-price-movers/get-price-movers.handler';
import { GetTrendingAreasHandler } from './application/queries/get-trending-areas/get-trending-areas.handler';
import { GetProjectAiAdviceHandler } from './application/queries/get-project-ai-advice/get-project-ai-advice.handler';
import { GetNearbyPOIsHandler } from './application/queries/get-nearby-pois/get-nearby-pois.handler';
import { GetNeighborhoodScoreHandler } from './application/queries/get-neighborhood-score/get-neighborhood-score.handler';
import { GetPriceTrendHandler } from './application/queries/get-price-trend/get-price-trend.handler';
import { GetValuationHandler } from './application/queries/get-valuation/get-valuation.handler';
import { PredictValuationHandler } from './application/queries/predict-valuation/predict-valuation.handler';
import { ValuationComparisonHandler } from './application/queries/valuation-comparison/valuation-comparison.handler';
import { ValuationExplanationHandler } from './application/queries/valuation-explanation/valuation-explanation.handler';
import { ValuationHistoryHandler } from './application/queries/valuation-history/valuation-history.handler';
import { MARKET_INDEX_REPOSITORY } from './domain/repositories/market-index.repository';
import { VALUATION_REPOSITORY } from './domain/repositories/valuation.repository';
import { AVM_SERVICE } from './domain/services/avm-service';
import { NEIGHBORHOOD_SCORE_SERVICE } from './domain/services/neighborhood-score.service';
import { PrismaMarketIndexRepository } from './infrastructure/repositories/prisma-market-index.repository';
import { PrismaValuationRepository } from './infrastructure/repositories/prisma-valuation.repository';
import { AI_SERVICE_CLIENT, AiServiceClient } from './infrastructure/services/ai-service.client';
import { HttpAVMService } from './infrastructure/services/http-avm.service';
import { MarketIndexCronService } from './infrastructure/services/market-index-cron.service';
import {
  HttpNeighborhoodScoreService,
  PrismaNeighborhoodScoreService,
} from './infrastructure/services/neighborhood-score.service';
import { PrismaAVMService } from './infrastructure/services/prisma-avm.service';
import { AnalyticsController } from './presentation/controllers/analytics.controller';
import { AvmController } from './presentation/controllers/avm.controller';

const CommandHandlers = [
  TrackEventHandler,
  GenerateReportHandler,
  UpdateMarketIndexHandler,
];

const QueryHandlers = [
  GetMarketReportHandler,
  GetMarketHistoryHandler,
  GetHeatmapHandler,
  GetListingVolumeWardHandler,
  GetPriceTrendHandler,
  GetDistrictStatsHandler,
  GetValuationHandler,
  PredictValuationHandler,
  BatchValuationHandler,
  ValuationHistoryHandler,
  ValuationComparisonHandler,
  ValuationExplanationHandler,
  GetNeighborhoodScoreHandler,
  GetNearbyPOIsHandler,
  IndustrialValuationHandler,
  GetListingAiAdviceHandler,
  GetProjectAiAdviceHandler,
  GetMarketSnapshotHandler,
  GetPriceMoversHandler,
  GetTrendingAreasHandler,
];

const EventHandlers = [
  ListingCreatedModerationHandler,
];

@Module({
  imports: [CqrsModule, forwardRef(() => ListingsModule), ProjectsModule],
  controllers: [AnalyticsController, AvmController],
  providers: [
    // AI service client
    { provide: AI_SERVICE_CLIENT, useClass: AiServiceClient },

    // Repositories
    { provide: MARKET_INDEX_REPOSITORY, useClass: PrismaMarketIndexRepository },
    { provide: VALUATION_REPOSITORY, useClass: PrismaValuationRepository },

    // AVM: HttpAVMService calls Python AI first, falls back to PrismaAVMService
    PrismaAVMService,
    { provide: AVM_SERVICE, useClass: HttpAVMService },

    // Neighborhood scoring: HTTP proxy → Python AI service, falls back to Prisma scoring
    PrismaNeighborhoodScoreService,
    { provide: NEIGHBORHOOD_SCORE_SERVICE, useClass: HttpNeighborhoodScoreService },

    // Cron
    MarketIndexCronService,

    // CQRS
    ...CommandHandlers,
    ...QueryHandlers,
    ...EventHandlers,
  ],
  exports: [MARKET_INDEX_REPOSITORY, VALUATION_REPOSITORY, AVM_SERVICE, AI_SERVICE_CLIENT],
})
export class AnalyticsModule {}
