import { Controller, Get, Query, Post, Res, Param, Body } from '@nestjs/common';
import { AnalyticsService } from './analytics.service';
import {
  ApiBearerAuth,
  ApiTags,
  ApiParam,
  ApiQuery,
  ApiOperation,
} from '@nestjs/swagger';
import { Public } from '../auth/public.decorator';
import { Response } from 'express';

@ApiTags('analytics')
@ApiBearerAuth('access-token')
@Controller('analytics')
export class AnalyticsController {
  constructor(private readonly analyticsService: AnalyticsService) {}

  @Public()
  @Get('jobs')
  @ApiOperation({ summary: 'Get Job Analytics' })
  @ApiQuery({ name: 'dateRange', required: false, type: String })
  async getJobAnalytics(@Query('dateRange') dateRange: string = '30') {
    return this.analyticsService.getJobAnalytics(parseInt(dateRange));
  }

  @Public()
  @Get('applications')
  @ApiOperation({ summary: 'Get Application Analytics' })
  @ApiQuery({ name: 'dateRange', required: false, type: String })
  async getApplicationAnalytics(@Query('dateRange') dateRange: string = '30') {
    return this.analyticsService.getApplicationAnalytics(parseInt(dateRange));
  }

  @Public()
  @Get('companies')
  @ApiOperation({ summary: 'Get Company Analytics' })
  async getCompanyAnalytics() {
    return this.analyticsService.getCompanyAnalytics();
  }

  @Public()
  @Get('users')
  @ApiOperation({ summary: 'Get User Analytics' })
  @ApiQuery({ name: 'dateRange', required: false, type: String })
  async getUserAnalytics(@Query('dateRange') dateRange: string = '30') {
    return this.analyticsService.getUserAnalytics(parseInt(dateRange));
  }

  @Public()
  @Get('overview')
  @ApiOperation({ summary: 'Get Analytics Overview' })
  @ApiQuery({ name: 'dateRange', required: false, type: String })
  async getOverview(@Query('dateRange') dateRange: string = '30') {
    return this.analyticsService.getOverview(parseInt(dateRange));
  }

  // ═══════════════════════════════════════════════════════════════════
  // CITY-WISE JOB ANALYTICS ENDPOINTS
  // ═══════════════════════════════════════════════════════════════════

  @Public()
  @Get('cities/active-jobs')
  @ApiOperation({ summary: 'Get list of cities with active jobs' })
  @ApiQuery({
    name: 'page',
    required: false,
    type: Number,
    description: 'Page number (default: 1)',
  })
  @ApiQuery({
    name: 'limit',
    required: false,
    type: Number,
    description: 'Items per page (default: 20)',
  })
  @ApiQuery({
    name: 'search',
    required: false,
    type: String,
    description: 'Search by city name',
  })
  @ApiQuery({
    name: 'dateRange',
    required: false,
    type: Number,
    description: 'Date range in days',
  })
  @ApiQuery({
    name: 'fromDate',
    required: false,
    type: String,
    description: 'Start date for filter (YYYY-MM-DD)',
  })
  @ApiQuery({
    name: 'toDate',
    required: false,
    type: String,
    description: 'End date for filter (YYYY-MM-DD)',
  })
  async getCityWiseActiveJobs(
    @Query('page') page: string = '1',
    @Query('limit') limit: string = '20',
    @Query('search') search?: string,
    @Query('dateRange') dateRange?: string,
    @Query('fromDate') fromDate?: string,
    @Query('toDate') toDate?: string,
  ) {
    return this.analyticsService.getCityWiseActiveJobs(
      parseInt(page),
      parseInt(limit),
      search,
      dateRange ? parseInt(dateRange) : undefined,
      fromDate,
      toDate,
    );
  }

  @Public()
  @Get('cities/:cityId/jobs')
  @ApiOperation({ summary: 'Get jobs in a specific city' })
  @ApiParam({ name: 'cityId', type: Number, description: 'City ID' })
  @ApiQuery({
    name: 'page',
    required: false,
    type: Number,
    description: 'Page number (default: 1)',
  })
  @ApiQuery({
    name: 'limit',
    required: false,
    type: Number,
    description: 'Items per page (default: 20)',
  })
  @ApiQuery({
    name: 'dateRange',
    required: false,
    type: Number,
    description: 'Date range in days',
  })
  @ApiQuery({
    name: 'fromDate',
    required: false,
    type: String,
    description: 'Start date for filter (YYYY-MM-DD)',
  })
  @ApiQuery({
    name: 'toDate',
    required: false,
    type: String,
    description: 'End date for filter (YYYY-MM-DD)',
  })
  async getJobsInCity(
    @Param('cityId') cityId: string,
    @Query('page') page: string = '1',
    @Query('limit') limit: string = '20',
    @Query('dateRange') dateRange?: string,
    @Query('fromDate') fromDate?: string,
    @Query('toDate') toDate?: string,
  ) {
    return this.analyticsService.getJobsInCity(
      parseInt(cityId),
      parseInt(page),
      parseInt(limit),
      dateRange ? parseInt(dateRange) : undefined,
      fromDate,
      toDate,
    );
  }

  @Public()
  @Get('cities/without-jobs')
  @ApiOperation({ summary: 'Get list of cities without active jobs' })
  @ApiQuery({
    name: 'page',
    required: false,
    type: Number,
    description: 'Page number (default: 1)',
  })
  @ApiQuery({
    name: 'limit',
    required: false,
    type: Number,
    description: 'Items per page (default: 20)',
  })
  @ApiQuery({
    name: 'search',
    required: false,
    type: String,
    description: 'Search by city name',
  })
  async getCitiesWithoutJobs(
    @Query('page') page: string = '1',
    @Query('limit') limit: string = '20',
    @Query('search') search?: string,
  ) {
    return this.analyticsService.getCitiesWithoutJobs(
      parseInt(page),
      parseInt(limit),
      search,
    );
  }

  @Public()
  @Post('cities/export/active-jobs')
  @ApiOperation({ summary: 'Export cities with active jobs as CSV' })
  @ApiQuery({
    name: 'format',
    required: false,
    enum: ['summary', 'detailed'],
    description: 'Export format',
  })
  @ApiQuery({
    name: 'search',
    required: false,
    type: String,
    description: 'Search by city name',
  })
  @ApiQuery({
    name: 'dateRange',
    required: false,
    type: Number,
    description: 'Date range in days',
  })
  @ApiQuery({
    name: 'fromDate',
    required: false,
    type: String,
    description: 'Start date for filter (YYYY-MM-DD)',
  })
  @ApiQuery({
    name: 'toDate',
    required: false,
    type: String,
    description: 'End date for filter (YYYY-MM-DD)',
  })
  async exportCityWiseActiveJobs(
    @Query('format') format: 'summary' | 'detailed' = 'summary',
    @Query('search') search?: string,
    @Query('dateRange') dateRange?: string,
    @Query('fromDate') fromDate?: string,
    @Query('toDate') toDate?: string,
    @Body('format') bodyFormat?: 'summary' | 'detailed',
    @Body('search') bodySearch?: string,
    @Body('dateRange') bodyDateRange?: string,
    @Body('fromDate') bodyFromDate?: string,
    @Body('toDate') bodyToDate?: string,
    @Res() res?: Response,
  ) {
    try {
      const finalFormat = bodyFormat || format;
      const finalSearch = bodySearch || search;
      const finalDateRange = bodyDateRange ?? dateRange;
      const finalFromDate = bodyFromDate || fromDate;
      const finalToDate = bodyToDate || toDate;

      const csv = await this.analyticsService.exportCityWiseActiveJobsCSV(
        finalFormat,
        finalSearch,
        finalDateRange ? parseInt(finalDateRange) : undefined,
        finalFromDate,
        finalToDate,
      );

      const fileName = `city-wise-jobs-${finalFormat}-${new Date().toISOString().split('T')[0]}.csv`;

      if (res) {
        res.setHeader('Content-Type', 'text/csv');
        res.setHeader(
          'Content-Disposition',
          `attachment; filename="${fileName}"`,
        );
        res.send(csv);
      } else {
        return { csv, fileName };
      }
    } catch (error) {
      console.error('Error exporting city-wise active jobs:', error);
      throw error;
    }
  }

  @Public()
  @Post('cities/export/without-jobs')
  @ApiOperation({ summary: 'Export cities without jobs as CSV' })
  @ApiQuery({
    name: 'search',
    required: false,
    type: String,
    description: 'Search by city name',
  })
  async exportCitiesWithoutJobs(
    @Query('search') search?: string,
    @Body('search') bodySearch?: string,
    @Res() res?: Response,
  ) {
    try {
      const finalSearch = bodySearch || search;
      const csv =
        await this.analyticsService.exportCitiesWithoutJobsCSV(finalSearch);

      const fileName = `cities-without-jobs-${new Date().toISOString().split('T')[0]}.csv`;

      if (res) {
        res.setHeader('Content-Type', 'text/csv');
        res.setHeader(
          'Content-Disposition',
          `attachment; filename="${fileName}"`,
        );
        res.send(csv);
      } else {
        return { csv, fileName };
      }
    } catch (error) {
      console.error('Error exporting cities without jobs:', error);
      throw error;
    }
  }
}
