import { Body, Controller, Get, Param, ParseUUIDPipe, Patch, Post, Put, 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 { AutorizacionesService } from './autorizaciones.service';
import { CrearDescuentoAdminDto, CreateAutorizacionDescuentoDto, QueryAutorizacionesDto, ResolverAutorizacionDto } from './dto/cobranzas.dto';

@ApiTags('Autorizaciones de Descuento')
@ApiBearerAuth()
@UseGuards(AuthGuard('jwt'), ModuleGuard, PermissionGuard)
@RequireModule('COBRANZAS')
@Controller({ path: 'autorizaciones-descuento', version: '1' })
export class AutorizacionesController {
  constructor(private readonly autorizacionesService: AutorizacionesService) {}

  /** Cobrador: solicitar autorización de descuento */
  @Post()
  @RequirePermission('COBRANZAS', 'COB_AUT_AUTORIZACION_SOLICITAR')
  @ApiOperation({ summary: 'Solicitar autorización de descuento (cobrador)' })
  solicitar(@Body() dto: CreateAutorizacionDescuentoDto, @GetUser() user: LoginUserInfo) {
    return this.autorizacionesService.solicitar(dto, user.empresa_id, user.id);
  }

  /** Admin: crear descuento directamente aprobado */
  @Post('admin')
  @RequirePermission('COBRANZAS', 'COB_AUT_AUTORIZACION_AUTORIZAR')
  @ApiOperation({ summary: 'Admin crea un descuento autorizado directamente para un cobrador' })
  crearAdmin(@Body() dto: CrearDescuentoAdminDto, @GetUser() user: LoginUserInfo) {
    return this.autorizacionesService.crearDescuentoAdmin(dto, user.empresa_id, user.id);
  }

  /** Cobros: descuento activo para una factura según el cobrador del usuario logueado */
  @Get('activa-factura/:facturaId')
  @RequirePermission('COBRANZAS', 'COB_AUT_AUTORIZACION_VER')
  @ApiOperation({ summary: 'Retorna el descuento autorizado vigente para una factura (para el módulo de cobros)' })
  async getActivaParaFactura(@Param('facturaId') facturaId: string, @GetUser() user: LoginUserInfo) {
    const auth = await this.autorizacionesService.getActivaParaUsuario(facturaId, user.id, user.empresa_id);
    return { data: auth };
  }

  /** Cobros: exoneraciones de interés activas para un set de cuotas (preview) */
  @Post('exoneraciones-activas')
  @RequirePermission('COBRANZAS', 'COB_AUT_AUTORIZACION_VER')
  @ApiOperation({
    summary:
      'Devuelve las autorizaciones EXONERACION_INTERES vigentes para las cuotas indicadas (read-only para el wizard de cobros)',
  })
  exoneracionesActivas(
    @Body() body: { factura_cuota_ids: string[] },
    @GetUser() user: LoginUserInfo,
  ) {
    return this.autorizacionesService.getExoneracionesActivasPorCuotas(
      user.empresa_id,
      body?.factura_cuota_ids ?? [],
    );
  }

  /** Supervisor: listar autorizaciones */
  @Get()
  @RequirePermission('COBRANZAS', 'COB_AUT_AUTORIZACION_VER')
  @ApiOperation({ summary: 'Listar autorizaciones de descuento' })
  findAll(@Query() query: QueryAutorizacionesDto, @GetUser() user: LoginUserInfo) {
    return this.autorizacionesService.findAll(user.empresa_id, query);
  }

  /** Supervisor: badge con cantidad de pendientes */
  @Get('pendientes/count')
  @RequirePermission('COBRANZAS', 'COB_AUT_AUTORIZACION_VER')
  @ApiOperation({ summary: 'Contar autorizaciones pendientes (para badge supervisor)' })
  async countPendientes(@GetUser() user: LoginUserInfo) {
    const count = await this.autorizacionesService.countPendientes(user.empresa_id);
    return { count };
  }

  /** Cobros: marcar autorización como usada al registrar el recibo */
  @Patch(':id/usar')
  @RequirePermission('COBRANZAS', 'COB_REC_RECIBO_CREAR')
  @ApiOperation({ summary: 'Marcar descuento como usado al crear el recibo de cobro' })
  usar(@Param('id') id: string, @Body() body: { recibo_cobro_id?: string }, @GetUser() user: LoginUserInfo) {
    return this.autorizacionesService.marcarUsada(id, body.recibo_cobro_id ?? null);
  }

  /** Supervisor: cancelar/inactivar autorización aprobada o pendiente no usada */
  @Patch(':id/cancelar')
  @RequirePermission('COBRANZAS', 'COB_AUT_AUTORIZACION_AUTORIZAR')
  @ApiOperation({ summary: 'Cancelar/inactivar una autorización aprobada o pendiente que aún no se usó' })
  cancelar(
    @Param('id', ParseUUIDPipe) id: string,
    @Body() body: { motivo?: string },
    @GetUser() user: LoginUserInfo,
  ) {
    return this.autorizacionesService.cancelar(id, user.empresa_id, user.id, body?.motivo);
  }

  /** Supervisor: aprobar o rechazar */
  @Patch(':id/resolver')
  @RequirePermission('COBRANZAS', 'COB_AUT_AUTORIZACION_AUTORIZAR')
  @ApiOperation({ summary: 'Aprobar o rechazar autorización de descuento (supervisor)' })
  resolver(@Param('id') id: string, @Body() dto: ResolverAutorizacionDto, @GetUser() user: LoginUserInfo) {
    return this.autorizacionesService.resolver(id, dto, user.empresa_id, user.id);
  }
}
