import {
  Controller,
  Post,
  Body,
  Get,
  Delete,
  Param,
  UseGuards,
  UseInterceptors,
  ClassSerializerInterceptor,
  ValidationPipe,
  Req,
  HttpException,
  HttpStatus,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth } from '@nestjs/swagger';
import { ApiKeyService } from './api-key.service';
import { ApiKeyAuth } from 'common/decorators/api-key.decorator';
import { CreateApiKeyDto } from './dto/api-create.dto';
import { JwtAuthGuard } from 'common/guards/jwt-auth.guard';
import { RateLimitService } from './rate-limit/rate-limit.service';

@ApiTags('API Keys')
@ApiBearerAuth()
@Controller({ path: 'api-keys', version: '1' })
@UseInterceptors(ClassSerializerInterceptor)
@UseGuards(JwtAuthGuard)
export class ApiKeyController {
  constructor(
    private apiKeyService: ApiKeyService,
    private rateLimitService: RateLimitService,
  ) {}

  @Post()
  @ApiOperation({ summary: 'Create a new API key' })
  @ApiResponse({ status: 201, description: 'API key created successfully' })
  @ApiResponse({ status: 400, description: 'Invalid input' })
  async createApiKey(@Req() req: any, @Body(new ValidationPipe()) createApiKeyDto: CreateApiKeyDto) {
    const { user } = req;
    return this.apiKeyService.generateApiKey(user.id, createApiKeyDto);
  }

  @Get()
  @ApiOperation({ summary: 'List all API keys for the authenticated user' })
  @ApiResponse({ status: 200, description: 'List of API keys returned successfully' })
  async listApiKeys(@Req() req: any) {
    const { user } = req;
    return this.apiKeyService.listApiKeys(user.id);
  }

  @Get(':id/usage')
  @ApiOperation({ summary: 'Get usage statistics for an API key' })
  @ApiResponse({ status: 200, description: 'Usage statistics returned successfully' })
  @ApiResponse({ status: 403, description: 'Unauthorized to access this API key' })
  async getApiKeyUsage(@Req() req: any, @Param('id') apiKeyId: string) {
    const { user } = req;
    // First verify the user owns this key
    const apiKey = await this.apiKeyService.findUserApiKey(user.id, apiKeyId);
    if (!apiKey) {
      throw new HttpException('API key not found or not authorized', HttpStatus.FORBIDDEN);
    }

    // Then get the usage stats
    return this.rateLimitService.getUsageStats(apiKeyId);
  }

  @Post(':id/reset-usage')
  @ApiOperation({ summary: 'Reset usage counters for an API key' })
  @ApiResponse({ status: 200, description: 'Usage counters reset successfully' })
  @ApiResponse({ status: 403, description: 'Unauthorized to modify this API key' })
  async resetApiKeyUsage(@Req() req: any, @Param('id') apiKeyId: string) {
    const { user } = req;
    // First verify the user owns this key
    const apiKey = await this.apiKeyService.findUserApiKey(user.id, apiKeyId);
    if (!apiKey) {
      throw new HttpException('API key not found or not authorized', HttpStatus.FORBIDDEN);
    }

    // Then reset the counters
    await this.rateLimitService.resetUsageCounters(apiKeyId);
    return { success: true, message: 'Usage counters reset successfully' };
  }

  @Delete(':id')
  @ApiOperation({ summary: 'Revoke an API key' })
  @ApiResponse({ status: 200, description: 'API key revoked successfully' })
  @ApiResponse({ status: 403, description: 'Unauthorized to revoke this API key' })
  @ApiKeyAuth()
  async revokeApiKey(@Req() req: any, @Param('id') apiKeyId: string) {
    const { user } = req;
    return this.apiKeyService.revokeApiKey(user.id, apiKeyId);
  }
}
