import { Body, Controller, Get, Param, Patch, Post, Query } from '@nestjs/common';
import { ApiBody, ApiOperation, ApiParam, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger';
import { UserRole } from '@prisma/client';
import { RequireRole } from '../auth/require-role.decorator';
import { CurrentUser } from '../common/current-user.decorator';
import { RequestUser } from '../common/request-user';
import { ApiNotFoundError, ApiProtectedEndpoint, ApiValidationError, ESTATE_ID_EXAMPLE } from '../common/swagger-docs';
import { FeatureKey } from '../features/feature-catalog';
import { RequireFeature } from '../features/require-feature.decorator';
import { CreateGateDto, UpdateGateDto } from './dto/gate.dto';
import { GatesService } from './gates.service';

@ApiTags('Gates')
@ApiProtectedEndpoint()
@Controller({ path: 'gates', version: '1' })
export class GatesController {
  constructor(private readonly gatesService: GatesService) {}

  @Get()
  @RequireRole(UserRole.ESTATE_ADMIN, UserRole.SECURITY_SUPERVISOR, UserRole.GUARD)
  @RequireFeature(FeatureKey.GATES_VIEW)
  @ApiOperation({ summary: 'List estate gates', description: 'Returns gates in the current estate scope with guard and session counts.' })
  @ApiQuery({ name: 'estateId', required: false, example: ESTATE_ID_EXAMPLE })
  @ApiResponse({ status: 200, description: 'Gates returned.' })
  findAll(@CurrentUser() user: RequestUser, @Query('estateId') estateId?: string) {
    return this.gatesService.findAll(user, estateId);
  }

  @Post()
  @RequireRole(UserRole.ESTATE_ADMIN)
  @RequireFeature(FeatureKey.GATES_MANAGE)
  @ApiOperation({ summary: 'Create gate', description: 'Creates a gate if the estate subscription plan allows another gate.' })
  @ApiBody({ type: CreateGateDto })
  @ApiResponse({ status: 201, description: 'Gate created.' })
  @ApiValidationError()
  create(@Body() dto: CreateGateDto, @CurrentUser() user: RequestUser) {
    return this.gatesService.create(dto, user);
  }

  @Patch(':id')
  @RequireRole(UserRole.ESTATE_ADMIN)
  @RequireFeature(FeatureKey.GATES_MANAGE)
  @ApiOperation({ summary: 'Update gate', description: 'Updates gate name, type, description, status, or metadata.' })
  @ApiParam({ name: 'id', example: 'gate-uuid' })
  @ApiBody({ type: UpdateGateDto })
  @ApiResponse({ status: 200, description: 'Gate updated.' })
  @ApiNotFoundError('Gate')
  @ApiValidationError()
  update(@Param('id') id: string, @Body() dto: UpdateGateDto, @CurrentUser() user: RequestUser) {
    return this.gatesService.update(id, dto, user);
  }
}
