import { Body, Controller, Get, Param, Patch, Post, Query, Res, UseGuards } from '@nestjs/common';
import type { Response } from 'express';
import { AuthGuard } from '@nestjs/passport';
import { ApiBearerAuth, ApiOperation, ApiQuery, ApiTags } from '@nestjs/swagger';
import type { LoginUserInfo } from 'src/auth/dto/login.dto';
import { GetUser } from 'src/auth/get-user.decorator';
import { RequireModule, RequirePermission } from 'src/auth/decorators';
import { ModuleGuard } from 'src/auth/guards/module.guard';
import { PermissionGuard } from 'src/auth/guards/permission.guard';
import { CobrosService } from './cobros.service';
import { CreateReciboCobroDto, PreviewDistribucionDto } from './dto/create-cobro.dto';
import { UpdateReciboCobroDto } from './dto/update-cobro.dto';

@ApiTags('Cobros')
@ApiBearerAuth()
@UseGuards(AuthGuard('jwt'), ModuleGuard, PermissionGuard)
@RequireModule('COBRANZAS')
@Controller({ path: 'cobros', version: '1' })
export class CobrosController {
  constructor(private readonly cobrosService: CobrosService) {}

  @Post()
  @RequirePermission('COBRANZAS', 'COB_REC_RECIBO_CREAR')
  @ApiOperation({ summary: 'Crear un nuevo recibo de cobro' })
  create(@Body() createReciboCobroDto: CreateReciboCobroDto, @GetUser() user: LoginUserInfo) {
    return this.cobrosService.create(createReciboCobroDto, user.id, user.empresa_id);
  }

  @Get()
  @RequirePermission('COBRANZAS', 'COB_REC_RECIBO_VER')
  @ApiOperation({ summary: 'Listar recibos de cobro' })
  @ApiQuery({ name: 'skip', required: false, type: Number })
  @ApiQuery({ name: 'take', required: false, type: Number })
  @ApiQuery({ name: 'clienteId', required: false, type: String })
  @ApiQuery({ name: 'estado', required: false, type: String })
  @ApiQuery({ name: 'fechaDesde', required: false, type: String })
  @ApiQuery({ name: 'fechaHasta', required: false, type: String })
  @ApiQuery({ name: 'cobradorId', required: false, type: String })
  @ApiQuery({ name: 'cajaId', required: false, type: String, description: "Auditoría: uuid de la caja donde se cobró, o 'SIN_CAJA' para los recibos sin sesión" })
  @ApiQuery({ name: 'busqueda', required: false, type: String, description: 'Buscar por N° recibo o nombre de cliente' })
  @ApiQuery({ name: 'modo', required: false, enum: ['LEGACY', 'MULTI'], description: 'Omitir para listar ambos' })
  @ApiQuery({ name: 'orderBy', required: false, type: String, description: 'Columna a ordenar' })
  @ApiQuery({ name: 'order', required: false, enum: ['asc', 'desc'] })
  findAll(
    @GetUser() user: LoginUserInfo,
    @Query('skip') skip?: string,
    @Query('take') take?: string,
    @Query('clienteId') clienteId?: string,
    @Query('estado') estado?: string,
    @Query('fechaDesde') fechaDesde?: string,
    @Query('fechaHasta') fechaHasta?: string,
    @Query('cobradorId') cobradorId?: string,
    @Query('cajaId') cajaId?: string,
    @Query('busqueda') busqueda?: string,
    @Query('modo') modo?: string,
    @Query('orderBy') orderBy?: string,
    @Query('order') order?: string,
  ) {
    return this.cobrosService.findAll(user.empresa_id, {
      skip: skip ? parseInt(skip, 10) : undefined,
      take: take ? parseInt(take, 10) : undefined,
      clienteId,
      estado,
      fechaDesde: fechaDesde ? new Date(fechaDesde) : undefined,
      fechaHasta: fechaHasta ? new Date(fechaHasta) : undefined,
      cobradorId,
      cajaId,
      busqueda,
      modo,
      orderBy,
      order: order === 'asc' ? 'asc' : order === 'desc' ? 'desc' : undefined,
    });
  }

  @Get('cajas-filtro')
  @RequirePermission('COBRANZAS', 'COB_REC_RECIBO_VER')
  @ApiOperation({ summary: 'Cajas con recibos, para el filtro de auditoría del listado' })
  getCajasFiltro(@GetUser() user: LoginUserInfo) {
    return this.cobrosService.cajasConRecibos(user.empresa_id);
  }

  @Get('facturas-credito/:clienteId')
  @RequirePermission('COBRANZAS', 'COB_REC_RECIBO_CREAR')
  @ApiOperation({ summary: 'Obtener facturas crédito pendientes de un cliente' })
  getFacturasCreditoPendientes(@Param('clienteId') clienteId: string, @GetUser() user: LoginUserInfo) {
    return this.cobrosService.getFacturasCreditoPendientes(clienteId, user.empresa_id);
  }

  @Get('cuotas-factura/:facturaId')
  @RequirePermission('COBRANZAS', 'COB_REC_RECIBO_CREAR')
  @ApiOperation({ summary: 'Obtener cuotas pendientes de una factura' })
  getCuotasPorFactura(@Param('facturaId') facturaId: string, @GetUser() user: LoginUserInfo) {
    return this.cobrosService.getCuotasPorFactura(facturaId, user.empresa_id);
  }

  @Get('cuotas-pendientes/:clienteId')
  @RequirePermission('COBRANZAS', 'COB_REC_RECIBO_CREAR')
  @ApiOperation({ summary: 'Obtener cuotas pendientes de un cliente' })
  getCuotasPendientes(@Param('clienteId') clienteId: string, @GetUser() user: LoginUserInfo) {
    return this.cobrosService.getCuotasPendientes(clienteId, user.empresa_id);
  }

  @Get('cliente/:clienteId')
  @RequirePermission('COBRANZAS', 'COB_REC_RECIBO_VER')
  @ApiOperation({ summary: 'Obtener recibos de cobro de un cliente' })
  findByCliente(@Param('clienteId') clienteId: string, @GetUser() user: LoginUserInfo) {
    return this.cobrosService.findByCliente(clienteId, user.empresa_id);
  }

  @Get('verificar-numeracion/:sucursalId')
  @RequirePermission('COBRANZAS', 'COB_REC_RECIBO_CREAR')
  @ApiOperation({ summary: 'Verificar si existe numeración activa para recibos de cobro en la sucursal' })
  verificarNumeracionRecibo(@Param('sucursalId') sucursalId: string, @GetUser() user: LoginUserInfo) {
    return this.cobrosService.verificarNumeracionRecibo(user.empresa_id, sucursalId);
  }

  @Get('morosidad/dashboard')
  @RequirePermission('COBRANZAS', 'COB_CC_CUENTA_COBRAR_VER')
  @ApiOperation({ summary: 'Dashboard de morosidad: proyección, cobrada, aging y top morosos (requiere submódulo ADM_INTERES_MORA)' })
  getDashboardMorosidad(@GetUser() user: LoginUserInfo) {
    return this.cobrosService.getDashboardMorosidad(user.empresa_id);
  }

  // ==================== HOJA DE RUTA ====================

  @Get('hoja-de-ruta/pdf')
  @RequirePermission('COBRANZAS', 'COB_HR_HOJA_RUTA_IMPRIMIR')
  @ApiOperation({ summary: 'Generar PDF de hoja de ruta por cobrador' })
  @ApiQuery({ name: 'cobrador_id', required: true })
  @ApiQuery({ name: 'tipo', required: false, enum: ['view', 'base64'] })
  async generateHojaDeRutaPdf(
    @GetUser() user: LoginUserInfo,
    @Query('cobrador_id') cobradorId: string,
    @Query('tipo') tipo?: string,
    @Res() res?: any,
  ) {
    const result = await this.cobrosService.generateHojaDeRutaPdf(user.empresa_id, cobradorId, {
      tipo_retorno: tipo || 'view',
    });

    if (result.base64) {
      return res.json({ status: 'success', pdf_base64: result.base64 });
    }

    res.set({
      'Content-Type': result.contentType,
      'Content-Disposition': `inline; filename="hoja-de-ruta-${cobradorId}.pdf"`,
      'Content-Length': result.pdfBuffer.length,
    });
    return res.send(result.pdfBuffer);
  }

  @Get('hoja-de-ruta')
  @RequirePermission('COBRANZAS', 'COB_HR_HOJA_RUTA_VER')
  @ApiOperation({ summary: 'Obtener hoja de ruta de un cobrador' })
  @ApiQuery({ name: 'cobrador_id', required: true })
  @ApiQuery({ name: 'estado', required: false, enum: ['todos', 'vencido', 'al_dia', 'sin_deuda', 'proximos', 'con_promesa'] })
  @ApiQuery({ name: 'dias_proximos', required: false, type: Number })
  getHojaDeRuta(
    @GetUser() user: LoginUserInfo,
    @Query('cobrador_id') cobradorId: string,
    @Query('estado') estado?: string,
    @Query('dias_proximos') diasProximos?: string,
  ) {
    return this.cobrosService.getHojaDeRuta(user.empresa_id, cobradorId, estado, diasProximos ? parseInt(diasProximos, 10) : undefined);
  }

  @Get('clientes-sin-cobrador')
  @RequirePermission('COBRANZAS', 'COB_ASG_ASIGNACION_VER')
  @ApiOperation({ summary: 'Clientes con cuentas a cobrar sin cobrador asignado' })
  getClientesSinCobrador(@GetUser() user: LoginUserInfo) {
    return this.cobrosService.getClientesSinCobrador(user.empresa_id);
  }

  @Patch('asignar-cobrador/:clienteId')
  @RequirePermission('COBRANZAS', 'COB_ASG_ASIGNACION_CREAR')
  @ApiOperation({ summary: 'Asignar cobrador a todas las facturas activas de un cliente' })
  asignarCobrador(
    @Param('clienteId') clienteId: string,
    @Body('cobrador_id') cobradorId: string,
    @GetUser() user: LoginUserInfo,
  ) {
    return this.cobrosService.asignarCobradorACliente(clienteId, cobradorId, user.empresa_id);
  }

  @Get('cuentas-cobrar/detalle-cliente/:clienteId')
  @RequirePermission('COBRANZAS', 'COB_CC_CUENTA_COBRAR_VER')
  @ApiOperation({ summary: 'Detalle extendido del cliente para tarjeta expandida en Panel Cobrador' })
  getDetalleClientePanelCobrador(@Param('clienteId') clienteId: string, @GetUser() user: LoginUserInfo) {
    return this.cobrosService.getDetalleClientePanelCobrador(clienteId, user.empresa_id);
  }

  // ==================== FIN HOJA DE RUTA ====================

  @Get(':id/print-data')
  @RequirePermission('COBRANZAS', 'COB_REC_RECIBO_VER')
  @ApiOperation({ summary: 'Obtener datos del recibo optimizados para impresión térmica ESC/POS' })
  @ApiQuery({ name: 'paper_width', required: false, enum: ['58', '80'], description: 'Ancho de papel en mm (default: 80)' })
  getReciboPrintData(
    @Param('id') id: string,
    @GetUser() user: LoginUserInfo,
    @Query('paper_width') paperWidth?: string,
  ) {
    return this.cobrosService.getReciboPrintData(id, user.empresa_id, {
      paperWidth: paperWidth ? parseInt(paperWidth, 10) : 80,
    });
  }

  @Get(':id/pdf')
  @RequirePermission('COBRANZAS', 'COB_REC_RECIBO_VER')
  @ApiOperation({ summary: 'Generar PDF de un recibo de cobro (A4 o ticket)' })
  @ApiQuery({ name: 'formato', required: false, enum: ['a4', 'ticket'], description: 'Formato del PDF: a4 (default) o ticket' })
  @ApiQuery({ name: 'tipo', required: false, enum: ['view', 'base64'], description: 'Tipo de respuesta: view (binary PDF) o base64' })
  async generatePdf(
    @Param('id') id: string,
    @GetUser() user: LoginUserInfo,
    @Query('formato') formato?: string,
    @Query('tipo') tipo?: string,
    @Query('paper_width') paperWidth?: string,
    @Res() res?: any,
  ) {
    const result = await this.cobrosService.generateReciboPdf(id, user.empresa_id, {
      formato: formato || 'a4',
      tipo_retorno: tipo || 'view',
      ancho_papel: paperWidth ? Number(paperWidth) : 80,
    });

    if (result.base64) {
      return res.json({ status: 'success', pdf_base64: result.base64 });
    }

    res.set({
      'Content-Type': 'application/pdf',
      'Content-Disposition': `inline; filename="recibo-${id}.pdf"`,
      'Content-Length': result.pdfBuffer.length,
    });
    return res.send(result.pdfBuffer);
  }

  @Get(':id')
  @RequirePermission('COBRANZAS', 'COB_REC_RECIBO_VER')
  @ApiOperation({ summary: 'Obtener un recibo de cobro por ID' })
  findOne(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.cobrosService.findOne(id, user.empresa_id);
  }

  @Patch(':id')
  @RequirePermission('COBRANZAS', 'COB_REC_RECIBO_EDITAR')
  @ApiOperation({ summary: 'Actualizar un recibo de cobro' })
  update(@Param('id') id: string, @Body() updateReciboCobroDto: UpdateReciboCobroDto, @GetUser() user: LoginUserInfo) {
    return this.cobrosService.update(id, updateReciboCobroDto, user.empresa_id, user.id);
  }

  @Patch(':id/anular')
  @RequirePermission('COBRANZAS', 'COB_REC_RECIBO_ANULAR')
  @ApiOperation({ summary: 'Anular un recibo de cobro' })
  anular(@Param('id') id: string, @Body('observacion') observacion?: string, @GetUser() user?: LoginUserInfo) {
    return this.cobrosService.anular(id, observacion, user?.empresa_id, user?.id);
  }

  @Patch(':id/fecha')
  @RequirePermission('COBRANZAS', 'COB_REC_RECIBO_EDITAR')
  @ApiOperation({ summary: 'Modificar la fecha de registro de un recibo' })
  actualizarFecha(
    @Param('id') id: string,
    @Body('fecha_registro') fecha_registro: string,
    @Body('motivo') motivo: string,
    @GetUser() user: LoginUserInfo,
  ) {
    return this.cobrosService.actualizarFecha(id, fecha_registro, motivo, user.empresa_id, user.id);
  }

  @Post(':id/reintentar-emision-intereses')
  @RequirePermission('COBRANZAS', 'COB_REC_RECIBO_CREAR')
  @ApiOperation({
    summary:
      'Reintentar la emisión SIFEN de la factura por intereses moratorios del recibo (luego de corregir datos del cliente)',
  })
  reintentarEmisionIntereses(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.cobrosService.reintentarEmisionIntereses(id, user.empresa_id, user.id);
  }

  // ==================== DISTRIBUCIÓN AUTOMÁTICA DE PAGOS ====================

  @Post('preview-distribucion')
  @RequirePermission('COBRANZAS', 'COB_REC_RECIBO_CREAR')
  @ApiOperation({ summary: 'Preview de distribución automática de pago entre cuotas' })
  previewDistribucion(@Body() dto: PreviewDistribucionDto, @GetUser() user: LoginUserInfo) {
    return this.cobrosService.previewDistribucion(dto, user.empresa_id);
  }

  @Post('crear-desde-distribucion')
  @RequirePermission('COBRANZAS', 'COB_REC_RECIBO_CREAR')
  @ApiOperation({ summary: 'Crear cobro usando distribución automática' })
  createFromDistribucion(
    @Body()
    body: {
      distribucion: PreviewDistribucionDto;
      sucursal_id: string;
      cliente_id: string;
      sesion_caja_id?: string;
      observacion?: string;
      cobrador_id?: string;
      fecha_registro?: string;
      fecha_emision?: string;
      numero_cheque?: string;
      banco_emisor?: string;
      banco_id?: string;
      exoneraciones_intereses?: Array<{
        factura_cuota_id: string;
        monto_exonerado: number;
        autorizacion_descuento_id?: string | null;
      }>;
    },
    @GetUser() user: LoginUserInfo,
  ) {
    return this.cobrosService.createFromDistribucion(
      body.distribucion,
      body.sucursal_id,
      body.cliente_id,
      body.sesion_caja_id || null,
      user.id,
      user.empresa_id,
      body.observacion,
      body.cobrador_id,
      body.fecha_registro,
      body.numero_cheque,
      body.banco_emisor,
      body.banco_id,
      body.fecha_emision,
      body.exoneraciones_intereses,
    );
  }

  // ==================== GESTIÓN DE CUENTAS A COBRAR ====================

  @Get('cuentas-cobrar/dashboard')
  @RequirePermission('COBRANZAS', 'COB_CC_CUENTA_COBRAR_VER')
  @ApiOperation({ summary: 'Dashboard de cuentas a cobrar con aging buckets y semáforos' })
  getCuentasCobrarDashboard(@GetUser() user: LoginUserInfo) {
    return this.cobrosService.getCuentasCobrarDashboard(user.empresa_id, user.id);
  }

  @Get('cuentas-cobrar/resumen')
  @RequirePermission('COBRANZAS', 'COB_CC_CUENTA_COBRAR_VER')
  @ApiOperation({ summary: 'Obtener resumen de cuentas a cobrar con todas las cuotas pendientes' })
  getCuentasCobrarResumen(@GetUser() user: LoginUserInfo) {
    return this.cobrosService.getCuentasCobrarResumen(user.empresa_id);
  }

  @Get('cuentas-cobrar/por-cliente')
  @RequirePermission('COBRANZAS', 'COB_CC_CUENTA_COBRAR_VER')
  @ApiOperation({ summary: 'Obtener cuentas a cobrar agrupadas por cliente' })
  @ApiQuery({ name: 'categoriaId', required: false, description: 'Filtra clientes que tengan ≥1 factura con producto de esa categoría' })
  getCuentasCobrarPorCliente(
    @GetUser() user: LoginUserInfo,
    @Query('categoriaId') categoriaId?: string,
  ) {
    return this.cobrosService.getCuentasCobrarPorCliente(user.empresa_id, { categoriaId });
  }

  @Get('reportes/cierre-cobros')
  @RequirePermission('COBRANZAS', 'COB_CC_CUENTA_COBRAR_VER')
  @ApiOperation({ summary: 'Reporte de cierre de cobros — por día, medios de pago y condición de pago' })
  @ApiQuery({ name: 'fechaDesde', required: false })
  @ApiQuery({ name: 'fechaHasta', required: false })
  @ApiQuery({ name: 'cobradorId', required: false })
  @ApiQuery({ name: 'sucursalId', required: false })
  @ApiQuery({ name: 'monedaId',   required: false })
  getCierreCobros(
    @GetUser() user: LoginUserInfo,
    @Query('fechaDesde') fechaDesde?: string,
    @Query('fechaHasta') fechaHasta?: string,
    @Query('cobradorId') cobradorId?: string,
    @Query('sucursalId') sucursalId?: string,
    @Query('monedaId') monedaId?: string,
  ) {
    return this.cobrosService.getCierreCobros(user.empresa_id, {
      fechaDesde, fechaHasta, cobradorId, sucursalId, monedaId,
    });
  }

  @Get('reportes/cierre-cobros/pdf')
  @RequirePermission('COBRANZAS', 'COB_CC_CUENTA_COBRAR_VER')
  @ApiOperation({ summary: 'PDF (msv-kude) del cierre de cobros' })
  async getCierreCobrosPdf(
    @GetUser() user: LoginUserInfo,
    @Res() res: Response,
    @Query('fechaDesde') fechaDesde?: string,
    @Query('fechaHasta') fechaHasta?: string,
    @Query('cobradorId') cobradorId?: string,
    @Query('sucursalId') sucursalId?: string,
    @Query('monedaId') monedaId?: string,
  ) {
    const pdfBuffer = await this.cobrosService.exportarCierreCobrosPDF(user.empresa_id, {
      fechaDesde, fechaHasta, cobradorId, sucursalId, monedaId,
    });
    res.setHeader('Content-Type', 'application/pdf');
    res.setHeader('Content-Disposition', 'inline; filename="cierre-cobros.pdf"');
    res.setHeader('Content-Length', pdfBuffer.length);
    res.send(pdfBuffer);
  }

  @Get('cuentas-cobrar/detalle-mensual-facturas/pdf')
  @RequirePermission('COBRANZAS', 'COB_CC_CUENTA_COBRAR_VER')
  @ApiOperation({ summary: 'PDF (msv-kude) del detalle mensual de pagos por factura' })
  @ApiQuery({ name: 'categoriaId',  required: false })
  @ApiQuery({ name: 'fechaCorte',   required: false })
  @ApiQuery({ name: 'fechaDesde',   required: false })
  @ApiQuery({ name: 'fechaHasta',   required: false })
  @ApiQuery({ name: 'soloConSaldo', required: false })
  async getDetalleMensualFacturasPdf(
    @GetUser() user: LoginUserInfo,
    @Res() res: Response,
    @Query('categoriaId') categoriaId?: string,
    @Query('fechaCorte') fechaCorte?: string,
    @Query('fechaDesde') fechaDesde?: string,
    @Query('fechaHasta') fechaHasta?: string,
    @Query('soloConSaldo') soloConSaldo?: string,
  ) {
    const pdfBuffer = await this.cobrosService.exportarDetalleMensualPDF(user.empresa_id, {
      categoriaId,
      fechaCorte,
      fechaDesde,
      fechaHasta,
      soloConSaldo: soloConSaldo === 'true',
    });
    res.setHeader('Content-Type', 'application/pdf');
    res.setHeader('Content-Disposition', 'inline; filename="detalle-mensual-cxc.pdf"');
    res.setHeader('Content-Length', pdfBuffer.length);
    res.send(pdfBuffer);
  }

  @Get('cuentas-cobrar/detalle-mensual-facturas')
  @RequirePermission('COBRANZAS', 'COB_CC_CUENTA_COBRAR_VER')
  @ApiOperation({ summary: 'Detalle mensual de pagos por factura (para Excel). Filtros: categoría, fecha corte, fecha desde/hasta' })
  @ApiQuery({ name: 'categoriaId',  required: false })
  @ApiQuery({ name: 'fechaCorte',   required: false, description: 'YYYY-MM-DD — saldo se calcula restando pagos hasta esa fecha' })
  @ApiQuery({ name: 'fechaDesde',   required: false, description: 'YYYY-MM-DD — filtra facturas emitidas desde' })
  @ApiQuery({ name: 'fechaHasta',   required: false, description: 'YYYY-MM-DD — filtra facturas emitidas hasta' })
  @ApiQuery({ name: 'soloConSaldo', required: false, description: 'true = solo facturas con saldo > 0 al corte' })
  getDetalleMensualFacturas(
    @GetUser() user: LoginUserInfo,
    @Query('categoriaId') categoriaId?: string,
    @Query('fechaCorte') fechaCorte?: string,
    @Query('fechaDesde') fechaDesde?: string,
    @Query('fechaHasta') fechaHasta?: string,
    @Query('soloConSaldo') soloConSaldo?: string,
  ) {
    return this.cobrosService.getDetalleMensualFacturas(user.empresa_id, {
      categoriaId,
      fechaCorte,
      fechaDesde,
      fechaHasta,
      soloConSaldo: soloConSaldo === 'true',
    });
  }

  @Get('cuentas-cobrar/cobros-cliente/:clienteId')
  @RequirePermission('COBRANZAS', 'COB_CC_CUENTA_COBRAR_VER')
  @ApiOperation({ summary: 'Historial de cobros registrados para un cliente' })
  getCobrosHistorialCliente(@GetUser() user: LoginUserInfo, @Param('clienteId') clienteId: string) {
    return this.cobrosService.getCobrosHistorialCliente(user.empresa_id, clienteId);
  }

  @Get('cuentas-cobrar/estado-cuenta/:clienteId')
  @RequirePermission('COBRANZAS', 'COB_CC_CUENTA_COBRAR_VER')
  @ApiOperation({ summary: 'Obtener estado de cuenta de un cliente (JSON)' })
  getEstadoCuentaCliente(@GetUser() user: LoginUserInfo, @Param('clienteId') clienteId: string) {
    return this.cobrosService.getEstadoCuentaCliente(user.empresa_id, clienteId, { usuarioId: user.id });
  }

  @Get('cuentas-cobrar/por-cliente/:clienteId')
  @RequirePermission('COBRANZAS', 'COB_CC_CUENTA_COBRAR_VER')
  @ApiOperation({ summary: 'Obtener cuentas a cobrar de un cliente con sus cuotas' })
  getCuentasCobrarByCliente(@Param('clienteId') clienteId: string, @GetUser() user: LoginUserInfo) {
    return this.cobrosService.getCuentasCobrarByCliente(clienteId, user.empresa_id);
  }

  @Patch('cuentas-cobrar/:id')
  @RequirePermission('COBRANZAS', 'COB_CC_CUENTA_COBRAR_EDITAR')
  @ApiOperation({ summary: 'Actualizar saldo pendiente de una cuenta a cobrar' })
  updateCuentaCobrar(
    @Param('id') id: string,
    @Body('saldo_pendiente') saldoPendiente: number,
    @Body('revisado') revisado: boolean,
    @Body('motivo') motivo: string | undefined,
    @GetUser() user: LoginUserInfo,
  ) {
    return this.cobrosService.updateCuentaCobrar(id, user.empresa_id, saldoPendiente, revisado, user.id, motivo);
  }

  @Get('condiciones-pago')
  @RequirePermission('COBRANZAS', 'COB_REC_RECIBO_VER')
  @ApiOperation({ summary: 'Listar condiciones de pago activas de la empresa' })
  getCondicionesPago(@GetUser() user: LoginUserInfo) {
    return this.cobrosService.getCondicionesPago(user.empresa_id);
  }

  @Post('cuentas-cobrar/:id/marcar-pagada')
  @RequirePermission('COBRANZAS', 'COB_CC_CUENTA_COBRAR_EDITAR')
  @ApiOperation({ summary: 'Marcar una cuenta a cobrar como pagada (ajuste manual)' })
  marcarComoPagada(
    @Param('id') id: string,
    @Body('motivo') motivo: string | undefined,
    @GetUser() user: LoginUserInfo,
  ) {
    return this.cobrosService.marcarComoPagada(id, user.empresa_id, user.id, motivo);
  }

  @Post('cuentas-cobrar/:id/regenerar-cuotas')
  @RequirePermission('COBRANZAS', 'COB_CC_CUENTA_COBRAR_EDITAR')
  @ApiOperation({ summary: 'Eliminar cuotas pendientes y regenerar nuevas cuotas' })
  regenerarCuotas(
    @Param('id') id: string,
    @Body() body: { monto_cuota: number; frecuencia: 'semanal' | 'quincenal' | 'mensual'; fecha_primer_vencimiento: string; forzar?: boolean; motivo?: string },
    @GetUser() user: LoginUserInfo,
  ) {
    return this.cobrosService.regenerarCuotas(id, user.empresa_id, body, user.id);
  }

  @Get('cuentas-cobrar/estado-cuenta/:clienteId/pdf')
  @RequirePermission('COBRANZAS', 'COB_CC_CUENTA_COBRAR_VER')
  @ApiOperation({ summary: 'Generar PDF de estado de cuenta de un cliente' })
  @ApiQuery({ name: 'tipo', required: false, enum: ['view', 'base64'] })
  @ApiQuery({ name: 'formato', required: false, enum: ['a4', 'a4-detallado', 'historial'] })
  @ApiQuery({ name: 'incluir_todas', required: false, description: 'Incluir cuotas no vencidas' })
  async generateEstadoCuentaPdf(
    @GetUser() user: LoginUserInfo,
    @Param('clienteId') clienteId: string,
    @Query('tipo') tipo?: string,
    @Query('formato') formato?: string,
    @Query('incluir_todas') incluirTodas?: string,
    @Res() res?: any,
  ) {
    const result = await this.cobrosService.generateEstadoCuentaPdf(user.empresa_id, clienteId, {
      tipo_retorno: tipo || 'view',
      formato: formato || 'a4',
      incluir_todas: incluirTodas === 'true' || incluirTodas === '1',
      usuarioId: user.id,
    });

    if (result.base64) {
      return res.json({ status: 'success', pdf_base64: result.base64 });
    }

    res.set({
      'Content-Type': result.contentType,
      'Content-Disposition': `inline; filename="estado-cuenta-${clienteId}.pdf"`,
      'Content-Length': result.pdfBuffer.length,
    });
    return res.send(result.pdfBuffer);
  }
}
