import {
  Controller,
  Get,
  Query,
  UseGuards,
} from '@nestjs/common';
import { type QueryBus } from '@nestjs/cqrs';
import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth } from '@nestjs/swagger';
import { JwtAuthGuard } from '@modules/auth/presentation/guards/jwt-auth.guard';
import { RequireQuota } from '@modules/subscriptions/presentation/decorators/require-quota.decorator';
import { QuotaGuard } from '@modules/subscriptions/presentation/guards/quota.guard';
import { type DistrictStatsDto } from '../../application/queries/get-district-stats/get-district-stats.handler';
import { GetDistrictStatsQuery } from '../../application/queries/get-district-stats/get-district-stats.query';
import { type HeatmapDto } from '../../application/queries/get-heatmap/get-heatmap.handler';
import { GetHeatmapQuery } from '../../application/queries/get-heatmap/get-heatmap.query';
import { type MarketReportDto } from '../../application/queries/get-market-report/get-market-report.handler';
import { GetMarketReportQuery } from '../../application/queries/get-market-report/get-market-report.query';
import { type PriceTrendDto } from '../../application/queries/get-price-trend/get-price-trend.handler';
import { GetPriceTrendQuery } from '../../application/queries/get-price-trend/get-price-trend.query';
import { type GetDistrictStatsDto } from '../dto/get-district-stats.dto';
import { type GetHeatmapDto } from '../dto/get-heatmap.dto';
import { type GetMarketReportDto } from '../dto/get-market-report.dto';
import { type GetPriceTrendDto } from '../dto/get-price-trend.dto';

@ApiTags('analytics')
@Controller('analytics')
export class AnalyticsController {
  constructor(
    private readonly queryBus: QueryBus,
  ) {}

  @ApiBearerAuth('JWT')
  @UseGuards(JwtAuthGuard, QuotaGuard)
  @RequireQuota('analytics_queries')
  @Get('market-report')
  @ApiOperation({ summary: 'Get market report for a city' })
  @ApiResponse({ status: 200, description: 'Market report retrieved' })
  @ApiResponse({ status: 403, description: 'Quota exceeded' })
  async getMarketReport(@Query() dto: GetMarketReportDto): Promise<MarketReportDto> {
    return this.queryBus.execute(
      new GetMarketReportQuery(dto.city, dto.period, dto.propertyType),
    );
  }

  @ApiBearerAuth('JWT')
  @UseGuards(JwtAuthGuard, QuotaGuard)
  @RequireQuota('analytics_queries')
  @Get('price-trend')
  @ApiOperation({ summary: 'Get price trend for a district' })
  @ApiResponse({ status: 200, description: 'Price trend data retrieved' })
  @ApiResponse({ status: 403, description: 'Quota exceeded' })
  async getPriceTrend(@Query() dto: GetPriceTrendDto): Promise<PriceTrendDto> {
    return this.queryBus.execute(
      new GetPriceTrendQuery(dto.district, dto.city, dto.propertyType, dto.periods),
    );
  }

  @ApiBearerAuth('JWT')
  @UseGuards(JwtAuthGuard, QuotaGuard)
  @RequireQuota('analytics_queries')
  @Get('heatmap')
  @ApiOperation({ summary: 'Get price heatmap for a city' })
  @ApiResponse({ status: 200, description: 'Heatmap data retrieved' })
  @ApiResponse({ status: 403, description: 'Quota exceeded' })
  async getHeatmap(@Query() dto: GetHeatmapDto): Promise<HeatmapDto> {
    return this.queryBus.execute(
      new GetHeatmapQuery(dto.city, dto.period),
    );
  }

  @ApiBearerAuth('JWT')
  @UseGuards(JwtAuthGuard, QuotaGuard)
  @RequireQuota('analytics_queries')
  @Get('district-stats')
  @ApiOperation({ summary: 'Get statistics by district' })
  @ApiResponse({ status: 200, description: 'District statistics retrieved' })
  @ApiResponse({ status: 403, description: 'Quota exceeded' })
  async getDistrictStats(@Query() dto: GetDistrictStatsDto): Promise<DistrictStatsDto> {
    return this.queryBus.execute(
      new GetDistrictStatsQuery(dto.city, dto.period),
    );
  }
}
