import { Body, Controller, Get, Param, Patch, Post, Query, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger';
import { RequireModule } from '../../auth/decorators/require-module.decorator';
import { RequirePermission } from '../../auth/decorators/require-permission.decorator';
import type { LoginUserInfo } from '../../auth/dto/login.dto';
import { GetUser } from '../../auth/get-user.decorator';
import { ModuleGuard } from '../../auth/guards/module.guard';
import { PermissionGuard } from '../../auth/guards/permission.guard';
import {
  AccionDesvinculacionDto,
  CalcularDesvinculacionDto,
  CrearDesvinculacionDto,
  QueryDesvinculacionesDto,
  UpdateDesvinculacionDto,
} from '../dto/desvinculaciones.dto';
import { DesvinculacionesService } from '../services/desvinculaciones.service';

@ApiTags('RRHH - Desvinculaciones / finiquitos')
@Controller({ path: 'rrhh/desvinculaciones', version: '1' })
@UseGuards(AuthGuard('jwt'), ModuleGuard, PermissionGuard)
@RequireModule('RRHH')
@ApiBearerAuth()
export class DesvinculacionesController {
  constructor(private readonly service: DesvinculacionesService) {}

  @Get()
  @RequirePermission('RRHH', 'RH_DES_DESVINCULACION_VER')
  @ApiOperation({ summary: 'Listar desvinculaciones' })
  listar(@GetUser() user: LoginUserInfo, @Query() query: QueryDesvinculacionesDto) {
    return this.service.listar(user.empresa_id, query);
  }

  @Get(':id')
  @RequirePermission('RRHH', 'RH_DES_DESVINCULACION_VER')
  @ApiOperation({ summary: 'Obtener desvinculación con desglose' })
  obtener(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.obtener(id, user.empresa_id);
  }

  @Post('preview')
  @RequirePermission('RRHH', 'RH_DES_DESVINCULACION_CREAR')
  @ApiOperation({
    summary: 'Calcular preview del finiquito sin persistir',
    description:
      'Aplica reglas legales: preaviso (Art. 87), indemnización (15 días por año Art. 91-94), ' +
      'vacaciones proporcionales según escala Art. 219, vacaciones no gozadas pendientes, aguinaldo proporcional (Art. 244).',
  })
  preview(@GetUser() user: LoginUserInfo, @Body() dto: CalcularDesvinculacionDto) {
    return this.service.calcularPreview(user.empresa_id, dto);
  }

  @Post()
  @RequirePermission('RRHH', 'RH_DES_DESVINCULACION_CREAR')
  @ApiOperation({ summary: 'Crear desvinculación en estado CALCULADO' })
  crear(@GetUser() user: LoginUserInfo, @Body() dto: CrearDesvinculacionDto) {
    return this.service.crear(user.empresa_id, dto, user.id);
  }

  @Patch(':id')
  @RequirePermission('RRHH', 'RH_DES_DESVINCULACION_EDITAR')
  @ApiOperation({ summary: 'Editar ajustes manuales (sólo CALCULADO)' })
  actualizar(
    @Param('id') id: string,
    @GetUser() user: LoginUserInfo,
    @Body() dto: UpdateDesvinculacionDto,
  ) {
    return this.service.actualizar(id, user.empresa_id, dto);
  }

  @Patch(':id/aprobar')
  @RequirePermission('RRHH', 'RH_DES_DESVINCULACION_PROCESAR')
  @ApiOperation({ summary: 'Aprobar finiquito (CALCULADO → APROBADO)' })
  aprobar(
    @Param('id') id: string,
    @GetUser() user: LoginUserInfo,
    @Body() dto: AccionDesvinculacionDto,
  ) {
    return this.service.aprobar(id, user.empresa_id, dto, user.id);
  }

  @Patch(':id/pagar')
  @RequirePermission('RRHH', 'RH_DES_DESVINCULACION_PROCESAR')
  @ApiOperation({
    summary: 'Marcar como PAGADO',
    description:
      'Marca el empleado como EGRESADO con fecha_egreso = fecha_ultimo_dia. Bloquea su inclusión en futuras liquidaciones.',
  })
  pagar(
    @Param('id') id: string,
    @GetUser() user: LoginUserInfo,
    @Body() dto: AccionDesvinculacionDto,
  ) {
    return this.service.pagar(id, user.empresa_id, dto, user.id);
  }

  @Patch(':id/anular')
  @RequirePermission('RRHH', 'RH_DES_DESVINCULACION_EDITAR')
  @ApiOperation({ summary: 'Anular finiquito (sólo si NO fue pagado)' })
  anular(
    @Param('id') id: string,
    @GetUser() user: LoginUserInfo,
    @Body() dto: AccionDesvinculacionDto,
  ) {
    return this.service.anular(id, user.empresa_id, dto, user.id);
  }
}
