using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Options;
using PARR.API.Services.Interfaces;
using System.Security.Claims;
using System.Text.Encodings.Web;

namespace PARR.API.Authentication
{
    public class ParrAuthenticationHandler : AuthenticationHandler<ParrAuthenticationOptions>
    {
        private readonly IServiceProvider serviceProvider;

        public ParrAuthenticationHandler(
            IOptionsMonitor<ParrAuthenticationOptions> options,
            ILoggerFactory logger,
            UrlEncoder encoder,
            ISystemClock clock,
            IServiceProvider serviceProvider) : base(options, logger, encoder, clock)
        {
            this.serviceProvider = serviceProvider;
        }

        protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
        {
            var ipClient = Request.HttpContext.Connection.RemoteIpAddress?.MapToIPv4().ToString();

            if (ipClient == null)
                return AuthenticateResult.Fail($"IP address not defined. IP: {ipClient}");


            // Аутентификация - просто проверка, есть ли у нас такой пользователь 
            using (var scope = serviceProvider.CreateScope())
            {
                var authService = scope.ServiceProvider.GetRequiredService<IAuthService>();

                var userIsBlocked = await authService.UserIsBlockedAsync(ipClient);
                if (userIsBlocked)
                    return AuthenticateResult.Fail($"IP address is on the blocking list. IP: {ipClient}");

                var user = await authService.GetUserAsync(ipClient);
                if (user == null)
                    return AuthenticateResult.Fail($"IP address not defined. IP: {ipClient}");


                // пользователь найден, аутентификация пройдена

                var claims = new List<Claim> {
                    new Claim(ClaimTypes.Name, user.UserIp)
                };
                // добавляем роли
                user.Roles.ForEach(r => claims.Add(new Claim(ClaimTypes.Role, r.Name)));

                var claimsIdentity = new ClaimsIdentity(claims, Scheme.Name);
                var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);


                return AuthenticateResult.Success(new AuthenticationTicket(claimsPrincipal, Scheme.Name));
            }
        }


        //private AuthenticateResult CreateLocalAuth(string ipClient)
        //{
        //    // Когда контейнер запрашивает health статус, 

        //    var claims = new List<Claim> {
        //            new Claim(ClaimTypes.Name, ipClient)
        //        };

        //    var claimsIdentity = new ClaimsIdentity(claims, Scheme.Name);
        //    var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);

        //    return AuthenticateResult.Success(new AuthenticationTicket(claimsPrincipal, Scheme.Name));
        //}


    }
}
