using _Core;
using System.Collections.Generic;
using System;
using Newtonsoft.Json;
using _Core.Storage;

namespace _Combo
{
    public class GlobalParameters : Singleton<GlobalParameters>
    {
        public string SeayooAccountAPIEndPoint =>
            GetParameter<string>("seayoo_account_game_api_endpoint");
        public bool SeayooAccountHideEula => GetParameter<bool>("seayoo_account_hide_eula");
        public bool SeayooAccountHideCloseButton =>
            GetParameter<bool>("seayoo_account_hide_close_button");
        public string SeayooAccountAgreementUrl => GetParameter<string>("seayoo_account_agreement_url");
        public string SeayooAccountPrivacyUrl => GetParameter<string>("seayoo_account_privacy_url");
        public string SeayooAccountForgetPasswordUrl => GetParameter<string>("seayoo_account_forgot_password_url");
        public bool SeayooAccountHideAccountSwitcher => GetParameter<bool>("seayoo_account_hide_account_switcher");
        public string SeayooAccountSupportUrl => GetParameter<string>("seayoo_account_support_url");
        public string SeayooAccountWebsiteUrl => GetParameter<string>("seayoo_account_website_url");
        public bool SeayooAccountHideLogo => GetParameter<bool>("seayoo_account_hide_logo");
        public bool SeayooAccountDisablePasswordLogin => GetParameter<bool>("seayoo_account_disable_password_login");
        public string SeayooAccountOtpProfile => GetParameter<string>("seayoo_account_otp_profile");
        public bool SeayooAccountDisableSdkApi => GetParameter<bool>("seayoo_account_disable_sdk_api");
        public string SeayooAccountCaptchaUrl => GetParameter<string>("seayoo_account_captcha_url");
        public string GameUrlUserAgreement => GetParameter<string>("game_url_user_agreement");
        public string GameUrlPrivacyPolicy => GetParameter<string>("game_url_privacy_policy");
        public string GameUrlPrivacyChildren => GetParameter<string>("game_url_privacy_children");
        public string GameUrlThirdParty => GetParameter<string>("game_url_third_party");
        public string GameUrlFangchenmi => GetParameter<string>("game_url_fangchenmi");
        public string GameGamerApiEndpoint => GetParameter<string>("game_gamer_api_endpoint");
        public string GameAnnouncementsUrl => GetParameter<string>("game_announcements_url");
        public string GameComplainUrl => GetParameter<string>("game_complain_url");
        public bool TaptapDisableTapLogin => GetParameter<bool>("taptap_disable_tap_login");
        public string TaptapClientId => GetParameter<string>("taptap_client_id");
        public string TaptapClientToken => GetParameter<string>("taptap_client_token");
        public string TaptapClientPublicKey => GetParameter<string>("taptap_client_public_key");
        public string TaptapPCDistro => GetParameter<string>("taptap_pc_distro");
        public bool TaptapMustLinkSeayooAccount => GetParameter<bool>("taptap_must_link_seayoo_account");
        public string SdkLanguageMode => GetParameter<string>("sdk_language_mode");
        public string SdkLUIMode => GetParameter<string>("sdk_ui_mode");
        public bool SdkLocalhostHttpServerEnabled => GetParameter<bool>("sdk_localhost_http_server_enabled");
        public string GameGiftCodeUrl => GetParameter<string>("game_gift_code_url");
        public string LenovoPcCpId => GetParameter<string>("lenovo_pc_cpid");
        public string LenovoPcAppId => GetParameter<string>("lenovo_pc_appid");
        public string LenovoPcBizId => GetParameter<string>("lenovo_pc_bizid");
        public string LenovoPcKey => GetParameter<string>("lenovo_pc_privatekey");
        private Dictionary<string, string> parameters;
        private readonly string parametersKey = "combosdk_parameters";

        public void Setup(Action onSuccess, Action<InternalError> onError)
        {
            FetchServerParameters(
                parameters =>
                {
                    UpdateParameters(parameters);
                    onSuccess.Invoke();
                },
                error =>
                {
                    onError.Invoke(error);
                }
            );
        }

        GlobalParameters()
        {
            parameters = GetCacheParameters();
        }

        private Dictionary<string, string> GetCacheParameters()
        {
            Dictionary<string, string> configurationParameters = Configuration.Instance.Parameters;
            if(UserPrefs.HasKey(parametersKey))
            {
                Dictionary<string, string> cacheParameters = JsonConvert.DeserializeObject<Dictionary<string, string>>(UserPrefs.GetString(parametersKey));
                foreach (var item in cacheParameters)
                {
                    configurationParameters[item.Key] = item.Value;
                }
            }
            return configurationParameters;
        }

        public Dictionary<string, string> GetParameters()
        {
            return parameters;
        }

        public T GetParameter<T>(string key)
        {
            if (!parameters.ContainsKey(key))
            {
                Log.D($"Key {key} not found in parameters dictionary, return {default(T)}.");
                return default(T);
            }
            try
            {
                object value = parameters[key];

                // 特殊处理空字符串转换为布尔值的情况
                if (typeof(T) == typeof(bool) && value is string strValue && string.IsNullOrEmpty(strValue))
                {
                    return (T)(object)false;
                }
                return (T)Convert.ChangeType(parameters[key], typeof(T));
            }
            catch (Exception ex)
            {
                Log.E(
                    $"Failed to convert parameter {key} with value {parameters[key]} to type {typeof(T)}, return {default(T)}. Exception: {ex}"
                );
                return default(T);
            }
        }

        private void FetchServerParameters(
            Action<Dictionary<string, string>> onSuccess,
            Action<InternalError> onError
        )
        {
            ComboClient.GetParameters(
                resp =>
                {
                    try
                    {
                        var data = resp.Data;
                        onSuccess.Invoke(data);
                    }
                    catch (InternalError e)
                    {
                        onError.Invoke(e);
                    }
                }
            );
        }

        private void UpdateParameters(IDictionary<string, string> dict2)
        {
            foreach (var item in dict2)
            {
                parameters[item.Key] = item.Value;
            }

            UserPrefs.SetString(parametersKey, JsonConvert.SerializeObject(dict2));
        }
    }
}
