using GestionIntegral.Api.Dtos.Comunicaciones; using GestionIntegral.Api.Services.Comunicaciones; using GestionIntegral.Api.Services.Suscripciones; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using System.Security.Claims; namespace GestionIntegral.Api.Controllers.Suscripciones { [Route("api/facturacion")] [ApiController] [Authorize] public class FacturacionController : ControllerBase { private readonly IFacturacionService _facturacionService; private readonly ILogger _logger; private readonly IEmailLogService _emailLogService; private const string PermisoGestionarFacturacion = "SU006"; private const string PermisoEnviarEmail = "SU009"; public FacturacionController(IFacturacionService facturacionService, ILogger logger, IEmailLogService emailLogService) { _facturacionService = facturacionService; _logger = logger; _emailLogService = emailLogService; } private bool TienePermiso(string codAcc) => User.IsInRole("SuperAdmin") || User.HasClaim(c => c.Type == "permission" && c.Value == codAcc); private int? GetCurrentUserId() { if (int.TryParse(User.FindFirstValue(ClaimTypes.NameIdentifier) ?? User.FindFirstValue("sub"), out int userId)) return userId; _logger.LogWarning("No se pudo obtener el UserId del token JWT en FacturacionController."); return null; } [HttpPut("{idFactura:int}/numero-factura")] [ProducesResponseType(StatusCodes.Status204NoContent)] public async Task UpdateNumeroFactura(int idFactura, [FromBody] string numeroFactura) { if (!TienePermiso(PermisoGestionarFacturacion)) return Forbid(); var userId = GetCurrentUserId(); if (userId == null) return Unauthorized(); var (exito, error) = await _facturacionService.ActualizarNumeroFactura(idFactura, numeroFactura, userId.Value); if (!exito) { if (error != null && error.Contains("no existe")) return NotFound(new { message = error }); return BadRequest(new { message = error }); } return NoContent(); } [HttpPost("{idFactura:int}/enviar-factura-pdf")] public async Task EnviarFacturaPdf(int idFactura) { if (!TienePermiso(PermisoEnviarEmail)) return Forbid(); var userId = GetCurrentUserId(); if (userId == null) return Unauthorized(); var (exito, error, emailDestino) = await _facturacionService.EnviarFacturaPdfPorEmail(idFactura, userId.Value); if (!exito) { return BadRequest(new { message = error }); } var mensajeExito = $"El email con la factura PDF se ha enviado correctamente a {emailDestino}."; return Ok(new { message = mensajeExito }); } [HttpGet("{anio:int}/{mes:int}")] public async Task GetFacturas( int anio, int mes, [FromQuery] string? nombreSuscriptor, [FromQuery] string? estadoPago, [FromQuery] string? estadoFacturacion) { if (!TienePermiso(PermisoGestionarFacturacion)) return Forbid(); if (anio < 2020 || mes < 1 || mes > 12) return BadRequest(new { message = "El período no es válido." }); var resumenes = await _facturacionService.ObtenerResumenesDeCuentaPorPeriodo(anio, mes, nombreSuscriptor, estadoPago, estadoFacturacion); return Ok(resumenes); } [HttpPost("{anio:int}/{mes:int}")] public async Task GenerarFacturacion(int anio, int mes) { if (!TienePermiso(PermisoGestionarFacturacion)) return Forbid(); var userId = GetCurrentUserId(); if (userId == null) return Unauthorized(); if (anio < 2020 || mes < 1 || mes > 12) return BadRequest(new { message = "El año y el mes proporcionados no son válidos." }); var (exito, mensaje, resultadoEnvio) = await _facturacionService.GenerarFacturacionMensual(anio, mes, userId.Value); if (!exito) return StatusCode(StatusCodes.Status500InternalServerError, new { message = mensaje }); return Ok(new { message = mensaje, resultadoEnvio }); } [HttpGet("historial-lotes-envio")] [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] public async Task GetHistorialLotesEnvio([FromQuery] int? anio, [FromQuery] int? mes) { if (!TienePermiso("SU006")) return Forbid(); var historial = await _facturacionService.ObtenerHistorialLotesEnvio(anio, mes); return Ok(historial); } // Endpoint para el historial de envíos de una factura individual [HttpGet("{idFactura:int}/historial-envios")] [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] public async Task GetHistorialEnvios(int idFactura) { if (!TienePermiso(PermisoGestionarFacturacion)) return Forbid(); // Reutilizamos el permiso // Construimos la referencia que se guarda en el log string referencia = $"Factura-{idFactura}"; var historial = await _emailLogService.ObtenerHistorialPorReferencia(referencia); return Ok(historial); } } }