// alert.controller.ts
import {
  Controller,
  Get,
  Post,
  Body,
  Param,
  Query,
  UseGuards,
  Logger,
  DefaultValuePipe,
  ParseIntPipe,
  BadRequestException,
  Delete,
  Put,
  UseInterceptors,
  UploadedFile,
} from '@nestjs/common';
import { AlertService } from './alert.service';
import { CreateAlertDto } from './dto/create-alert.dto';
import { ReviewAlertDto } from './dto/review-alert.dto';
import { PublishAlertDto } from './dto/publish-alert.dto';
import { JwtAuthGuard } from 'common/guards/jwt-auth.guard';
import { Roles } from 'common/decorators/role.decorator';
import { UserRole } from 'common/enum/UserRole.enum';
import { RolesGuard } from 'common/guards/roles.guard';
import { AlertStage, AlertType, AttackType } from 'common/enum/alert.enum';
import { ApiBody, ApiConsumes, ApiOperation, ApiParam, ApiQuery, ApiResponse } from '@nestjs/swagger';
import { Permissions } from 'common/decorators/permissions.decorator';
import { AlertResponseDto, IAlertResponsePaginated } from './dto/response-alert.dto';
import { updateAlertDto } from './dto/update-alert.dto';
import { FileInterceptor } from '@nestjs/platform-express';

@Controller({ path: 'alert', version: '1' })
export class AlertController {
  private logger = new Logger(AlertController.name);
  constructor(private readonly alertService: AlertService) {}

  // get all alerts
  @Get()
  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles(UserRole.ADMIN, UserRole.SUPER_ADMIN)
  @ApiOperation({ summary: 'Get all alerts' })
  @ApiQuery({ name: 'page', required: false, default: 1 })
  @ApiQuery({ name: 'limit', required: false, default: 10 })
  @ApiResponse({ status: 200, description: 'List of all alerts', type: IAlertResponsePaginated })
  @ApiResponse({ status: 403, description: 'Forbidden - Insufficient permissions' })
  async getAllAlerts(@Query('page') page = 1, @Query('limit') limit = 10): Promise<IAlertResponsePaginated> {
    this.logger.log('Fetching all alerts...');
    return this.alertService.fetchExternalAlerts({ page, limit });
  }

  // Retrieve all gathered data
  @Get('gathered')
  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles(UserRole.ADMIN, UserRole.SUPER_ADMIN)
  @ApiOperation({ summary: 'Get gathered alerts' })
  @ApiResponse({ status: 200, description: 'List of gathered alerts', type: IAlertResponsePaginated })
  @ApiResponse({ status: 403, description: 'Forbidden - Insufficient permissions' })
  @ApiResponse({ status: 500, description: 'Internal Server Error' })
  @ApiQuery({ name: 'page', required: true, default: 1 })
  @ApiQuery({ name: 'limit', required: true, default: 10 })
  @ApiQuery({ name: 'search', required: false })
  async getGatheredAlerts(@Query('page') page = 1, @Query('limit') limit = 10, @Query('search') search?: string): Promise<IAlertResponsePaginated> {
    this.logger.log('Fetching gathered alerts...');
    return this.alertService.findAlertsByStage(AlertStage.GATHERED, { page, limit, search });
  }
  // Submit new attack data

  @Post('gathered')
  @UseGuards(JwtAuthGuard)
  @Roles(UserRole.ADMIN, UserRole.SUPER_ADMIN)
  @UseInterceptors(FileInterceptor('attachment'))
  @ApiOperation({ summary: 'Submit a new attack alert' })
  @ApiConsumes('multipart/form-data')
  @ApiBody({ type: CreateAlertDto })
  @ApiResponse({ status: 201, description: 'Alert successfully created.', type: AlertResponseDto })
  @ApiResponse({ status: 400, description: 'Bad Request' })
  @ApiResponse({ status: 403, description: 'Forbidden' })
  @ApiResponse({ status: 500, description: 'Internal Server Error' })
  async submitAlert(@Body() createAlertDto: CreateAlertDto, @UploadedFile() file: Express.Multer.File): Promise<AlertResponseDto> {
    return this.alertService.createAlert(createAlertDto, file);
  }

  // Retrieve reviewed data
  @Get('reviewed')
  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles(UserRole.ADMIN, UserRole.SUPER_ADMIN)
  @ApiOperation({ summary: 'Get alerts in the reviewed stage' })
  @ApiQuery({ name: 'page', required: true, default: 1 })
  @ApiQuery({ name: 'limit', required: true, default: 10 })
  @ApiQuery({ name: 'search', required: false })
  @ApiResponse({ status: 200, description: 'List of reviewed alerts', type: IAlertResponsePaginated })
  @ApiResponse({ status: 400, description: 'Invalid request data' })
  @ApiResponse({ status: 403, description: 'Forbidden - Insufficient permissions' })
  async getReviewedAlerts(
    @Query('page', new DefaultValuePipe(1), ParseIntPipe) page: number,
    @Query('limit', new DefaultValuePipe(10), ParseIntPipe) limit: number,
    @Query('search') search?: string,
  ): Promise<IAlertResponsePaginated> {
    if (page < 1) {
      throw new BadRequestException('Page must be at least 1');
    }
    return this.alertService.findAlertsByStage(AlertStage.REVIEWED, { page, limit, search });
  }

  // Retrieve published alerts
  @Get('published')
  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles(UserRole.ADMIN, UserRole.SUPER_ADMIN, UserRole.USER, UserRole.CLIENT)
  @ApiOperation({ summary: 'Get published alerts' })
  @ApiResponse({ status: 200, description: 'List of published alerts', type: IAlertResponsePaginated })
  @ApiResponse({ status: 403, description: 'Forbidden - Insufficient permissions' })
  @ApiResponse({ status: 500, description: 'Internal Server Error' })
  @ApiQuery({ name: 'page', required: false, description: 'Page number for pagination', example: 1 })
  @ApiQuery({ name: 'limit', required: false, description: 'Number of alerts per page', example: 10 })
  @ApiQuery({ name: 'search', required: false, description: 'Search term to filter alerts', example: 'government' })
  async getPublishedAlerts(@Query('page') page = 1, @Query('limit') limit = 10, @Query('search') search?: string): Promise<IAlertResponsePaginated> {
    return this.alertService.findAlertsByStage(AlertStage.PUBLISHED, { page, limit, search });
  }
  
  // Get alert by ID
  @Get(':id')
  @Roles(UserRole.ADMIN, UserRole.SUPER_ADMIN, UserRole.USER)
  @ApiOperation({ summary: 'Get alert by ID' })
  @ApiParam({ name: 'id', description: 'The unique identifier of the alert', example: '1' })
  @ApiResponse({ status: 200, description: 'Alert found', type: AlertResponseDto })
  @ApiResponse({ status: 404, description: 'Alert not found' })
  @UseGuards(JwtAuthGuard)
  async getAlertById(@Param('id') id: string): Promise<AlertResponseDto> {
    return this.alertService.findAlertById(id);
  }

  // Move gathered data to reviewed stage
  @Put('reviewed')
  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles(UserRole.ADMIN, UserRole.SUPER_ADMIN)
  @ApiBody({ type: ReviewAlertDto })
  @ApiOperation({ summary: 'Review an alert and mark it as verified' })
  @ApiResponse({ status: 201, description: 'Alert reviewed successfully', type: AlertResponseDto })
  @ApiResponse({ status: 400, description: 'Invalid request data' })
  @ApiResponse({ status: 403, description: 'Forbidden - Insufficient permissions' })
  async reviewAlert(@Body() reviewAlertDto: ReviewAlertDto): Promise<AlertResponseDto> {
    this.logger.log('Reviewing alert...', reviewAlertDto);
    return this.alertService.reviewAlert(reviewAlertDto);
  }

  // Publish a reviewed alert
  @Put('published')
  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles(UserRole.ADMIN, UserRole.SUPER_ADMIN)
  @ApiOperation({ summary: 'Publish an alert and optionally send to the newsletter' })
  @ApiResponse({ status: 201, description: 'Alert published successfully', type: AlertResponseDto })
  @ApiBody({ type: PublishAlertDto })
  @ApiResponse({ status: 400, description: 'Invalid request data' })
  @ApiResponse({ status: 403, description: 'Forbidden - Insufficient permissions' })
  async publishAlert(@Body() publishAlertDto: PublishAlertDto): Promise<AlertResponseDto> {
    return this.alertService.publishAlert(publishAlertDto);
  }

  // Update alert by ID
  @Put(':id')
  @Roles(UserRole.ADMIN, UserRole.SUPER_ADMIN)
  @ApiOperation({ summary: 'Update alert by ID' })
  @ApiParam({ name: 'id', description: 'The unique identifier of the alert', example: '1' })
  @ApiBody({ type: updateAlertDto })
  @ApiResponse({ status: 200, description: 'Alert updated successfully', type: AlertResponseDto })
  @ApiResponse({ status: 404, description: 'Alert not found' })
  @ApiResponse({ status: 403, description: 'Forbidden - Insufficient permissions' })
  @UseGuards(JwtAuthGuard)
  async updateAlert(@Param('id') id: string, @Body() updateAlert: updateAlertDto): Promise<AlertResponseDto> {
    return this.alertService.updateAlert(id, updateAlert);
  }

  @Delete(':id')
  @Roles(UserRole.ADMIN, UserRole.SUPER_ADMIN)
  @ApiOperation({ summary: 'Delete alert by ID' })
  @ApiParam({ name: 'id', description: 'The unique identifier of the alert', example: '1' })
  @ApiResponse({ status: 200, description: 'Alert deleted successfully', example: 'Alert deleted successfully' })
  @ApiResponse({ status: 404, description: 'Alert not found' })
  @ApiResponse({ status: 403, description: 'Forbidden - Insufficient permissions' })
  @UseGuards(JwtAuthGuard)
  async deleteAlert(@Param('id') id: string): Promise<void> {
    return this.alertService.deleteAlert(id);
  }
}
