import {
  Controller,
  Post,
  Body,
  Get,
  Param,
  ValidationPipe,
  HttpStatus,
  NotFoundException,
  BadRequestException,
  InternalServerErrorException,
  UseGuards,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse, ApiBody, ApiParam } from '@nestjs/swagger';
import { WebsiteScannerService } from './website-scanner.service';
import { ScanResultDto } from './dto/scanner.dto';
import { ScanWebsiteDto } from './dto/scanner.dto';
import { JwtAuthGuard } from 'common/guards/jwt-auth.guard';
import { RolesGuard } from 'common/guards/roles.guard';
import { PermissionsGuard } from 'common/guards/ppermissions.guard';
import { Roles } from 'common/decorators/role.decorator';
import { UserRole } from 'common/enum/UserRole.enum';
import { Permissions } from 'common/decorators/permissions.decorator';
import { FeatureEnum } from 'common/enum/Permissions.enum';

@ApiTags('Website Security Scanner')
// @Controller('security')
@Controller({ path: 'security', version: '1' })
@UseGuards(JwtAuthGuard, RolesGuard, PermissionsGuard)
export class WebsiteScannerController {
  constructor(private readonly websiteScannerService: WebsiteScannerService) {}

  @Post('scan')
  @Roles(UserRole.SUPER_ADMIN, UserRole.ADMIN, UserRole.CLIENT, UserRole.USER)
  @Permissions(FeatureEnum.WS_SCAN)
  @ApiOperation({
    summary: 'Initiate a security scan for a website',
    description: 'Performs a comprehensive security assessment of the given URL',
  })
  @ApiBody({
    type: ScanWebsiteDto,
    description: 'URL to be scanned',
  })
  @ApiResponse({
    status: HttpStatus.CREATED,
    description: 'Scan initiated successfully',
    type: ScanResultDto,
  })
  @ApiResponse({
    status: HttpStatus.BAD_REQUEST,
    description: 'Invalid URL provided',
  })
  async scanWebsite(
    @Body(
      new ValidationPipe({
        transform: true,
        whitelist: true,
        forbidNonWhitelisted: true,
      }),
    )
    scanDto: ScanWebsiteDto,
  ): Promise<ScanResultDto> {
    try {
      return await this.websiteScannerService.scanWebsite(scanDto.url);
    } catch (error) {
      throw new BadRequestException(error.message);
    }
  }

  @Get('scan/:id')
  @Roles(UserRole.SUPER_ADMIN, UserRole.ADMIN, UserRole.CLIENT, UserRole.USER)
  @Permissions(FeatureEnum.WS_SCAN_BY_ID)
  @ApiOperation({
    summary: 'Retrieve previous scan results',
    description: 'Fetches detailed results of a previous website security scan',
  })
  @ApiParam({
    name: 'id',
    description: 'Unique identifier of the scan',
    example: '123e4567-e89b-12d3-a456-426614174000',
  })
  @ApiResponse({
    status: HttpStatus.OK,
    description: 'Scan results retrieved successfully',
    type: ScanResultDto,
  })
  @ApiResponse({
    status: HttpStatus.NOT_FOUND,
    description: 'Scan results not found',
  })
  async getScanResults(@Param('id') id: number): Promise<ScanResultDto> {
    try {
      const scanResult = await this.websiteScannerService.getScanResultsById(id);

      if (!scanResult) {
        throw new NotFoundException(`Scan results with ID ${id} not found`);
      }

      return scanResult;
    } catch (error) {
      if (error instanceof NotFoundException) {
        throw error;
      }
      throw new InternalServerErrorException('Error retrieving scan results');
    }
  }

  @Get('recent-scans')
  @Roles(UserRole.SUPER_ADMIN, UserRole.ADMIN, UserRole.CLIENT, UserRole.USER)
  @Permissions(FeatureEnum.WS_RECENT_SCANS)
  @ApiOperation({
    summary: 'Retrieve recent scan results',
    description: 'Fetches a list of most recent website security scans',
  })
  @ApiResponse({
    status: HttpStatus.OK,
    description: 'Recent scans retrieved successfully',
    type: [ScanResultDto],
  })
  async getRecentScans(): Promise<ScanResultDto[]> {
    try {
      return await this.websiteScannerService.getScanResults();
    } catch (error) {
      throw new InternalServerErrorException('Error retrieving recent scans', error.message);
    }
  }

  //advanced scan headers
  @Post('scan-headers')
  @Roles(UserRole.SUPER_ADMIN, UserRole.ADMIN, UserRole.CLIENT, UserRole.USER)
  @Permissions(FeatureEnum.WS_SCAN_HEADERS)
  @ApiOperation({
    summary: 'Scan HTTP response headers for security issues',
    description: "Checks a website's HTTP headers to identify security-related configurations",
  })
  @ApiBody({
    type: ScanWebsiteDto,
    description: 'URL to be scanned for headers',
  })
  @ApiResponse({
    status: HttpStatus.OK,
    description: 'Header scan completed successfully',
  })
  @ApiResponse({
    status: HttpStatus.BAD_REQUEST,
    description: 'Invalid URL or scan failed',
  })
  async scanHeaders(
    @Body(
      new ValidationPipe({
        transform: true,
        whitelist: true,
        forbidNonWhitelisted: true,
      }),
    )
    scanDto: ScanWebsiteDto,
  ): Promise<any> {
    try {
      return await this.websiteScannerService.scanHeaders(scanDto.url);
    } catch (error) {
      throw new BadRequestException(error.message);
    }
  }
}
