import {
  Body,
  Controller,
  Delete,
  ForbiddenException,
  Get,
  Param,
  Patch,
  Post,
} from '@nestjs/common';
import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger';
import { ComplexesService } from './complexes.service';
import { CreateComplexDto } from './dto/create-complex.dto';
import { CreateSpatialUnitDto } from './dto/create-spatial-unit.dto';
import { CreateRepartitionKeyDto } from './dto/create-repartition-key.dto';
import { GenerateLayoutDto } from './dto/generate-layout.dto';
import { Roles } from '../../common/decorators/roles.decorator';
import { CurrentUser, AuthenticatedUser } from '../../common/decorators/current-user.decorator';

@ApiTags('Complexes')
@ApiBearerAuth()
@Controller('complexes')
export class ComplexesController {
  constructor(private readonly complexesService: ComplexesService) {}

  @Roles('SYNDIC')
  @Post()
  @ApiOperation({ summary: 'Create a residential complex' })
  create(@CurrentUser() user: AuthenticatedUser, @Body() dto: CreateComplexDto) {
    if (!user.tenantId) throw new ForbiddenException('Tenant context required');
    return this.complexesService.create(user.tenantId, dto);
  }

  @Get()
  @ApiOperation({ summary: 'List complexes in current tenant' })
  findAll(@CurrentUser() user: AuthenticatedUser) {
    return this.complexesService.findAllForTenant(user.isSuperAdmin ? null : user.tenantId);
  }

  @Get(':id')
  findOne(@CurrentUser() user: AuthenticatedUser, @Param('id') id: string) {
    return this.complexesService.findOne(id, user.tenantId, user.isSuperAdmin);
  }

  @Get(':id/tree')
  @ApiOperation({ summary: 'Return full spatial hierarchy tree with lots & residents' })
  getTree(@CurrentUser() user: AuthenticatedUser, @Param('id') id: string) {
    return this.complexesService.getTree(id, user.tenantId, user.isSuperAdmin);
  }

  @Roles('SYNDIC')
  @Post(':id/spatial-units')
  addSpatialUnit(@Param('id') id: string, @Body() dto: CreateSpatialUnitDto) {
    return this.complexesService.addSpatialUnit(id, dto);
  }

  @Roles('SYNDIC')
  @Post(':id/repartition-keys')
  addRepartitionKey(@Param('id') id: string, @Body() dto: CreateRepartitionKeyDto) {
    return this.complexesService.addRepartitionKey(id, dto);
  }

  @Roles('SYNDIC')
  @Post(':id/generate-layout')
  @ApiOperation({ summary: 'Generate buildings × floors × units + parkings + caves in one shot' })
  generateLayout(
    @CurrentUser() user: AuthenticatedUser,
    @Param('id') id: string,
    @Body() dto: GenerateLayoutDto,
  ) {
    return this.complexesService.generateLayout(id, user.tenantId, user.isSuperAdmin, dto);
  }

  @Roles('SYNDIC', 'SUPERADMIN')
  @Get(':id/dashboard')
  @ApiOperation({ summary: 'Key KPIs for the complex' })
  getDashboard(@CurrentUser() user: AuthenticatedUser, @Param('id') id: string) {
    return this.complexesService.getDashboard(id, user.tenantId, user.isSuperAdmin);
  }

  @Roles('SYNDIC', 'SUPERADMIN')
  @Patch(':id')
  @ApiOperation({ summary: 'Update a complex' })
  update(
    @CurrentUser() user: AuthenticatedUser,
    @Param('id') id: string,
    @Body() dto: CreateComplexDto,
  ) {
    return this.complexesService.update(id, user.tenantId, user.isSuperAdmin, dto);
  }

  @Roles('SYNDIC', 'SUPERADMIN')
  @Delete(':id')
  @ApiOperation({ summary: 'Delete a complex (cascade)' })
  remove(
    @CurrentUser() user: AuthenticatedUser,
    @Param('id') id: string,
  ) {
    return this.complexesService.remove(id, user.tenantId, user.isSuperAdmin);
  }
}
