using System.Text;
using System.Text.Json;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.WebUtilities;

namespace RegistroPersonalAN.Models
{
    public sealed class UserStateCookieStore
    {
        private const string CookieName = "RegistroPersonalAN.AuthState";
        private readonly IDataProtector _protector;

        public UserStateCookieStore(IDataProtectionProvider dataProtectionProvider)
        {
            _protector = dataProtectionProvider.CreateProtector("RegistroPersonalAN.UserStateCookieStore.v1");
        }

        public UserStateCookiePayload? Read(HttpContext? httpContext)
        {
            if (httpContext?.Request.Cookies.TryGetValue(CookieName, out var cookieValue) != true ||
                string.IsNullOrWhiteSpace(cookieValue))
            {
                return null;
            }

            try
            {
                var protectedPayload = Encoding.UTF8.GetString(WebEncoders.Base64UrlDecode(cookieValue));
                var json = _protector.Unprotect(protectedPayload);
                var payload = JsonSerializer.Deserialize<UserStateCookiePayload>(json);

                if (payload is null || string.IsNullOrWhiteSpace(payload.Token))
                {
                    return null;
                }

                return payload;
            }
            catch
            {
                return null;
            }
        }

        public void Write(HttpContext httpContext, UserStateCookiePayload payload)
        {
            if (string.IsNullOrWhiteSpace(payload.Token))
            {
                Clear(httpContext);
                return;
            }

            var json = JsonSerializer.Serialize(payload);
            var protectedPayload = _protector.Protect(json);
            var cookieValue = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(protectedPayload));

            httpContext.Response.Cookies.Append(CookieName, cookieValue, BuildCookieOptions(httpContext));
        }

        public void Clear(HttpContext httpContext)
        {
            httpContext.Response.Cookies.Delete(CookieName, BuildCookieOptions(httpContext));
        }

        private static CookieOptions BuildCookieOptions(HttpContext httpContext)
        {
            return new CookieOptions
            {
                HttpOnly = true,
                IsEssential = true,
                Path = "/",
                SameSite = SameSiteMode.Lax,
                Secure = httpContext.Request.IsHttps
            };
        }
    }

    public sealed class UserStateCookiePayload
    {
        public string Token { get; set; } = string.Empty;
        public string NombreUsu { get; set; } = string.Empty;
    }
}
