import {
  Body,
  Controller,
  Delete,
  Get,
  HttpCode,
  HttpStatus,
  Param,
  ParseUUIDPipe,
  Post,
  UseGuards,
} from '@nestjs/common';
import { ApiBearerAuth, ApiOperation, ApiResponse, ApiSecurity, ApiTags } from '@nestjs/swagger';

import { CurrentUser } from '../decorators/current-user.decorator';
import { RequiresFeature } from '../decorators/requires-feature.decorator';
import { FeatureFlagGuard } from '../guards/feature-flag.guard';

import { ApiKeysService } from './api-keys.service';
import { CreateApiKeyDto, ApiKeyDto, CreateApiKeyResultDto } from '../dto/api-key.dto';

@ApiTags('API Keys')
@ApiBearerAuth()
@ApiSecurity('x-api-key')
@UseGuards(FeatureFlagGuard)
@RequiresFeature('api_access')
@Controller('api-keys')
export class ApiKeysController {
  constructor(private readonly apiKeysService: ApiKeysService) {}

  @Post()
  @ApiOperation({
    summary: 'Générer une nouvelle clé API',
    description:
      'Crée une clé API pour accès programmatique. La clé complète est retournée **une seule fois** — conservez-la immédiatement. Réservé aux abonnements Gold et Platinium.',
  })
  @ApiResponse({
    status: 201,
    description: 'Clé créée avec succès. La clé complète est dans le champ `fullKey`.',
    type: CreateApiKeyResultDto,
  })
  @ApiResponse({ status: 403, description: 'Abonnement Gold ou Platinium requis' })
  async create(
    @CurrentUser() user: { id: string; organizationId: string },
    @Body() dto: CreateApiKeyDto
  ): Promise<CreateApiKeyResultDto> {
    return this.apiKeysService.generateApiKey(user.id, user.organizationId, dto);
  }

  @Get()
  @ApiOperation({
    summary: 'Lister les clés API',
    description:
      "Retourne toutes les clés API de l'organisation. Les clés complètes ne sont jamais exposées — uniquement le préfixe.",
  })
  @ApiResponse({ status: 200, type: [ApiKeyDto] })
  async list(@CurrentUser() user: { organizationId: string }): Promise<ApiKeyDto[]> {
    return this.apiKeysService.listApiKeys(user.organizationId);
  }

  @Delete(':id')
  @HttpCode(HttpStatus.NO_CONTENT)
  @ApiOperation({
    summary: 'Révoquer une clé API',
    description: 'Désactive immédiatement la clé API. Cette action est irréversible.',
  })
  @ApiResponse({ status: 204, description: 'Clé révoquée' })
  @ApiResponse({ status: 404, description: 'Clé introuvable' })
  async revoke(
    @CurrentUser() user: { organizationId: string },
    @Param('id', ParseUUIDPipe) keyId: string
  ): Promise<void> {
    return this.apiKeysService.revokeApiKey(keyId, user.organizationId);
  }
}
