using ChatMvc.Controllers;
using Newtonsoft.Json;
using Stripe.Forwarding;
using System.IdentityModel.Tokens.Jwt;
using System.Net.Http;
using System.Security.Claims;
using System.Text;

namespace ChatMvc.Managers
{
    public class TokenManager
    {
        private readonly IHttpClientFactory _httpClientFactory;
        private readonly IConfiguration _configuration;

        public TokenManager(IHttpClientFactory httpClientFactory, IConfiguration configuration)
        {
            this._httpClientFactory = httpClientFactory;
            this._configuration = configuration;
        }

        public async Task<string> GetToken(string userId, string company, string name)
        {
            var client = _httpClientFactory.CreateClient();
            var baseUrl = _configuration["ExternalApiBaseUrl"];

            // Primeira requisição - newclient
            var newClientRequest = new
            {
                localId = userId,
                companyTenant = company,
                name = name
            };

            var newClientResponse = await client.PostAsync(
                $"{baseUrl}/login/newclient",
                new StringContent(JsonConvert.SerializeObject(newClientRequest),
                    Encoding.UTF8, "application/json"));

            newClientResponse.EnsureSuccessStatusCode();
            var clientContent = await newClientResponse.Content.ReadAsStringAsync();
            var clientResult = JsonConvert.DeserializeObject<NewClientResponse>(clientContent);

            // Segunda requisição - token
            var tokenRequest = new
            {
                clientId = userId,
                clientName = name,
                clientSecret = clientResult.Secret
            };

            var tokenResponse = await client.PostAsync(
                $"{baseUrl}/login/token",
                new StringContent(JsonConvert.SerializeObject(tokenRequest),
                    Encoding.UTF8, "application/json"));

            tokenResponse.EnsureSuccessStatusCode();
            var tokenContent = await tokenResponse.Content.ReadAsStringAsync();
            var tokenResult = JsonConvert.DeserializeObject<TokenResponse>(tokenContent);

            return tokenResult.Token;

        }

        public async Task<string> GetToken(ClaimsPrincipal user)
        {
            var userId = user.Claims.FirstOrDefault(f => f.Type == "UserId")?.Value;
            var name = user.Claims.FirstOrDefault(f => f.Type == "FirstName")?.Value;
            var company = user.Claims.FirstOrDefault(f => f.Type == "CompanyName")?.Value;

            var client = _httpClientFactory.CreateClient();
            var baseUrl = _configuration["ExternalApiBaseUrl"];

            // Primeira requisição - newclient
            var newClientRequest = new
            {
                localId = userId,
                companyTenant = company,
                name = name
            };

            var newClientResponse = await client.PostAsync(
                $"{baseUrl}/login/newclient",
                new StringContent(JsonConvert.SerializeObject(newClientRequest),
                    Encoding.UTF8, "application/json"));

            newClientResponse.EnsureSuccessStatusCode();
            var clientContent = await newClientResponse.Content.ReadAsStringAsync();
            var clientResult = JsonConvert.DeserializeObject<NewClientResponse>(clientContent);

            // Segunda requisição - token
            var tokenRequest = new
            {
                clientId = userId,
                clientName = name,
                clientSecret = clientResult.Secret
            };

            var tokenResponse = await client.PostAsync(
                $"{baseUrl}/login/token",
                new StringContent(JsonConvert.SerializeObject(tokenRequest),
                    Encoding.UTF8, "application/json"));

            tokenResponse.EnsureSuccessStatusCode();
            var tokenContent = await tokenResponse.Content.ReadAsStringAsync();
            var tokenResult = JsonConvert.DeserializeObject<TokenResponse>(tokenContent);

            return tokenResult.Token;

        }

        public bool IsTokenExpired(string token)
        {
            var handler = new JwtSecurityTokenHandler();
            var jwtToken = handler.ReadJwtToken(token);

            var expiracao = jwtToken.ValidTo; 
            return expiracao < DateTime.UtcNow;
        }
    }
}
