using System;
using System.Collections.Generic;
using System.Text;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using Microsoft.IdentityModel.Tokens;
using Microsoft.Identity.Client;
using System.ComponentModel;
using System.Threading.Tasks;
using Azure.Security.KeyVault.Secrets;
using Azure.Core;
using Azure.Identity;
using System.Net.Http;
using System.Collections.Concurrent;
using System.Diagnostics;

namespace TEAMModelOS.SDK.Extension
{
    public static class CoreTokenExtensions
    {       //var issuer = Configuration.GetValue<string>("JwtSettings:Issuer");
            //var signKey = Configuration.GetValue<string>("JwtSettings:SignKey");
        private const string issuer = "account.teammodel";
        //Azure AD 租用戶識別碼(國際、大陸)
        private static List<string> tenantids = new List<string> { "73a2bcc5-fe99-4566-aa8a-07e7bb287df1", "4807e9cf-87b8-4174-aa5b-e76497d7392b" };
        private static ConcurrentDictionary<string, KeyVaultSecret> KeyVaultSecrets { get; } = new ConcurrentDictionary<string, KeyVaultSecret>();
              

        #region  Access Token
        /// <summary>
        /// 產生AccessToken
        /// </summary>
        /// <param name="clientID"></param>
        /// <param name="location">服務位置，Global or China ...</param>
        /// <returns></returns>
        public static async ValueTask<AuthenticationResult> CreateAccessToken(string clientID, string clientSecret, string location)
        {
            //從金鑰庫取出秘密，此作法讓所有端直接刷新金鑰，無需傳送秘密，SPA更適用
            var secret = clientSecret ?? (await GetClientIDSecret(clientID, location)).Value;

            var sts = Enum.Parse<STSEndpoint>(location, true);

            IConfidentialClientApplication app;
            app = ConfidentialClientApplicationBuilder.Create(clientID)
                                                      .WithClientSecret(secret)
                                                      .WithAuthority(new Uri(sts.GetDescriptionText()))
                                                      .Build();
            var scope = ((STSScope)sts).GetDescriptionText();
            var result = await app.AcquireTokenForClient(new[] { scope }).ExecuteAsync();
            return result;
        }

        /// <summary>
        /// 驗證是否為公司Azure發行金鑰，支援大陸國際
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public static bool ValidateAccessToken(JwtSecurityToken token)
        {
            try
            {
                if (token.Payload.TryGetValue("tid", out var value) && value is string tokenTenantId)
                {
                    return tenantids.Contains(tokenTenantId);
                }
                return false;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public static bool ValidateIdToken(string token, string salt)
        {
            try
            {
                var handler = new JwtSecurityTokenHandler();
                var validationParameters = new TokenValidationParameters
                {
                    RequireExpirationTime = true,
                    ValidateIssuer = false,
                    ValidateAudience = false,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(salt)),
                    ValidateLifetime = false,
                    //LifetimeValidator = LifetimeValidator,
                    ClockSkew = TimeSpan.Zero                    
                };
                ClaimsPrincipal principal = handler.ValidateToken(token, validationParameters, out SecurityToken securityToken);
                return true;
            }
            catch(Exception ex)
            {
                Trace.WriteLine(ex.Message);
                return false;
            }
        }
        #endregion

        private static async ValueTask<KeyVaultSecret> GetClientIDSecret(string clientID, string location)
        {   //Azure 金鑰庫處理
            var s = await Task.Run(() =>
            {
                var secret = KeyVaultSecrets.GetOrAdd(clientID, (x) =>
                {
                    try
                    {
                        var sts = Enum.Parse<CoreServiceClient>(location, true);
                        var scrtetstring = sts.GetDescriptionText().Split(",");
                        //TODO 之後驗證端點用KnownAuthorityHosts取代，此SDK版本無支援
                        var secret = new ClientSecretCredential(scrtetstring[0], scrtetstring[1], scrtetstring[2], new TokenCredentialOptions() { AuthorityHost = new Uri(scrtetstring[3]) });
                        var client = new SecretClient(new Uri(((KeyVaultEndpoint)sts).GetDescriptionText()), secret);
                        var clientSecret = client.GetSecretAsync(clientID).ConfigureAwait(false);
                        return clientSecret.GetAwaiter().GetResult();
                    }
                    catch
                    {
                        return null;
                    }
                });
                return secret;
            });
            return s;
        }

        public static bool LifetimeValidator(DateTime? notBefore, DateTime? expires, SecurityToken securityToken, TokenValidationParameters validationParameters)
        {
            return true;
            //if (expires != null)
            //{
            //    if (DateTime.UtcNow < expires)
            //    {
            //        return true;
            //    }
            //}

            //return false;
        }

        private enum STSEndpoint
        {
            [Description("https://login.chinacloudapi.cn/4807e9cf-87b8-4174-aa5b-e76497d7392b")]
            China,
            [Description("https://login.microsoftonline.com/73a2bcc5-fe99-4566-aa8a-07e7bb287df1")]
            Global
        }

        private enum STSScope
        {
            [Description("api://72643704-b2e7-4b26-b881-bd5865e7a7a5/.default")]
            China,
            [Description("api://8768b06f-c5c5-4b0c-abfb-d7ded354626d/.default")]
            Global
        }

        private enum KeyVaultEndpoint
        {
            [Description("https://corekeyvaultcn.vault.azure.cn/")]
            China,
            [Description("https://corekeyvaultjp.vault.azure.net/")]
            Global
        }

        private enum CoreServiceClient
        {
            [Description("4807e9cf-87b8-4174-aa5b-e76497d7392b,72643704-b2e7-4b26-b881-bd5865e7a7a5,tRYbDXtotEOe2Bbmo=[3h9Hbu_Trt:c6,https://login.partner.microsoftonline.cn")]
            China,
            [Description("73a2bcc5-fe99-4566-aa8a-07e7bb287df1,8768b06f-c5c5-4b0c-abfb-d7ded354626d,7=O./yws0L89WcEsece:9/4deJHP4E=F,https://login.microsoftonline.com/")]
            Global
        }
    }
}
