import { Body, Controller, Get, Param, 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 { ApiProtectedEndpoint, ApiValidationError, ESTATE_ID_EXAMPLE } from '../common/swagger-docs';
import { FeatureKey } from '../features/feature-catalog';
import { RequireFeature } from '../features/require-feature.decorator';
import { AnnouncementsService } from './announcements.service';
import { CreateAnnouncementDto } from './dto/announcement.dto';

@ApiTags('Announcements')
@ApiProtectedEndpoint()
@Controller({ path: 'announcements', version: '1' })
export class AnnouncementsController {
  constructor(private readonly announcements: AnnouncementsService) {}

  @Get('options')
  @RequireRole(UserRole.ESTATE_ADMIN, UserRole.SECURITY_SUPERVISOR, UserRole.GUARD, UserRole.RESIDENT)
  @RequireFeature(FeatureKey.ANNOUNCEMENTS_VIEW)
  @ApiOperation({
    summary: 'List announcement options',
    description:
      'Returns announcement categories, priority options, and public-safe content rules for MobileApp and WebApp announcement screens.'
  })
  @ApiResponse({ status: 200, description: 'Announcement options returned.' })
  getOptions() {
    return this.announcements.getOptions();
  }

  @Get()
  @RequireRole(UserRole.ESTATE_ADMIN, UserRole.SECURITY_SUPERVISOR, UserRole.GUARD, UserRole.RESIDENT)
  @RequireFeature(FeatureKey.ANNOUNCEMENTS_VIEW)
  @ApiOperation({
    summary: 'List estate announcements',
    description: 'Returns published estate announcements and news visible to the signed-in estate.'
  })
  @ApiQuery({ name: 'estateId', required: false, example: ESTATE_ID_EXAMPLE })
  @ApiResponse({ status: 200, description: 'Announcements returned.' })
  findAll(@CurrentUser() user: RequestUser, @Query('estateId') estateId?: string) {
    return this.announcements.findAll(user, estateId);
  }

  @Get(':id')
  @RequireRole(UserRole.ESTATE_ADMIN, UserRole.SECURITY_SUPERVISOR, UserRole.GUARD, UserRole.RESIDENT)
  @RequireFeature(FeatureKey.ANNOUNCEMENTS_VIEW)
  @ApiOperation({
    summary: 'View announcement detail',
    description: 'Returns a single published announcement with author, target, attachment metadata, and read-status data where available.'
  })
  @ApiParam({ name: 'id', example: 'announcement-uuid' })
  @ApiResponse({ status: 200, description: 'Announcement returned.' })
  findOne(@CurrentUser() user: RequestUser, @Param('id') id: string) {
    return this.announcements.findOne(user, id);
  }

  @Post()
  @RequireRole(UserRole.ESTATE_ADMIN, UserRole.SECURITY_SUPERVISOR, UserRole.GUARD)
  @RequireFeature(FeatureKey.ANNOUNCEMENTS_SEND)
  @ApiOperation({
    summary: 'Send estate announcement',
    description:
      'Sends a plan-limited estate announcement. Promotional, political, spam, or unrelated content is blocked and logged for super-admin review.'
  })
  @ApiBody({ type: CreateAnnouncementDto })
  @ApiResponse({ status: 201, description: 'Announcement sent.' })
  @ApiValidationError()
  create(@Body() dto: CreateAnnouncementDto, @CurrentUser() user: RequestUser) {
    return this.announcements.create(dto, user);
  }
}
