import {
  Body,
  Controller,
  Delete,
  Get,
  Param,
  ParseUUIDPipe,
  Patch,
  Post,
  Query,
  UseGuards,
  ValidationPipe,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiBearerAuth, ApiOperation, ApiQuery, ApiTags } from '@nestjs/swagger';
import { inm_proyecto_estado } from '@prisma/client';
import { RequirePermission } from 'src/auth/decorators/require-permission.decorator';
import { RequireSubmodulo } from 'src/auth/decorators/require-submodulo.decorator';
import type { LoginUserInfo } from 'src/auth/dto/login.dto';
import { GetUser } from 'src/auth/get-user.decorator';
import { PermissionGuard } from 'src/auth/guards/permission.guard';
import { SubmoduloGuard } from 'src/auth/guards/submodulo.guard';
import {
  CreateEtapaInmDto,
  CreateHitoDto,
  CumplirHitoDto,
  UpdateEtapaInmDto,
  UpdateHitoDto,
} from './dto/etapa-hito.dto';
import { CreateProyectoDto, UpdateProyectoDto } from './dto/proyecto.dto';
import { ProyectosInmService } from './proyectos.service';

@ApiTags('Inmobiliario · Proyectos')
@ApiBearerAuth()
@UseGuards(AuthGuard('jwt'), SubmoduloGuard)
@RequireSubmodulo('INM_PROYECTOS')
@Controller({ path: 'inmobiliario', version: '1' })
export class ProyectosInmController {
  constructor(private readonly service: ProyectosInmService) {}

  @Get('proyectos')
  @UseGuards(PermissionGuard)
  @RequirePermission('INMOBILIARIO', 'INM_PRO_PROYECTO_VER')
  @ApiQuery({ name: 'estado', required: false, enum: inm_proyecto_estado })
  @ApiQuery({ name: 'q', required: false, description: 'Busca en nombre, código y ciudad' })
  @ApiQuery({ name: 'incluir_inactivos', required: false })
  listar(
    @GetUser() user: LoginUserInfo,
    @Query('estado') estado?: inm_proyecto_estado,
    @Query('q') q?: string,
    @Query('incluir_inactivos') incluirInactivos?: string,
  ) {
    return this.service.listar(user.empresa_id, { estado, q, incluir_inactivos: incluirInactivos === 'true' });
  }

  @Get('proyectos/:id')
  @UseGuards(PermissionGuard)
  @RequirePermission('INMOBILIARIO', 'INM_PRO_PROYECTO_VER')
  @ApiOperation({ summary: 'Proyecto con sus etapas e hitos activos' })
  detalle(@Param('id', ParseUUIDPipe) id: string, @GetUser() user: LoginUserInfo) {
    return this.service.detalle(id, user.empresa_id);
  }

  @Post('proyectos')
  @UseGuards(PermissionGuard)
  @RequirePermission('INMOBILIARIO', 'INM_PRO_PROYECTO_CREAR')
  @ApiOperation({ summary: 'Crea el proyecto; si no se elige centro de costo, crea uno con su código' })
  crear(@Body(ValidationPipe) dto: CreateProyectoDto, @GetUser() user: LoginUserInfo) {
    return this.service.crear(dto, user.empresa_id, user.id);
  }

  @Patch('proyectos/:id')
  @UseGuards(PermissionGuard)
  @RequirePermission('INMOBILIARIO', 'INM_PRO_PROYECTO_EDITAR')
  actualizar(
    @Param('id', ParseUUIDPipe) id: string,
    @Body(ValidationPipe) dto: UpdateProyectoDto,
    @GetUser() user: LoginUserInfo,
  ) {
    return this.service.actualizar(id, dto, user.empresa_id, user.id);
  }

  @Delete('proyectos/:id')
  @UseGuards(PermissionGuard)
  @RequirePermission('INMOBILIARIO', 'INM_PRO_PROYECTO_ELIMINAR')
  @ApiOperation({ summary: 'Baja lógica: el proyecto nunca se borra' })
  darDeBaja(@Param('id', ParseUUIDPipe) id: string, @GetUser() user: LoginUserInfo) {
    return this.service.darDeBaja(id, user.empresa_id, user.id);
  }

  // ------------------------------------------------------------------- etapas

  @Post('proyectos/:id/etapas')
  @UseGuards(PermissionGuard)
  @RequirePermission('INMOBILIARIO', 'INM_PRO_PROYECTO_EDITAR')
  crearEtapa(
    @Param('id', ParseUUIDPipe) id: string,
    @Body(ValidationPipe) dto: CreateEtapaInmDto,
    @GetUser() user: LoginUserInfo,
  ) {
    return this.service.crearEtapa(id, dto, user.empresa_id, user.id);
  }

  @Patch('etapas/:id')
  @UseGuards(PermissionGuard)
  @RequirePermission('INMOBILIARIO', 'INM_PRO_PROYECTO_EDITAR')
  actualizarEtapa(
    @Param('id', ParseUUIDPipe) id: string,
    @Body(ValidationPipe) dto: UpdateEtapaInmDto,
    @GetUser() user: LoginUserInfo,
  ) {
    return this.service.actualizarEtapa(id, dto, user.empresa_id, user.id);
  }

  @Delete('etapas/:id')
  @UseGuards(PermissionGuard)
  @RequirePermission('INMOBILIARIO', 'INM_PRO_PROYECTO_EDITAR')
  darDeBajaEtapa(@Param('id', ParseUUIDPipe) id: string, @GetUser() user: LoginUserInfo) {
    return this.service.darDeBajaEtapa(id, user.empresa_id, user.id);
  }

  // -------------------------------------------------------------------- hitos

  @Post('proyectos/:id/hitos')
  @UseGuards(PermissionGuard)
  @RequirePermission('INMOBILIARIO', 'INM_PRO_PROYECTO_EDITAR')
  crearHito(
    @Param('id', ParseUUIDPipe) id: string,
    @Body(ValidationPipe) dto: CreateHitoDto,
    @GetUser() user: LoginUserInfo,
  ) {
    return this.service.crearHito(id, dto, user.empresa_id, user.id);
  }

  @Patch('hitos/:id')
  @UseGuards(PermissionGuard)
  @RequirePermission('INMOBILIARIO', 'INM_PRO_PROYECTO_EDITAR')
  actualizarHito(
    @Param('id', ParseUUIDPipe) id: string,
    @Body(ValidationPipe) dto: UpdateHitoDto,
    @GetUser() user: LoginUserInfo,
  ) {
    return this.service.actualizarHito(id, dto, user.empresa_id, user.id);
  }

  @Post('hitos/:id/cumplir')
  @UseGuards(PermissionGuard)
  @RequirePermission('INMOBILIARIO', 'INM_PRO_HITO_CONFIRMAR')
  @ApiOperation({ summary: 'Da el hito por cumplido (habilita las cuotas atadas a él)' })
  cumplirHito(
    @Param('id', ParseUUIDPipe) id: string,
    @Body(ValidationPipe) dto: CumplirHitoDto,
    @GetUser() user: LoginUserInfo,
  ) {
    return this.service.cumplirHito(id, dto, user.empresa_id, user.id);
  }

  @Post('hitos/:id/revertir')
  @UseGuards(PermissionGuard)
  @RequirePermission('INMOBILIARIO', 'INM_PRO_HITO_REVERTIR')
  revertirHito(@Param('id', ParseUUIDPipe) id: string, @GetUser() user: LoginUserInfo) {
    return this.service.revertirHito(id, user.empresa_id, user.id);
  }

  @Delete('hitos/:id')
  @UseGuards(PermissionGuard)
  @RequirePermission('INMOBILIARIO', 'INM_PRO_PROYECTO_EDITAR')
  darDeBajaHito(@Param('id', ParseUUIDPipe) id: string, @GetUser() user: LoginUserInfo) {
    return this.service.darDeBajaHito(id, user.empresa_id, user.id);
  }
}
