import { Body, Controller, Delete, 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 {
  CambiarEstadoPrestamoDto,
  CreatePrestamoDto,
  MarcarCuotaDescontadaDto,
  QueryPrestamosDto,
  UpdatePrestamoDto,
} from '../dto/prestamos.dto';
import { PrestamosService } from '../services/prestamos.service';

@ApiTags('RRHH - Préstamos a empleados')
@Controller({ path: 'rrhh/prestamos', version: '1' })
@UseGuards(AuthGuard('jwt'), ModuleGuard, PermissionGuard)
@RequireModule('RRHH')
@ApiBearerAuth()
export class PrestamosController {
  constructor(private readonly service: PrestamosService) {}

  @Get()
  @RequirePermission('RRHH', 'RH_ANT_PRESTAMO_VER')
  @ApiOperation({ summary: 'Listar préstamos' })
  listar(@GetUser() user: LoginUserInfo, @Query() query: QueryPrestamosDto) {
    return this.service.listar(user.empresa_id, query);
  }

  @Get(':id')
  @RequirePermission('RRHH', 'RH_ANT_PRESTAMO_VER')
  @ApiOperation({ summary: 'Obtener préstamo con cuotas' })
  obtener(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.obtener(id, user.empresa_id);
  }

  @Post()
  @RequirePermission('RRHH', 'RH_ANT_PRESTAMO_CREAR')
  @ApiOperation({ summary: 'Otorgar préstamo (genera cronograma de cuotas automáticamente)' })
  crear(@GetUser() user: LoginUserInfo, @Body() dto: CreatePrestamoDto) {
    return this.service.crear(user.empresa_id, dto, user.id);
  }

  @Patch(':id')
  @RequirePermission('RRHH', 'RH_ANT_PRESTAMO_EDITAR')
  @ApiOperation({ summary: 'Editar observación del préstamo' })
  actualizar(
    @Param('id') id: string,
    @GetUser() user: LoginUserInfo,
    @Body() dto: UpdatePrestamoDto,
  ) {
    return this.service.actualizar(id, user.empresa_id, dto);
  }

  @Patch(':id/estado')
  @RequirePermission('RRHH', 'RH_ANT_PRESTAMO_EDITAR')
  @ApiOperation({ summary: 'Cambiar estado (ACTIVO ↔ SUSPENDIDO; → CANCELADO)' })
  cambiarEstado(
    @Param('id') id: string,
    @GetUser() user: LoginUserInfo,
    @Body() dto: CambiarEstadoPrestamoDto,
  ) {
    return this.service.cambiarEstado(id, user.empresa_id, dto, user.id);
  }

  @Delete(':id')
  @RequirePermission('RRHH', 'RH_ANT_PRESTAMO_ELIMINAR')
  @ApiOperation({ summary: 'Eliminar préstamo (sólo si no tiene cuotas descontadas)' })
  eliminar(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.eliminar(id, user.empresa_id);
  }

  // ── Cuotas ───────────────────────────────────────
  @Get(':id/cuotas')
  @RequirePermission('RRHH', 'RH_ANT_PRESTAMO_VER')
  @ApiOperation({ summary: 'Listar cuotas del préstamo' })
  listarCuotas(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.service.listarCuotas(id, user.empresa_id);
  }

  @Patch(':id/cuotas/:cuotaId/descontar')
  @RequirePermission('RRHH', 'RH_ANT_PRESTAMO_EDITAR')
  @ApiOperation({
    summary: 'Marcar cuota como DESCONTADO (actualiza saldo del préstamo)',
    description:
      'Será invocado por el motor de liquidación al cerrar la liquidación del período. ' +
      'Si la cuota era la última pendiente, el préstamo pasa a CANCELADO automáticamente.',
  })
  marcarCuotaDescontada(
    @Param('id') id: string,
    @Param('cuotaId') cuotaId: string,
    @GetUser() user: LoginUserInfo,
    @Body() dto: MarcarCuotaDescontadaDto,
  ) {
    return this.service.marcarCuotaDescontada(id, cuotaId, user.empresa_id, dto);
  }
}
