using Microsoft.AspNetCore.Mvc;
using QRRapidoApp.Models.ViewModels;
using QRRapidoApp.Models.DTOs;
using QRRapidoApp.Services;
using System.Diagnostics;
using System.Security.Claims;
using System.Text;
using System.Security.Cryptography;
using Microsoft.Extensions.Localization;
using QRRapidoApp.Models;
using MongoDB.Driver;

namespace QRRapidoApp.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class QRController : ControllerBase
    {
        private readonly IQRBusinessManager _qrBusinessManager;
        private readonly IUserService _userService;
        private readonly IQRCodeService _qrService; // Mantido para Download
        private readonly ILogger<QRController> _logger;
        private readonly IStringLocalizer<QRRapidoApp.Resources.SharedResource> _localizer;

        public QRController(
            IQRBusinessManager qrBusinessManager, 
            IUserService userService, 
            IQRCodeService qrService,
            ILogger<QRController> logger, 
            IStringLocalizer<QRRapidoApp.Resources.SharedResource> localizer)
        {
            _qrBusinessManager = qrBusinessManager;
            _userService = userService;
            _qrService = qrService;
            _logger = logger;
            _localizer = localizer;
        }

        [HttpPost("GenerateRapid")]
        public async Task<IActionResult> GenerateRapid([FromBody] QRGenerationRequest request)
        {
            var context = new UserRequesterContext
            {
                UserId = User?.FindFirst(ClaimTypes.NameIdentifier)?.Value,
                IpAddress = HttpContext.Connection.RemoteIpAddress?.ToString() ?? "unknown",
                DeviceId = Request.Cookies["_qr_device_id"]
            };

            var result = await _qrBusinessManager.ProcessGenerationAsync(request, context);

            if (!result.Success)
            {
                if (result.ErrorCode == "LIMIT_REACHED")
                {
                    return StatusCode(429, new 
                    { 
                        error = result.Message,
                        upgradeUrl = "/Account/Login"
                    });
                }
                if (result.ErrorCode == "INSUFFICIENT_CREDITS")
                {
                    return StatusCode(402, new { 
                        success = false, 
                        error = result.Message,
                        redirectUrl = "/Pagamento/SelecaoPlano"
                    });
                }
                return BadRequest(new { success = false, error = result.Message });
            }

            // Gerenciar Cookie de DeviceID para anônimos
            if (!context.IsAuthenticated && string.IsNullOrEmpty(context.DeviceId))
            {
                var newDeviceId = Guid.NewGuid().ToString("N");
                Response.Cookies.Append("_qr_device_id", newDeviceId, new CookieOptions 
                { 
                    Expires = DateTime.UtcNow.AddYears(1),
                    HttpOnly = true,
                    Secure = true,
                    SameSite = SameSiteMode.Strict
                });
            }

            return Ok(new 
            { 
                success = true,
                QRCodeBase64 = result.QRCodeBase64,
                QRId = result.QRId,
                FromCache = result.FromCache,
                RemainingQRs = context.IsAuthenticated ? result.RemainingCredits : (result.RemainingFreeQRs > 0 ? result.RemainingFreeQRs : 0),
                Message = result.Message,
                GenerationTimeMs = result.GenerationTimeMs
            });
        }

        [HttpGet("GetUserStats")]
        public async Task<IActionResult> GetUserStats()
        {
            var userId = User?.FindFirst(ClaimTypes.NameIdentifier)?.Value;
            if (string.IsNullOrEmpty(userId)) return Unauthorized();

            var user = await _userService.GetUserAsync(userId);
            if (user == null) return NotFound();

            return Ok(new 
            { 
                credits = user.Credits,
                freeUsed = user.FreeQRsUsed,
                freeLimit = 5,
                isPremium = user.Credits > 0 || user.FreeQRsUsed < 5 
            });
        }

        [HttpGet("Download/{qrId}")]
        public async Task<IActionResult> Download(string qrId, string format = "png")
        {
             try
            {
                var qrData = await _userService.GetQRDataAsync(qrId);
                if (qrData == null) return NotFound();

                byte[] fileContent = Convert.FromBase64String(qrData.QRCodeBase64);
                var contentType = "image/png";
                var fileName = $"qrrapido-{qrId}.png";

                if (format == "svg")
                {
                    fileContent = await _qrService.ConvertToSvgAsync(qrData.QRCodeBase64);
                    contentType = "image/svg+xml";
                    fileName = fileName.Replace(".png", ".svg");
                }
                else if (format == "pdf")
                {
                    fileContent = await _qrService.ConvertToPdfAsync(qrData.QRCodeBase64, qrData.Size);
                    contentType = "application/pdf";
                    fileName = fileName.Replace(".png", ".pdf");
                }

                return File(fileContent, contentType, fileName);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Download error");
                return StatusCode(500);
            }
        }
        
        [HttpGet("History")]
        public async Task<IActionResult> GetHistory(int limit = 20)
        {
            var userId = User?.FindFirst(ClaimTypes.NameIdentifier)?.Value;
            if (string.IsNullOrEmpty(userId)) return Unauthorized();
            return Ok(await _userService.GetUserQRHistoryAsync(userId, limit));
        }

        [HttpPost("GenerateRapidWithLogo")]
        public async Task<IActionResult> GenerateRapidWithLogo([FromForm] QRGenerationRequest request, IFormFile? logo)
        {
             var userId = User?.FindFirst(ClaimTypes.NameIdentifier)?.Value;
             if (string.IsNullOrEmpty(userId)) return Unauthorized();

             if (logo != null)
             {
                 using var ms = new MemoryStream();
                 await logo.CopyToAsync(ms);
                 request.Logo = ms.ToArray();
                 request.HasLogo = true;
             }

             var context = new UserRequesterContext
             {
                 UserId = userId,
                 IpAddress = HttpContext.Connection.RemoteIpAddress?.ToString() ?? "unknown"
             };

             var result = await _qrBusinessManager.ProcessGenerationAsync(request, context);

             if (!result.Success) return BadRequest(result);

             return Ok(new { 
                success = true,
                QRCodeBase64 = result.QRCodeBase64,
                QRId = result.QRId,
                RemainingQRs = result.RemainingCredits
             });
        }
        
        [HttpPost("SaveToHistory")]
        public async Task<IActionResult> SaveToHistory([FromBody] SaveToHistoryRequest request)
        {
             return Ok(new { success = true });
        }
    }
    
    public class SaveToHistoryRequest
    {
        public string QrId { get; set; } = string.Empty;
    }
}