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<FacturacionController> _logger;
        private readonly IEmailLogService _emailLogService;
        private const string PermisoGestionarFacturacion = "SU006";
        private const string PermisoEnviarEmail = "SU009";

        public FacturacionController(IFacturacionService facturacionService, ILogger<FacturacionController> 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<IActionResult> 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<IActionResult> 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<IActionResult> GetFacturas(
        int anio, int mes,
        [FromQuery] string? nombreSuscriptor,
        [FromQuery] string? estadoPago,
        [FromQuery] string? estadoFacturacion,
        [FromQuery] string? tipoFactura)
        {
            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, tipoFactura);
            return Ok(resumenes);
        }

        [HttpPost("{anio:int}/{mes:int}")]
        public async Task<IActionResult> 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<LoteDeEnvioHistorialDto>), StatusCodes.Status200OK)]
        public async Task<IActionResult> 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<EmailLogDto>), StatusCodes.Status200OK)]
        public async Task<IActionResult> 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);
        }
    }
}