import { Controller, Get, Query, UsePipes, ValidationPipe, Logger, UseGuards } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse, ApiQuery } from '@nestjs/swagger';
import { FeatureAnalyticsService } from './analytics.service';
import { FeatureAnalytics } from './entities/feature-analytics.entity';
// import { CreateFeatureAnalyticsDto } from './dto/creaate-feature-analytics.dto';
import { AnalyticsQueryDto, DateRangeDto, FeatureNameDto, MetadataFilterDto } from './dto/query-analytics.dto';
import {
  FeatureUsageCountResponse,
  FeatureUsageOverTimeResponse,
  GeoDistributionResponse,
  UserAgentDistributionResponse,
  UsageByTimeOfDayResponse,
  FeatureMetricsResponse,
  MetadataAnalysisResponse,
  HomeAnalyticsRespone,
} from './dto/analytics-response.dto';
import { JwtAuthGuard } from 'common/guards/jwt-auth.guard';
import { RolesGuard } from 'common/guards/roles.guard';
import { Roles } from 'common/decorators/role.decorator';
import { UserRole } from 'common/enum/UserRole.enum';

@ApiTags('feature-analytics')
@Controller({ path: 'feature-analytics', version: '1' })
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles(UserRole.SUPER_ADMIN)
export class FeatureAnalyticsController {
  private readonly logger = new Logger(FeatureAnalyticsController.name);
  constructor(private readonly analyticsService: FeatureAnalyticsService) {}

  //   @Post()
  //   @ApiOperation({ summary: 'Create new feature analytics entry' })
  //   @ApiResponse({ status: 201, description: 'The record has been successfully created.', type: FeatureAnalytics })
  //   @UsePipes(new ValidationPipe({ transform: true }))
  //   async createAnalytics(@Body() createDto: CreateFeatureAnalyticsDto): Promise<FeatureAnalytics> {
  //     this.logger.log('Creating new feature analytics entry', createDto);
  //     return await this.analyticsService.createAnalytics(createDto);
  //   }

  @Get()
  @ApiOperation({ summary: 'Get raw analytics data with filters' })
  @ApiResponse({ status: 200, description: 'Returns home analytics data', type: [FeatureAnalytics] })
  async getHomeAnalytics(@Query() query: AnalyticsQueryDto): Promise<HomeAnalyticsRespone> {
    const { startDate, endDate } = query;
    this.logger.log('Fetching home analytics data', { startDate, endDate });
    return await this.analyticsService.getHomeAnalytics(query);
  }

  @Get('usage-count')
  @ApiOperation({ summary: 'Get feature usage count' })
  @ApiResponse({ status: 200, description: 'Returns feature usage counts', type: [FeatureUsageCountResponse] })
  async getFeatureUsageCount(): Promise<FeatureUsageCountResponse[]> {
    this.logger.log('Fetching feature usage count');
    return await this.analyticsService.getFeatureUsageCount();
  }

  @Get('usage-over-time')
  @ApiOperation({ summary: 'Get feature usage over time' })
  @ApiResponse({ status: 200, description: 'Returns feature usage over time', type: [FeatureUsageOverTimeResponse] })
  @ApiQuery({ name: 'featureName', required: true, description: 'Name of the feature', example: 'FeatureA' })
  @ApiQuery({ name: 'startDate', required: true, description: 'Start date for the analysis', example: '2025-01-01' })
  @ApiQuery({ name: 'endDate', required: true, description: 'End date for the analysis', example: '2025-12-31' })
  @UsePipes(new ValidationPipe({ transform: true }))
  async getFeatureUsageOverTime(@Query() query: DateRangeDto & FeatureNameDto): Promise<FeatureUsageOverTimeResponse[]> {
    const { featureName, startDate, endDate } = query;
    this.logger.log('Fetching feature usage over time', { featureName, startDate, endDate });
    return await this.analyticsService.getFeatureUsageOverTime(featureName, startDate, endDate);
  }

  @Get('geo-distribution')
  @ApiOperation({ summary: 'Get geographical distribution of feature usage' })
  @ApiResponse({ status: 200, description: 'Returns geographical distribution', type: [GeoDistributionResponse] })
  @ApiQuery({ name: 'featureName', required: true, description: 'Name of the feature', example: 'get-ip-details' })
  @UsePipes(new ValidationPipe({ transform: true }))
  async getGeoDistribution(@Query() query: FeatureNameDto): Promise<GeoDistributionResponse[]> {
    this.logger.log('Fetching geographical distribution', { featureName: query.featureName });
    const geoData = await this.analyticsService.getGeoDistribution(query.featureName);
    return geoData.map(item => ({
      featureName: query.featureName,
      country: item.country,
      count: item.count,
    }));
  }

  @Get('user-agent-distribution')
  @ApiOperation({ summary: 'Get user agent distribution' })
  @ApiResponse({ status: 200, description: 'Returns user agent distribution', type: [UserAgentDistributionResponse] })
  @ApiQuery({ name: 'featureName', required: true, description: 'Name of the feature', example: 'get-ip-details' })
  @UsePipes(new ValidationPipe({ transform: true }))
  async getUserAgentDistribution(@Query() query: FeatureNameDto): Promise<UserAgentDistributionResponse[]> {
    this.logger.log('Fetching user agent distribution', { featureName: query.featureName });
    return await this.analyticsService.getUserAgentDistribution(query.featureName);
  }

  @Get('usage-by-time')
  @ApiOperation({ summary: 'Get usage by time of day' })
  @ApiResponse({ status: 200, description: 'Returns usage by hour of day', type: [UsageByTimeOfDayResponse] })
  @ApiQuery({ name: 'featureName', required: true, description: 'Name of the feature', example: 'get-ip-details' })
  async getUsageByTimeOfDay(@Query() query: FeatureNameDto): Promise<UsageByTimeOfDayResponse[]> {
    this.logger.log('Fetching usage by time of day', { featureName: query.featureName });
    return await this.analyticsService.getUsageByTimeOfDay(query.featureName);
  }

  @Get('unique-users')
  @ApiOperation({ summary: 'Get unique users count' })
  @ApiResponse({ status: 200, description: 'Returns unique users count', type: Number })
  @ApiQuery({ name: 'featureName', required: true, description: 'Name of the feature', example: 'get-ip-details' })
  @ApiQuery({ name: 'startDate', required: true, description: 'Start date for the analysis', example: '2025-01-01' })
  @ApiQuery({ name: 'endDate', required: true, description: 'End date for the analysis', example: '2025-12-31' })
  @UsePipes(new ValidationPipe({ transform: true }))
  async getUniqueUsersCount(@Query() query: DateRangeDto & FeatureNameDto): Promise<{
    totalUsers: number;
  }> {
    const { featureName, startDate, endDate } = query;
    this.logger.log('Fetching unique users count', { featureName, startDate, endDate });
    return await this.analyticsService.getUniqueUsersCount(featureName, startDate, endDate);
  }

  @Get('feature-metrics')
  @ApiOperation({ summary: 'Get feature metrics within date range' })
  @ApiResponse({ status: 200, description: 'Returns feature metrics', type: [FeatureMetricsResponse] })
  @ApiQuery({ name: 'startDate', required: true, description: 'Start date for the analysis', example: '2025-01-01' })
  @ApiQuery({ name: 'endDate', required: true, description: 'End date for the analysis', example: '2025-12-31' })
  @UsePipes(new ValidationPipe({ transform: true }))
  async getFeatureMetrics(@Query() query: DateRangeDto): Promise<FeatureMetricsResponse[]> {
    this.logger.log('Fetching feature metrics', query);
    const { startDate, endDate } = query;
    this.logger.log('Fetching feature metrics', { startDate, endDate });
    return await this.analyticsService.getFeatureMetrics(startDate, endDate);
  }

  @Get('metadata-analysis')
  @ApiOperation({ summary: 'Get metadata analysis for a feature' })
  @ApiResponse({ status: 200, description: 'Returns metadata analysis', type: [MetadataAnalysisResponse] })
  @ApiQuery({ name: 'featureName', required: true, description: 'Name of the feature', example: 'get-ip-details' })
  @ApiQuery({ name: 'metadataKey', required: true, description: 'Name of the metadata key', example: 'method' })
  @UsePipes(new ValidationPipe({ transform: true }))
  async getMetadataAnalysis(@Query() query: MetadataFilterDto): Promise<MetadataAnalysisResponse[]> {
    const { featureName, metadataKey } = query;
    this.logger.log('Fetching metadata analysis', { featureName, metadataKey });
    return await this.analyticsService.getMetadataAnalysis(featureName, metadataKey);
  }
}
