import { Body, Controller, Delete, Get, Param, Patch, Post, 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 {
  UpsertCargoDto,
  UpsertCentroCostoDto,
  UpsertDepartamentoDto,
  UpsertTipoEmpleadoDto,
} from '../dto/catalogos.dto';
import { CatalogosService } from '../services/catalogos.service';

@ApiTags('RRHH - Catálogos')
@Controller({ path: 'rrhh', version: '1' })
@UseGuards(AuthGuard('jwt'), ModuleGuard, PermissionGuard)
@RequireModule('RRHH')
@ApiBearerAuth()
export class CatalogosController {
  constructor(private readonly service: CatalogosService) {}

  // ── Bancos ─────────────────────────────────────────────
  @Get('bancos')
  @RequirePermission('RRHH', 'RH_CFG_CATALOGO_VER')
  @ApiOperation({ summary: 'Listar bancos disponibles (de la empresa + globales)' })
  listarBancos(@GetUser() user: LoginUserInfo) {
    return this.service.listarBancos(user.empresa_id);
  }

  // ── Cargos ─────────────────────────────────────────────
  @Get('cargos')
  @RequirePermission('RRHH', 'RH_CFG_CATALOGO_VER')
  @ApiOperation({ summary: 'Listar cargos' })
  listarCargos(@GetUser() user: LoginUserInfo) {
    return this.service.listarCargos(user.empresa_id);
  }

  @Post('cargos')
  @RequirePermission('RRHH', 'RH_CFG_CATALOGO_EDITAR')
  @ApiOperation({ summary: 'Crear cargo' })
  crearCargo(@GetUser() user: LoginUserInfo, @Body() dto: UpsertCargoDto) {
    return this.service.crearCargo(user.empresa_id, dto);
  }

  @Patch('cargos/:id')
  @RequirePermission('RRHH', 'RH_CFG_CATALOGO_EDITAR')
  @ApiOperation({ summary: 'Editar cargo' })
  actualizarCargo(@Param('id') id: string, @GetUser() user: LoginUserInfo, @Body() dto: UpsertCargoDto) {
    return this.service.actualizarCargo(id, user.empresa_id, dto);
  }

  @Delete('cargos/:id')
  @RequirePermission('RRHH', 'RH_CFG_CATALOGO_EDITAR')
  @ApiOperation({ summary: 'Eliminar cargo (sólo sin empleados asignados)' })
  eliminarCargo(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.eliminarCargo(id, user.empresa_id);
  }

  // ── Centros de costo ───────────────────────────────────
  @Get('centros-costo')
  @RequirePermission('RRHH', 'RH_CFG_CATALOGO_VER')
  @ApiOperation({ summary: 'Listar centros de costo de RRHH' })
  listarCentrosCosto(@GetUser() user: LoginUserInfo) {
    return this.service.listarCentrosCosto(user.empresa_id);
  }

  @Post('centros-costo')
  @RequirePermission('RRHH', 'RH_CFG_CATALOGO_EDITAR')
  @ApiOperation({ summary: 'Crear centro de costo' })
  crearCentroCosto(@GetUser() user: LoginUserInfo, @Body() dto: UpsertCentroCostoDto) {
    return this.service.crearCentroCosto(user.empresa_id, dto);
  }

  @Patch('centros-costo/:id')
  @RequirePermission('RRHH', 'RH_CFG_CATALOGO_EDITAR')
  @ApiOperation({ summary: 'Editar centro de costo' })
  actualizarCentroCosto(
    @Param('id') id: string,
    @GetUser() user: LoginUserInfo,
    @Body() dto: UpsertCentroCostoDto,
  ) {
    return this.service.actualizarCentroCosto(id, user.empresa_id, dto);
  }

  @Delete('centros-costo/:id')
  @RequirePermission('RRHH', 'RH_CFG_CATALOGO_EDITAR')
  @ApiOperation({ summary: 'Eliminar centro de costo' })
  eliminarCentroCosto(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.eliminarCentroCosto(id, user.empresa_id);
  }

  // ── Departamentos ──────────────────────────────────────
  @Get('departamentos')
  @RequirePermission('RRHH', 'RH_CFG_CATALOGO_VER')
  @ApiOperation({ summary: 'Listar departamentos' })
  listarDepartamentos(@GetUser() user: LoginUserInfo) {
    return this.service.listarDepartamentos(user.empresa_id);
  }

  @Post('departamentos')
  @RequirePermission('RRHH', 'RH_CFG_CATALOGO_EDITAR')
  @ApiOperation({ summary: 'Crear departamento' })
  crearDepartamento(@GetUser() user: LoginUserInfo, @Body() dto: UpsertDepartamentoDto) {
    return this.service.crearDepartamento(user.empresa_id, dto);
  }

  @Patch('departamentos/:id')
  @RequirePermission('RRHH', 'RH_CFG_CATALOGO_EDITAR')
  @ApiOperation({ summary: 'Editar departamento' })
  actualizarDepartamento(
    @Param('id') id: string,
    @GetUser() user: LoginUserInfo,
    @Body() dto: UpsertDepartamentoDto,
  ) {
    return this.service.actualizarDepartamento(id, user.empresa_id, dto);
  }

  @Delete('departamentos/:id')
  @RequirePermission('RRHH', 'RH_CFG_CATALOGO_EDITAR')
  @ApiOperation({ summary: 'Eliminar departamento' })
  eliminarDepartamento(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.eliminarDepartamento(id, user.empresa_id);
  }

  // ── Tipos de empleado ──────────────────────────────────
  @Get('tipos-empleado')
  @RequirePermission('RRHH', 'RH_CFG_CATALOGO_VER')
  @ApiOperation({ summary: 'Listar tipos de empleado' })
  listarTiposEmpleado(@GetUser() user: LoginUserInfo) {
    return this.service.listarTiposEmpleado(user.empresa_id);
  }

  @Post('tipos-empleado')
  @RequirePermission('RRHH', 'RH_CFG_CATALOGO_EDITAR')
  @ApiOperation({ summary: 'Crear tipo de empleado' })
  crearTipoEmpleado(@GetUser() user: LoginUserInfo, @Body() dto: UpsertTipoEmpleadoDto) {
    return this.service.crearTipoEmpleado(user.empresa_id, dto);
  }

  @Patch('tipos-empleado/:id')
  @RequirePermission('RRHH', 'RH_CFG_CATALOGO_EDITAR')
  @ApiOperation({ summary: 'Editar tipo de empleado' })
  actualizarTipoEmpleado(
    @Param('id') id: string,
    @GetUser() user: LoginUserInfo,
    @Body() dto: UpsertTipoEmpleadoDto,
  ) {
    return this.service.actualizarTipoEmpleado(id, user.empresa_id, dto);
  }

  @Delete('tipos-empleado/:id')
  @RequirePermission('RRHH', 'RH_CFG_CATALOGO_EDITAR')
  @ApiOperation({ summary: 'Eliminar tipo de empleado' })
  eliminarTipoEmpleado(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.eliminarTipoEmpleado(id, user.empresa_id);
  }
}
