import { Body, Controller, Get, Param, Patch, Post, Query, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiBearerAuth, ApiOperation, ApiQuery, ApiTags } from '@nestjs/swagger';
import type { LoginUserInfo } from '../auth/dto/login.dto';
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 { CreateRutaCobranzaDto, UpdateRutaEstadoDto, AgregarFacturasRutaDto } from './dto/rutas-cobranza.dto';
import { RutasCobranzaService } from './rutas-cobranza.service';

/**
 * RutasCobranzaController
 * ────────────────────────────────────────────────────────────────────────
 * Endpoints para gestionar rutas diarias de cobranza.
 *
 * Flujo típico:
 *  POST /rutas-cobranza           → Supervisor crea ruta con facturas
 *  GET  /rutas-cobranza           → Listar rutas (filtros: cobrador, fecha, estado)
 *  GET  /rutas-cobranza/:id       → Detalle de ruta con facturas y clientes
 *  PATCH /rutas-cobranza/:id/estado → Cambiar estado (planificada→en_curso→completada)
 *  POST /rutas-cobranza/:id/facturas → Agregar facturas a ruta planificada
 *  GET  /rutas-cobranza/:id/hoja-ruta → Datos para impresión de hoja de ruta
 *  GET  /rutas-cobranza/para-rendicion/:cobradorId → Rutas sin rendición
 */
@ApiTags('Rutas de Cobranza')
@ApiBearerAuth()
@UseGuards(AuthGuard('jwt'), ModuleGuard, PermissionGuard)
@RequireModule('COBRANZAS')
@Controller('rutas-cobranza')
export class RutasCobranzaController {
  constructor(private readonly service: RutasCobranzaService) {}

  @Post()
  @RequirePermission('COBRANZAS', 'COB_RUT_RUTA_CREAR')
  @ApiOperation({ summary: 'Crear una nueva ruta de cobranza diaria' })
  create(@GetUser() user: LoginUserInfo, @Body() dto: CreateRutaCobranzaDto) {
    return this.service.create(user.empresa_id, dto);
  }

  @Get()
  @RequirePermission('COBRANZAS', 'COB_RUT_RUTA_VER')
  @ApiOperation({ summary: 'Listar rutas de cobranza con filtros y paginación' })
  @ApiQuery({ name: 'cobrador_id', required: false })
  @ApiQuery({ name: 'fecha_desde', required: false, description: 'YYYY-MM-DD' })
  @ApiQuery({ name: 'fecha_hasta', required: false, description: 'YYYY-MM-DD' })
  @ApiQuery({ name: 'estado', required: false, enum: ['planificada', 'en_curso', 'completada', 'cancelada'] })
  @ApiQuery({ name: 'page', required: false, type: Number })
  @ApiQuery({ name: 'limit', required: false, type: Number })
  findAll(
    @GetUser() user: LoginUserInfo,
    @Query('cobrador_id') cobrador_id?: string,
    @Query('fecha_desde') fecha_desde?: string,
    @Query('fecha_hasta') fecha_hasta?: string,
    @Query('estado') estado?: string,
    @Query('page') page?: string,
    @Query('limit') limit?: string,
  ) {
    return this.service.findAll(user.empresa_id, {
      cobrador_id,
      fecha_desde,
      fecha_hasta,
      estado,
      page: page ? parseInt(page) : 1,
      limit: limit ? parseInt(limit) : 20,
    });
  }

  @Get('para-rendicion/:cobradorId')
  @RequirePermission('COBRANZAS', 'COB_RUT_RUTA_VER')
  @ApiOperation({ summary: 'Obtener rutas disponibles para rendición de un cobrador' })
  getRutasParaRendicion(
    @GetUser() user: LoginUserInfo,
    @Param('cobradorId') cobradorId: string,
  ) {
    return this.service.getRutasParaRendicion(user.empresa_id, cobradorId);
  }

  @Get(':id')
  @RequirePermission('COBRANZAS', 'COB_RUT_RUTA_VER')
  @ApiOperation({ summary: 'Obtener detalle de una ruta de cobranza' })
  findOne(@GetUser() user: LoginUserInfo, @Param('id') id: string) {
    return this.service.findOne(user.empresa_id, id);
  }

  @Get(':id/hoja-ruta')
  @RequirePermission('COBRANZAS', 'COB_RUT_RUTA_VER')
  @ApiOperation({ summary: 'Obtener datos de hoja de ruta para impresión' })
  getHojaRuta(@GetUser() user: LoginUserInfo, @Param('id') id: string) {
    return this.service.getHojaRuta(user.empresa_id, id);
  }

  @Patch(':id/estado')
  @RequirePermission('COBRANZAS', 'COB_RUT_RUTA_EDITAR')
  @ApiOperation({ summary: 'Cambiar estado de la ruta (planificada→en_curso→completada)' })
  updateEstado(
    @GetUser() user: LoginUserInfo,
    @Param('id') id: string,
    @Body() dto: UpdateRutaEstadoDto,
  ) {
    return this.service.updateEstado(user.empresa_id, id, dto);
  }

  @Post(':id/facturas')
  @RequirePermission('COBRANZAS', 'COB_RUT_RUTA_EDITAR')
  @ApiOperation({ summary: 'Agregar facturas a una ruta en estado planificada' })
  agregarFacturas(
    @GetUser() user: LoginUserInfo,
    @Param('id') id: string,
    @Body() dto: AgregarFacturasRutaDto,
  ) {
    return this.service.agregarFacturas(user.empresa_id, id, dto);
  }
}
