import { Body, Controller, Get, Param, Patch, Post, Query, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiBearerAuth, ApiOperation, 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 {
  CancelarPromesaDto,
  CreatePromesaMultiFacturaDto,
  CreatePromesaPagoDto,
  QueryPromesasDto,
  RenegociarPromesaDto,
  UpdatePromesaEstadoDto,
} from './dto/cobranzas.dto';
import { PromesasService } from './promesas.service';

@ApiTags('Promesas de Pago')
@ApiBearerAuth()
@UseGuards(AuthGuard('jwt'), ModuleGuard, PermissionGuard)
@RequireModule('COBRANZAS')
@Controller({ path: 'promesas-pago', version: '1' })
export class PromesasController {
  constructor(private readonly promesasService: PromesasService) {}

  @Post()
  @RequirePermission('COBRANZAS', 'COB_PRM_PROMESA_CREAR')
  @ApiOperation({ summary: 'Registrar promesa de pago de un cliente' })
  create(@Body() dto: CreatePromesaPagoDto, @GetUser() user: LoginUserInfo) {
    return this.promesasService.create(dto, user.empresa_id, user.id);
  }

  @Post('multi-factura')
  @RequirePermission('COBRANZAS', 'COB_PRM_PROMESA_CREAR')
  @ApiOperation({ summary: 'Registrar promesa que cubre varias facturas' })
  createMultiFactura(@Body() dto: CreatePromesaMultiFacturaDto, @GetUser() user: LoginUserInfo) {
    return this.promesasService.createMultiFactura(dto, user.empresa_id, user.id);
  }

  @Get()
  @RequirePermission('COBRANZAS', 'COB_PRM_PROMESA_VER')
  @ApiOperation({ summary: 'Listar promesas de pago con filtros' })
  findAll(@Query() query: QueryPromesasDto, @GetUser() user: LoginUserInfo) {
    return this.promesasService.findAll(user.empresa_id, query);
  }

  @Get('por-factura/:facturaId')
  @RequirePermission('COBRANZAS', 'COB_PRM_PROMESA_VER')
  @ApiOperation({ summary: 'Listar promesas de una factura específica' })
  findByFactura(@Param('facturaId') facturaId: string, @GetUser() user: LoginUserInfo) {
    return this.promesasService.findByFactura(facturaId, user.empresa_id);
  }

  @Get('vigentes-cliente/:clienteId')
  @RequirePermission('COBRANZAS', 'COB_PRM_PROMESA_VER')
  @ApiOperation({ summary: 'Promesas vigentes (pendiente/incumplida) de un cliente — banner ventas' })
  getVigentesPorCliente(@Param('clienteId') clienteId: string, @GetUser() user: LoginUserInfo) {
    return this.promesasService.getVigentesPorCliente(clienteId, user.empresa_id);
  }

  @Get('reporte/cumplimiento')
  @RequirePermission('COBRANZAS', 'COB_PRM_REPORTE_CUMPLIMIENTO')
  @ApiOperation({ summary: 'Reporte de cumplimiento por cobrador' })
  getReporteCumplimiento(
    @Query('fecha_desde') fecha_desde: string,
    @Query('fecha_hasta') fecha_hasta: string,
    @GetUser() user: LoginUserInfo,
  ) {
    return this.promesasService.getReporteCumplimiento(user.empresa_id, fecha_desde, fecha_hasta);
  }

  @Get('dashboard/cashflow')
  @RequirePermission('COBRANZAS', 'COB_PRM_REPORTE_CUMPLIMIENTO')
  @ApiOperation({ summary: 'Proyección de cobranza por fecha (promesas pendientes)' })
  getDashboardCashflow(@GetUser() user: LoginUserInfo) {
    return this.promesasService.getDashboardCashflow(user.empresa_id);
  }

  @Patch(':id/estado')
  @RequirePermission('COBRANZAS', 'COB_PRM_PROMESA_EDITAR')
  @ApiOperation({ summary: 'Actualizar estado de una promesa (cumplida / incumplida / cancelada)' })
  updateEstado(@Param('id') id: string, @Body() dto: UpdatePromesaEstadoDto, @GetUser() user: LoginUserInfo) {
    return this.promesasService.updateEstado(id, dto, user.empresa_id, user.id);
  }

  @Patch(':id/cancelar')
  @RequirePermission('COBRANZAS', 'COB_PRM_PROMESA_CANCELAR')
  @ApiOperation({ summary: 'Cancelar una promesa pendiente con motivo' })
  cancelar(@Param('id') id: string, @Body() dto: CancelarPromesaDto, @GetUser() user: LoginUserInfo) {
    return this.promesasService.cancelar(id, dto, user.empresa_id, user.id);
  }

  @Patch(':id/renegociar')
  @RequirePermission('COBRANZAS', 'COB_PRM_PROMESA_RENEGOCIAR')
  @ApiOperation({ summary: 'Renegociar promesa: cierra la anterior y crea nueva enlazada' })
  renegociar(@Param('id') id: string, @Body() dto: RenegociarPromesaDto, @GetUser() user: LoginUserInfo) {
    return this.promesasService.renegociar(id, dto, user.empresa_id, user.id);
  }
}
