import { Body, Controller, Delete, Get, Param, Patch, Post, Query, Req, Res, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiBearerAuth, ApiOperation, ApiQuery, ApiTags } from '@nestjs/swagger';
import { Response } from 'express';
import { GetUser } from '../auth/get-user.decorator';
import { RequireModule, RequirePermission } from '../auth/decorators';
import { ModuleGuard } from '../auth/guards/module.guard';
import { PermissionGuard } from '../auth/guards/permission.guard';
import { AsignacionFacturasService } from './asignacion-facturas.service';

@ApiTags('Asignación de Facturas')
@ApiBearerAuth()
@UseGuards(AuthGuard('jwt'), ModuleGuard, PermissionGuard)
@RequireModule('COBRANZAS')
@Controller('asignacion-facturas')
export class AsignacionFacturasController {
  constructor(private readonly asignacionService: AsignacionFacturasService) {}

  @Get('pendientes')
  @RequirePermission('COBRANZAS', 'COB_ASG_ASIGNACION_VER')
  @ApiOperation({ summary: 'Obtener facturas pendientes de cobro (paginado)' })
  @ApiQuery({ name: 'cobrador_id', required: false })
  @ApiQuery({ name: 'vendedor_id', required: false })
  @ApiQuery({ name: 'cliente_id', required: false })
  @ApiQuery({ name: 'moneda_id', required: false })
  @ApiQuery({ name: 'sin_asignar', required: false, type: Boolean })
  @ApiQuery({ name: 'asignadas', required: false, type: Boolean })
  @ApiQuery({ name: 'search', required: false })
  @ApiQuery({ name: 'fechaDesde', required: false })
  @ApiQuery({ name: 'fechaHasta', required: false })
  @ApiQuery({ name: 'page', required: false, type: Number })
  @ApiQuery({ name: 'limit', required: false, type: Number })
  async getFacturasPendientes(
    @GetUser() user: any,
    @Query('cobrador_id') cobrador_id?: string,
    @Query('vendedor_id') vendedor_id?: string,
    @Query('cliente_id') cliente_id?: string,
    @Query('moneda_id') moneda_id?: string,
    @Query('sin_asignar') sin_asignar?: string,
    @Query('asignadas') asignadas?: string,
    @Query('search') search?: string,
    @Query('fechaDesde') fechaDesde?: string,
    @Query('fechaHasta') fechaHasta?: string,
    @Query('page') page?: string,
    @Query('limit') limit?: string,
  ) {
    return this.asignacionService.getFacturasPendientes(user.empresa_id, {
      cobrador_id,
      vendedor_id,
      cliente_id,
      moneda_id,
      sin_asignar: sin_asignar === 'true',
      asignadas: asignadas === 'true',
      search: search || undefined,
      fechaDesde: fechaDesde || undefined,
      fechaHasta: fechaHasta || undefined,
      page: page ? parseInt(page, 10) : 1,
      limit: limit ? parseInt(limit, 10) : 100,
    });
  }

  @Post()
  @RequirePermission('COBRANZAS', 'COB_ASG_ASIGNACION_CREAR')
  @ApiOperation({ summary: 'Asignar una factura a un cobrador' })
  async asignarCobrador(
    @GetUser() user: any,
    @Body() body: { factura_id: string; cobrador_id: string; notas?: string },
  ) {
    return this.asignacionService.asignarCobrador(
      user.empresa_id,
      body.factura_id,
      body.cobrador_id,
      user.id,
      body.notas,
    );
  }

  @Post('masivo')
  @RequirePermission('COBRANZAS', 'COB_ASG_ASIGNACION_CREAR')
  @ApiOperation({ summary: 'Asignar múltiples facturas a un cobrador' })
  async asignarCobradorMasivo(
    @GetUser() user: any,
    @Body() body: { factura_ids: string[]; cobrador_id: string; notas?: string },
  ) {
    return this.asignacionService.asignarCobradorMasivo(
      user.empresa_id,
      body.factura_ids,
      body.cobrador_id,
      user.id,
      body.notas,
    );
  }

  @Get('cobrador/:cobradorId')
  @RequirePermission('COBRANZAS', 'COB_ASG_ASIGNACION_VER')
  @ApiOperation({ summary: 'Obtener asignaciones de un cobrador' })
  @ApiQuery({ name: 'estado', required: false })
  async getAsignacionesCobrador(
    @GetUser() user: any,
    @Param('cobradorId') cobradorId: string,
    @Query('estado') estado?: string,
  ) {
    return this.asignacionService.getAsignacionesCobrador(user.empresa_id, cobradorId, estado);
  }

  @Patch(':id/estado')
  @RequirePermission('COBRANZAS', 'COB_ASG_ASIGNACION_CREAR')
  @ApiOperation({ summary: 'Actualizar estado de una asignación' })
  async updateEstadoAsignacion(
    @GetUser() user: any,
    @Param('id') id: string,
    @Body() body: { estado: string; notas?: string },
  ) {
    return this.asignacionService.updateEstadoAsignacion(user.empresa_id, id, body.estado, body.notas);
  }

  @Get('resumen-cobradores')
  @RequirePermission('COBRANZAS', 'COB_ASG_ASIGNACION_VER')
  @ApiOperation({ summary: 'Obtener resumen de facturas por cobrador' })
  async getResumenCobradores(@GetUser() user: any) {
    return this.asignacionService.getResumenCobradores(user.empresa_id);
  }

  @Post('vendedor')
  @RequirePermission('COBRANZAS', 'COB_ASG_ASIGNACION_CREAR')
  @ApiOperation({ summary: 'Asignar vendedor a una factura' })
  async asignarVendedor(@GetUser() user: any, @Body() body: { factura_id: string; vendedor_id: string }) {
    return this.asignacionService.asignarVendedor(user.empresa_id, body.factura_id, body.vendedor_id, user.id);
  }

  @Get('resumen-comisiones')
  @RequirePermission('COBRANZAS', 'COB_COM_COMISION_VER')
  @ApiOperation({ summary: 'Obtener resumen de comisiones por vendedor/cobrador' })
  @ApiQuery({ name: 'fecha_desde', required: false, description: 'Fecha desde (YYYY-MM-DD)' })
  @ApiQuery({ name: 'fecha_hasta', required: false, description: 'Fecha hasta (YYYY-MM-DD)' })
  @ApiQuery({ name: 'moneda_id', required: false, description: 'ID de la moneda para filtrar' })
  async getResumenComisiones(
    @GetUser() user: any,
    @Query('fecha_desde') fechaDesde?: string,
    @Query('fecha_hasta') fechaHasta?: string,
    @Query('moneda_id') monedaId?: string,
  ) {
    const desde = fechaDesde ? new Date(fechaDesde) : undefined;
    const hasta = fechaHasta ? new Date(fechaHasta + 'T23:59:59') : undefined;
    return this.asignacionService.getResumenComisiones(user.empresa_id, desde, hasta, monedaId);
  }

  @Post('generar-comisiones')
  @RequirePermission('COBRANZAS', 'COB_COM_COMISION_GENERAR')
  @ApiOperation({ summary: 'Generar comisiones para facturas ya asignadas que no tienen comisión' })
  async generarComisionesFacturasExistentes(@GetUser() user: any) {
    return this.asignacionService.generarComisionesFacturasExistentes(user.empresa_id);
  }

  @Get('comisiones-detalle')
  @RequirePermission('COBRANZAS', 'COB_COM_COMISION_VER')
  @ApiOperation({ summary: 'Detalle de comisiones generadas para un vendedor/cobrador' })
  @ApiQuery({ name: 'vendedor_cobrador_id', required: true })
  @ApiQuery({ name: 'fecha_desde', required: false })
  @ApiQuery({ name: 'fecha_hasta', required: false })
  @ApiQuery({ name: 'moneda_id', required: false })
  async getComisionesDetalle(
    @GetUser() user: any,
    @Query('vendedor_cobrador_id') vendedorCobradorId: string,
    @Query('fecha_desde') fechaDesde?: string,
    @Query('fecha_hasta') fechaHasta?: string,
    @Query('moneda_id') monedaId?: string,
  ) {
    const desde = fechaDesde ? new Date(fechaDesde) : undefined;
    const hasta = fechaHasta ? new Date(fechaHasta + 'T23:59:59') : undefined;
    return this.asignacionService.getComisionesDetalle(user.empresa_id, vendedorCobradorId, desde, hasta, monedaId);
  }

  @Get('resumen-comisiones/pdf')
  @RequirePermission('COBRANZAS', 'COB_COM_COMISION_VER')
  @ApiOperation({ summary: 'PDF con el resumen de comisiones por vendedor/cobrador' })
  @ApiQuery({ name: 'fecha_desde', required: false })
  @ApiQuery({ name: 'fecha_hasta', required: false })
  @ApiQuery({ name: 'moneda_id', required: false })
  async getResumenComisionesPdf(
    @GetUser() user: any,
    @Res() res: Response,
    @Query('fecha_desde') fechaDesde?: string,
    @Query('fecha_hasta') fechaHasta?: string,
    @Query('moneda_id') monedaId?: string,
  ) {
    const desde = fechaDesde ? new Date(fechaDesde) : undefined;
    const hasta = fechaHasta ? new Date(fechaHasta + 'T23:59:59') : undefined;
    const pdf = await this.asignacionService.comisionesResumenPdf(user.empresa_id, desde, hasta, monedaId);
    res.setHeader('Content-Type', 'application/pdf');
    res.setHeader('Content-Disposition', 'inline; filename="comisiones-resumen.pdf"');
    res.end(pdf);
  }

  @Get('comisiones-detalle/pdf')
  @RequirePermission('COBRANZAS', 'COB_COM_COMISION_VER')
  @ApiOperation({ summary: 'PDF con el detalle de comisiones por vendedor/cobrador y operación' })
  @ApiQuery({ name: 'fecha_desde', required: false })
  @ApiQuery({ name: 'fecha_hasta', required: false })
  @ApiQuery({ name: 'moneda_id', required: false })
  async getComisionesDetallePdf(
    @GetUser() user: any,
    @Res() res: Response,
    @Query('fecha_desde') fechaDesde?: string,
    @Query('fecha_hasta') fechaHasta?: string,
    @Query('moneda_id') monedaId?: string,
  ) {
    const desde = fechaDesde ? new Date(fechaDesde) : undefined;
    const hasta = fechaHasta ? new Date(fechaHasta + 'T23:59:59') : undefined;
    const pdf = await this.asignacionService.comisionesDetallePdf(user.empresa_id, desde, hasta, monedaId);
    res.setHeader('Content-Type', 'application/pdf');
    res.setHeader('Content-Disposition', 'inline; filename="comisiones-detalle.pdf"');
    res.end(pdf);
  }

  @Delete('comisiones/:id')
  @RequirePermission('COBRANZAS', 'COB_COM_COMISION_ELIMINAR')
  @ApiOperation({ summary: 'Eliminar una comisión pendiente (no liquidada)' })
  async eliminarComision(@GetUser() user: any, @Param('id') id: string, @Req() req: any) {
    return this.asignacionService.eliminarComision(user.empresa_id, id, user.id, {
      ip: req.ip,
      userAgent: req.headers['user-agent'],
    });
  }
}
