import { Body, Controller, Get, Param, Patch, Post, Query } from '@nestjs/common';
import { ApiBody, ApiOperation, ApiParam, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger';
import { ResidentRequestStatus, 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 { ApiProtectedEndpoint, ApiValidationError, ESTATE_ID_EXAMPLE, RESIDENT_ID_EXAMPLE } from '../common/swagger-docs';
import { FeatureKey } from '../features/feature-catalog';
import { RequireFeature } from '../features/require-feature.decorator';
import { CreateResidentRequestDto, RespondResidentRequestDto } from './dto/request.dto';
import { RequestsService } from './requests.service';

@ApiTags('Resident Requests')
@ApiProtectedEndpoint()
@Controller({ path: 'requests', version: '1' })
export class RequestsController {
  constructor(private readonly requests: RequestsService) {}

  @Get('options')
  @RequireRole(UserRole.ESTATE_ADMIN, UserRole.SECURITY_SUPERVISOR, UserRole.GUARD, UserRole.RESIDENT)
  @RequireFeature(FeatureKey.REQUESTS_VIEW)
  @ApiOperation({
    summary: 'List request form options',
    description:
      'Returns the resident request categories, priority options, expected fields, and photo-upload rule used by MobileApp request screens.'
  })
  @ApiResponse({ status: 200, description: 'Request form options returned.' })
  getOptions() {
    return this.requests.getOptions();
  }

  @Get()
  @RequireRole(UserRole.ESTATE_ADMIN, UserRole.SECURITY_SUPERVISOR, UserRole.GUARD, UserRole.RESIDENT)
  @RequireFeature(FeatureKey.REQUESTS_VIEW)
  @ApiOperation({
    summary: 'List requests and complaints',
    description: 'Residents see their own requests. Security and estate admins see requests in their estate scope.'
  })
  @ApiQuery({ name: 'estateId', required: false, example: ESTATE_ID_EXAMPLE })
  @ApiQuery({ name: 'residentId', required: false, example: RESIDENT_ID_EXAMPLE })
  @ApiQuery({ name: 'status', required: false, enum: ResidentRequestStatus })
  @ApiResponse({ status: 200, description: 'Requests returned.' })
  findAll(
    @CurrentUser() user: RequestUser,
    @Query('estateId') estateId?: string,
    @Query('residentId') residentId?: string,
    @Query('status') status?: ResidentRequestStatus
  ) {
    return this.requests.findAll(user, estateId, residentId, status);
  }

  @Post()
  @RequireRole(UserRole.RESIDENT, UserRole.ESTATE_ADMIN, UserRole.SECURITY_SUPERVISOR)
  @RequireFeature(FeatureKey.REQUESTS_CREATE)
  @ApiOperation({ summary: 'Create request or complaint', description: 'Creates a security, infrastructure, estate services, or support request.' })
  @ApiBody({ type: CreateResidentRequestDto })
  @ApiResponse({ status: 201, description: 'Request created.' })
  @ApiValidationError()
  create(@Body() dto: CreateResidentRequestDto, @CurrentUser() user: RequestUser) {
    return this.requests.create(dto, user);
  }

  @Patch(':id/respond')
  @RequireRole(UserRole.ESTATE_ADMIN, UserRole.SECURITY_SUPERVISOR, UserRole.GUARD)
  @RequireFeature(FeatureKey.REQUESTS_RESPOND)
  @ApiOperation({ summary: 'Respond to request', description: 'Adds a response and optionally updates status or assignment.' })
  @ApiParam({ name: 'id', example: 'request-uuid' })
  @ApiBody({ type: RespondResidentRequestDto })
  @ApiResponse({ status: 200, description: 'Request updated.' })
  @ApiValidationError()
  respond(@Param('id') id: string, @Body() dto: RespondResidentRequestDto, @CurrentUser() user: RequestUser) {
    return this.requests.respond(id, dto, user);
  }
}
