import { Body, Controller, Get, Param, Patch, Post, Query, Res, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiBearerAuth, ApiOperation, ApiQuery, ApiTags } from '@nestjs/swagger';
import type { 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 { LiquidacionesService } from './liquidaciones.service';

@ApiTags('Liquidaciones de Comisiones')
@ApiBearerAuth()
@UseGuards(AuthGuard('jwt'), ModuleGuard, PermissionGuard)
@RequireModule('COBRANZAS')
@Controller('liquidaciones')
export class LiquidacionesController {
  constructor(private readonly liquidacionesService: LiquidacionesService) {}

  @Get('comisiones-pendientes')
  @RequirePermission('COBRANZAS', 'COB_COM_COMISION_VER')
  @ApiOperation({ summary: 'Obtener comisiones pendientes de liquidar' })
  @ApiQuery({ name: 'vendedor_cobrador_id', required: false })
  async getComisionesPendientes(
    @GetUser() user: any,
    @Query('vendedor_cobrador_id') vendedorCobradorId?: string,
  ) {
    return this.liquidacionesService.getComisionesPendientes(user.empresa_id, vendedorCobradorId);
  }

  @Get('resumen')
  @RequirePermission('COBRANZAS', 'COB_COM_COMISION_VER')
  @ApiQuery({ name: 'moneda_id', required: false })
  @ApiOperation({ summary: 'Obtener resumen de comisiones por vendedor/cobrador' })
  async getResumenComisiones(@GetUser() user: any, @Query('moneda_id') monedaId?: string) {
    return this.liquidacionesService.getResumenComisiones(user.empresa_id, monedaId);
  }

  @Get()
  @RequirePermission('COBRANZAS', 'COB_COM_LIQUIDACION_VER')
  @ApiOperation({ summary: 'Listar liquidaciones' })
  @ApiQuery({ name: 'vendedor_cobrador_id', required: false })
  @ApiQuery({ name: 'estado', required: false })
  @ApiQuery({ name: 'tipo', required: false, enum: ['vendedor', 'supervisor'] })
  async getLiquidaciones(
    @GetUser() user: any,
    @Query('vendedor_cobrador_id') vendedorCobradorId?: string,
    @Query('estado') estado?: string,
    @Query('tipo') tipo?: string,
  ) {
    return this.liquidacionesService.getLiquidaciones(user.empresa_id, {
      vendedor_cobrador_id: vendedorCobradorId,
      estado,
      tipo,
    });
  }

  @Get('lista/pdf')
  @RequirePermission('COBRANZAS', 'COB_COM_LIQUIDACION_VER')
  @ApiOperation({ summary: 'PDF del historial de liquidaciones (filtrado)' })
  @ApiQuery({ name: 'vendedor_cobrador_id', required: false })
  @ApiQuery({ name: 'estado', required: false })
  @ApiQuery({ name: 'moneda_id', required: false })
  async getLiquidacionesListaPdf(
    @GetUser() user: any,
    @Res() res: Response,
    @Query('vendedor_cobrador_id') vendedorCobradorId?: string,
    @Query('estado') estado?: string,
    @Query('moneda_id') monedaId?: string,
  ) {
    const pdf = await this.liquidacionesService.liquidacionesListaPdf(user.empresa_id, {
      vendedor_cobrador_id: vendedorCobradorId,
      estado,
      moneda_id: monedaId,
    });
    res.setHeader('Content-Type', 'application/pdf');
    res.setHeader('Content-Disposition', 'inline; filename="liquidaciones-historial.pdf"');
    res.end(pdf);
  }

  @Get(':id/pdf')
  @RequirePermission('COBRANZAS', 'COB_COM_LIQUIDACION_VER')
  @ApiOperation({ summary: 'PDF comprobante de una liquidación' })
  async getLiquidacionPdf(@GetUser() user: any, @Res() res: Response, @Param('id') id: string) {
    const pdf = await this.liquidacionesService.liquidacionComprobantePdf(user.empresa_id, id);
    res.setHeader('Content-Type', 'application/pdf');
    res.setHeader('Content-Disposition', `inline; filename="liquidacion-${id.slice(0, 8)}.pdf"`);
    res.end(pdf);
  }

  @Get(':id')
  @RequirePermission('COBRANZAS', 'COB_COM_LIQUIDACION_VER')
  @ApiOperation({ summary: 'Obtener detalle de una liquidación' })
  async getLiquidacionDetalle(@GetUser() user: any, @Param('id') id: string) {
    return this.liquidacionesService.getLiquidacionDetalle(user.empresa_id, id);
  }

  @Post()
  @RequirePermission('COBRANZAS', 'COB_COM_LIQUIDACION_GENERAR')
  @ApiOperation({ summary: 'Crear una liquidación de comisiones' })
  async crearLiquidacion(
    @GetUser() user: any,
    @Body()
    body: {
      vendedor_cobrador_id: string;
      periodo_desde: string;
      periodo_hasta: string;
      observaciones?: string;
    },
  ) {
    return this.liquidacionesService.crearLiquidacion(
      user.empresa_id,
      body.vendedor_cobrador_id,
      new Date(body.periodo_desde),
      new Date(body.periodo_hasta),
      body.observaciones,
    );
  }

  @Patch(':id/pagar')
  @RequirePermission('COBRANZAS', 'COB_COM_LIQUIDACION_PAGAR')
  @ApiOperation({ summary: 'Marcar liquidación como pagada' })
  async marcarComoPagada(
    @GetUser() user: any,
    @Param('id') id: string,
    @Body() body: { fecha_pago?: string },
  ) {
    return this.liquidacionesService.marcarComoPagada(
      user.empresa_id,
      id,
      body.fecha_pago ? new Date(body.fecha_pago) : undefined,
    );
  }

  @Patch(':id/anular')
  @RequirePermission('COBRANZAS', 'COB_COM_LIQUIDACION_ANULAR')
  @ApiOperation({ summary: 'Anular una liquidación' })
  async anularLiquidacion(@GetUser() user: any, @Param('id') id: string) {
    return this.liquidacionesService.anularLiquidacion(user.empresa_id, id);
  }

  @Post('generar-comision-venta')
  @RequirePermission('COBRANZAS', 'COB_COM_COMISION_GENERAR')
  @ApiOperation({ summary: 'Generar comisión por venta (uso interno)' })
  async generarComisionVenta(
    @GetUser() user: any,
    @Body()
    body: {
      factura_id: string;
      vendedor_cobrador_id: string;
      monto_base: number;
    },
  ) {
    return this.liquidacionesService.generarComisionVenta(
      user.empresa_id,
      body.factura_id,
      body.vendedor_cobrador_id,
      body.monto_base,
    );
  }

  @Post('generar-comision-cobranza')
  @RequirePermission('COBRANZAS', 'COB_COM_COMISION_GENERAR')
  @ApiOperation({ summary: 'Generar comisión por cobranza (uso interno)' })
  async generarComisionCobranza(
    @GetUser() user: any,
    @Body()
    body: {
      factura_id: string;
      cobrador_id: string;
      monto_cobrado: number;
    },
  ) {
    return this.liquidacionesService.generarComisionCobranza(
      user.empresa_id,
      body.factura_id,
      body.cobrador_id,
      body.monto_cobrado,
    );
  }
}
