using System;
using FairyGUI;
using UnityEngine;
using DG.Tweening;
using Spine.Unity;
using System.Text;
using BingoBrain.Core;
using System.Linq;
using BingoBrain.HotFix;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
using AppsFlyerSDK;
using DontConfuse;

namespace BingoBrain
{
    public static class GameHelper
    {
        public static string GetNum(float num, int floatLength = -1)
        {
            var numString = num.ToString(floatLength < 0 ? "" : $"f{floatLength}");
            if (num > 1000)
            {
                return numString;
            }

            numDic.TryAdd(num, numString);
            return numDic[num];
        }

        private const string fenhao = ":";

        public static string GetInterval(long interval)
        {
            int hour, minute, second;
            second = (int)(interval % 60);
            int tempMinute = (int)(interval / 60);
            hour = tempMinute / 60;
            minute = tempMinute - (hour * 60);
            StringBuilder str = new StringBuilder();
            if (hour < 10)
                str.Append("0");
            str.Append(hour);
            str.Append(fenhao);
            if (minute < 10)
                str.Append("0");
            str.Append(minute);
            str.Append(fenhao);
            if (second < 10)
                str.Append("0");
            str.Append(second);

            return str.ToString();
        }

        public static Vector3 FguiToUnityLocalPot(Vector3 pot)
        {
            var v = Vector3.zero;
            v.x = pot.x;
            v.y = -pot.y;
            v.z = pot.z;
            return v;
        }

        public static void Toast(string val, bool isLangue = false)
        {
            var valStr = val;
            var tipsData = TipsData.GetTips(valStr);
            UICtrlDispatcher.Instance.Dispatch(SkinInfo.JTipsUI_Open, tipsData);
        }

        public static void GetVideo(string adId, Action<bool> onCompleted)
        {
            MaxADKit.ShowVideo(adId, isSuccess =>
            {
                if (isSuccess)
                {
                    CtrlDispatcher.Instance.Dispatch(CtrlMsg.WatchVideoFinish);
                }
                else
                {
                    Toast("Ads Not Ready", true);
                }

                onCompleted?.Invoke(isSuccess);
            });
        }

        private static long CanShowInterstitialTime;

        public static void ShowInterstitial(string key)
        {

            //if(Random.Range(0, 100)>ConfigSystem.GetConfig<CommonModel>().interstitialtype) return;
            if (!IsGiftSwitch()) return;
            MaxADKit.ShowInterstitial(key, isSuccess =>
            {
                if (isSuccess)
                {
                    //  CtrlDispatcher.Instance.Dispatch(CtrlMsg.WatchIntVideoFinish);

                    Debug.Log($"ShowInterstitial key==== {key}");
                    if (key == "AfterReward")
                    {
                        NetworkKit.BuriedPoint(BuriedPointEvent.Apple_pay_event, BuriedPointEvent.afterRewardAdEnd, 1);
                    }

                    AdOverEvent(2);
                }
            });



        }
        private static int Interstitial_num = 0;
        private enum DynamicType : int
        {
            /// <summary>
            /// 累计
            /// </summary>
            Max = 0,

            /// <summary>
            /// 当前
            /// </summary>
            Curr
        }

        public static string GetItemSum(int id, decimal sum)
        {
            if (id == 102)
            {
                if (sum == 0)
                {
                    return "0";
                }

                return $"{sum:N}";
            }

            if (sum == 0)
            {
                return "0";
            }

            return GetNoDecimalUnitStr((int)sum);
        }

        public static Dictionary<string, GObject> gObjectDic = new Dictionary<string, GObject>();
        public static Dictionary<string, Vector2> posDic = new Dictionary<string, Vector2>();

        public static void SetGObject(string name, GObject gObject)
        {
            gObjectDic[name] = gObject;
        }

        public static void SetGuidePos(string key, GObject value)
        {
            if (value != null)
            {
                posDic[key] = GetUICenterPosition(value);
            }
        }

        public static void SetGuidePos(string key, Vector2 value)
        {
            posDic[key] = value;
        }

        public static Vector2 GetUICenterPosition(GObject gObject, bool isCenter = false)
        {
            Vector2 centerPot = Vector2.zero;
            if (!isCenter)
            {
                centerPot = gObject.size / 2;
            }

            return gObject.LocalToRoot(Vector2.zero, GRoot.inst) + centerPot;
        }

        public static void PlayFGUIFx(Transition transition, bool isReset = true,
            PlayCompleteCallback onCompleted = null)
        {
            if (isReset)
            {
                if (transition.playing)
                {
                    transition.Stop();
                }
            }

            if (!transition.playing)
            {
                transition.Play();
            }

            transition.SetCompleteEvent(onCompleted);
        }

        public static int GetTomorrowCountTime()
        {
            var today = DateTime.Now;
            return 86400 - today.Hour * 3600 - today.Minute * 60 - today.Second;
        }

        public static long GetNowTime(bool isFix = false)
        {
#if BingoBrainRelease1
            return DateTimeBoardk.Instance.GetCurrTimestamp();
#else
            return DateTimeBoardk.Instance.GetServerCurrTimestamp(isFix);
#endif
        }

        public static string LimitName(string name, int length, string suffix = "...")
        {
            if (!string.IsNullOrEmpty(name) && name.Length > length)
            {
                name = name.Substring(0, length) + suffix;
            }

            return name;
        }

        public static void SetName(GTextField gTextField, bool isLimit = false, int length = 6)
        {
            var name = PreferencesMgr.Instance.PlayerName;
            if (isLimit)
            {
                name = LimitName(name, length);
            }

            gTextField.text = name;
        }

        public static void OnRiseUIRecover(int itemId, UILayerType layerType = UILayerType.Top)
        {
            var gObject = GetItemUI(itemId);
            if (gObject == null) return;
            SetUILayer(gObject, gObject.sortingOrder - 500, layerType);
            UI.Instance.ResetGObjectUILayer(gObject);
        }

        public static GComponent GetItemUI(int itemId)
        {
            GComponent gObject = null;
            switch (itemId)
            {
                case 101:
                    {
                        if (UI.Instance.GetDynamicUI(UIConst.SmailUI) is SmailUI topUI2)
                        {
                            gObject = topUI2.ui.btn_coin;
                        }
                        else if (UI.Instance.GetDynamicUI(UIConst.BingoStartUI) is BingoStartUI topUI)
                        {
                            gObject = topUI.ui.btn_coin;
                        }
                    }
                    break;
                case 102:
                    {
                        if (UI.Instance.GetDynamicUI(UIConst.SmailUI) is SmailUI topUI2)
                        {
                            gObject = topUI2.ui.btn_cash;
                        }
                        else if (UI.Instance.GetDynamicUI(UIConst.BingoStartUI) is BingoStartUI topUI)
                        {
                            gObject = topUI.ui.btn_cash;
                        }
                    }

                    break;
                case 110:
                    {
                        if (UI.Instance.GetDynamicUI(UIConst.BingoStartUI) is BingoStartUI topUI)
                        {
                            gObject = topUI.ui.com_carddi;
                        }
                    }
                    break;
            }

            return gObject;
        }

        public static void SetUILayer(GObject gObject, int sortingOrder, UILayerType layerType)
        {
            gObject.sortingOrder = sortingOrder;
            UI.Instance.SetGObjectUILayer(layerType, gObject);
        }

        public static Dictionary<float, string> noDecimalUnitDic = new();

        public static string GetNoDecimalUnitStr(double tmp)
        {
            float num = (float)tmp;

            // if (num < 1000)
            //     return GetNum(num);
            // if (!noDecimalUnitDic.ContainsKey(num))
            //     noDecimalUnitDic.Add(num, HRsac.ConvertUnit(num));
            // return noDecimalUnitDic[num];
            return num.ToString();
        }


        public static Jcna<GoWrapper> goWrapperPool = new();
        private static ShungTik _shungTik;

        public static ShungTik ShungTik
        {
            get { return _shungTik ??= new ShungTik(); }

            private set => _shungTik = value;
        }

        public static GameObject SetEffect(string effectPath, string effectName, GGraph graph,
            bool isResetRotation = false)
        {
            var effect = ShungTik.Get(effectPath, effectName);
            var goWrapper = goWrapperPool.Get();
            goWrapper.SetWrapTarget(effect, false);
            graph.SetNativeObject(goWrapper);
            effect.transform.localPosition = Vector3.zero;
            effect.transform.localScale = Vector3.one * 100;
            if (isResetRotation)
            {
                effect.transform.localEulerAngles = Vector3.zero;
            }

            return effect;
        }

        public static GameObject SetEffect(string effectPath, string effectName, GameObject graph,
            bool isResetRotation = false)
        {
            var effect = ShungTik.Get(effectPath, effectName);
            var goWrapper = goWrapperPool.Get();
            goWrapper.SetWrapTarget(effect, false);
            effect.transform.SetParent(graph.transform);
            effect.transform.localPosition = Vector3.zero;
            effect.transform.localScale = Vector3.one;
            if (isResetRotation)
            {
                effect.transform.localEulerAngles = Vector3.zero;
            }

            return effect;
        }

        public static GameObject SetParticleSystem(string effectPath, string effectName, GGraph graph,
            bool isResetRotation = false)
        {
            var effect = SetEffect(effectPath, effectName, graph, isResetRotation);
            return effect;
        }

        public static SkeletonAnimation SetSpine(string effectPath, string effectName, GGraph graph,
            string animName = null,
            bool isLoop = true,
            bool isResetRotation = false)
        {
            var effect = SetEffect(effectPath, effectName, graph, isResetRotation);
            var spine = effect.GetComponentInChildren<SkeletonAnimation>();
            if (spine != null)
            {
                spine.ClearState();
                if (!animName.IsNullOrWhiteSpace())
                {
                    spine.state?.SetAnimation(0, animName, isLoop);
                }
            }

            return spine;
        }

        public static SkeletonAnimation SetSpine(string effectPath, string effectName, GameObject graph,
            string animName = null,
            bool isLoop = true,
            bool isResetRotation = false)
        {
            var effect = SetEffect(effectPath, effectName, graph, isResetRotation);
            var spine = effect.GetComponentInChildren<SkeletonAnimation>();
            spine.ClearState();
            if (!animName.IsNullOrWhiteSpace())
            {
                spine.state.SetAnimation(0, animName, isLoop);
            }

            return spine;
        }

        public static bool IsGiftSwitch()
        {
            //  return false;
            //  return true;   //zhushi
            // Debug.Log(GetLoginModel().is_magic);
            return GetLoginModel().is_magic;
        }

        public static bool IsOpenGuide()
        {
            return true;
        }

        public static bool IsCanGuide()
        {
            return IsOpenGuide() && IsGiftSwitch();
        }

        public static int Get101()
        {
            return PreferencesMgr.Instance.Currency101;
        }

        public static decimal Get102()
        {
            return PreferencesMgr.Instance.Currency102;
        }

        public static string Get101Str(decimal currency)
        {
            return $"{currency:N0}";
        }

        public static Tween DelayedShowGObject(BaseUI baseUI, params GObject[] gObjects)
        {
            return DelayedShowGObject(baseUI, 1.5f, gObjects);
        }

        public static Tween DelayedShowGObject(BaseUI baseUI, float time = 1.5f, params GObject[] gObjects)
        {
            if (baseUI.isClose)
            {
                return null;
            }

            foreach (var item in gObjects)
            {
                item.visible = false;
            }

            var tween = DOVirtual.DelayedCall(time, () =>
            {
                foreach (var item in gObjects)
                {
                    if (baseUI.isClose)
                    {
                        return;
                    }

                    item.visible = true;
                }
            });

            return tween;
        }

        public static Vector2 WoldToUIPot(Vector3 tar)
        {
            Vector3 screenPos = Camera.main.WorldToScreenPoint(tar);
            screenPos.y = Screen.height - screenPos.y;
            Vector2 pt = GRoot.inst.GlobalToLocal(screenPos);
            return pt;
        }

        public static void OpenEmail()
        {
            var email = "";
            var common = ConfigSystem.GetConfig<CommonModel>();
            if (common != null)
            {
                email = common.contactUs;
            }

            email = "maxyuen001@gmail.com";
            var subject = "Contact Us";
            var body = $"Thanks for your words\n";
            var url = $"mailto:{email}?subject={subject}&body={body}";
            var uri = new Uri(url);
            Application.OpenURL(uri.AbsoluteUri);
            GameHelper.Toast("Trying to call send mail...");
        }

        public static void GetReward(int rewardTypeId, decimal value, RewardOrigin origin, GObject startGObject = null,
            GObject endGObject = null, bool isDialog = true, bool isNeedAd = true, Action<bool> onCompleted = null,
            decimal rate = 1)
        {
            var rewardData = new RewardData();
            var rewardSingleData = new Goda(rewardTypeId, value, origin)
            {
                multiRate = rate
            };

            if (startGObject != null)
            {
                rewardSingleData.startPosition = GetUICenterPosition(startGObject);
            }

            if (endGObject != null)
            {
                rewardSingleData.endPosition = GetUICenterPosition(endGObject);
            }

            rewardData.AddReward(rewardSingleData);
            if (isDialog)
            {
                rewardData.displayType = RewardDisplayType.RewardFly | RewardDisplayType.Dialog |
                                         RewardDisplayType.ValueChange;
                rewardData.condition = isNeedAd ? RewardCondition.AD : RewardCondition.None;
            }
            else
            {
                rewardData.displayType = RewardDisplayType.RewardFly | RewardDisplayType.ValueChange;
            }

            rewardData.AddCompleted(onCompleted);
            GameDispatcher.Instance.Dispatch(BingoInfo.GetReward, rewardData);
        }

        public static void GetReward(int rewardTypeId, decimal value, RewardOrigin origin,
            Vector3 startPosition = default,
            Vector3 endPosition = default, bool isDialog = true, bool isNeedAd = true, Action<bool> onCompleted = null,
            decimal rate = 1)
        {
            var rewardData = new RewardData();
            var rewardSingleData = new Goda(rewardTypeId, value, origin)
            {
                multiRate = rate
            };

            if (startPosition != default)
            {
                rewardSingleData.startPosition = startPosition;
            }

            if (endPosition != default)
            {
                rewardSingleData.endPosition = endPosition;
            }

            rewardData.AddReward(rewardSingleData);
            if (isDialog)
            {
                rewardData.displayType = RewardDisplayType.RewardFly | RewardDisplayType.Dialog |
                                         RewardDisplayType.ValueChange;
                rewardData.condition = isNeedAd ? RewardCondition.AD : RewardCondition.None;
            }
            else
            {
                rewardData.displayType = RewardDisplayType.RewardFly | RewardDisplayType.ValueChange;
            }

            rewardData.AddCompleted(onCompleted);
            GameDispatcher.Instance.Dispatch(BingoInfo.GetReward, rewardData);
        }

        public static void GetRewardOnly(int rewardTypeId, decimal value, RewardOrigin origin,
            Action<bool> onCompleted = null, GObject startGObject = null, GObject endGObject = null, decimal rate = 1)
        {
            GetReward(rewardTypeId, value, origin, startGObject, endGObject, false, false, onCompleted, rate);
        }

        public static void GetRewardOnly1(int rewardTypeId, decimal value, RewardOrigin origin,
            Action<bool> onCompleted = null, Vector3 startPosition = default, Vector3 endPosition = default,
            decimal rate = 1)
        {
            GetReward(rewardTypeId, value, origin, startPosition, endPosition, false, false, onCompleted, rate);
        }

        public static string Get102Str(decimal currency102 = -1)
        {
            if (currency102 == -1)
            {
                currency102 = PreferencesMgr.Instance.Currency102;
            }

            if (IsGiftSwitch())
            {
                return $"${currency102:N}";
            }
            else
            {
                return $"{currency102:N}";
            }
        }
        public static string Get102Str_new(decimal currency102 = -1)
        {
            if (currency102 == -1)
            {
                currency102 = PreferencesMgr.Instance.Currency102;
            }

            if (IsGiftSwitch())
            {
                if (isRDExchangeMode())
                {
                    return $"{currency102:N}";
                }
                else
                {
                    return $"${currency102:N}";
                }
            }
            else
            {
                currency102 = (int)currency102;
                return $"{currency102:N0}";
            }
        }
        public static T GetConfig<T>()
        {
            return ConfigSystem.GetConfig<T>();
        }

        public static CommonModel GetCommonModel()
        {
            return ConfigSystem.GetConfig<CommonModel>();
        }

        public static bool IsCommonCard(CardEntity card)
        {
            return !card.data.isSelect && !card.data.isCoin && card.data.type == CardPropType.none &&
                   !card.data.isDelaySelect;
        }

        public static Out101 GetDynamicVersion_Coin()
        {
            var outCoinModel = ConfigSystem.GetConfig<Out101Model>();
            foreach (Out101 item in outCoinModel.dataList)
            {
                int min = item.totalCoin[0];
                int max = item.totalCoin[1];
                if (max == -1)
                {
                    max = int.MaxValue;
                }

                double val = 0;
                if (GetCommonModel().DynamicType == (int)DynamicType.Max)
                {
                    val = PreferencesMgr.Instance.Max101;
                }
                else if (GetCommonModel().DynamicType == (int)DynamicType.Curr)
                {
                    val = PreferencesMgr.Instance.Currency101;
                }

                if (val >= min && val <= max)
                {
                    return item;
                }
            }

            return outCoinModel.dataList.Last();
        }

        public static Out102 GetDynamicVersion_Cash()
        {
            var outCashModel = ConfigSystem.GetConfig<Out102Model>();
            foreach (Out102 item in outCashModel.dataList)
            {
                float min = item.totalCash[0];
                float max = item.totalCash[1];
                if (max == -1)
                {
                    max = float.MaxValue;
                }

                double val = 0;
                if (GetCommonModel().DynamicType == (int)DynamicType.Max)
                {
                    val = (double)PreferencesMgr.Instance.Max102;
                }
                else if (GetCommonModel().DynamicType == (int)DynamicType.Curr)
                {
                    val = (double)PreferencesMgr.Instance.Currency102;
                }

                if (val >= min && val <= max)
                {
                    return item;
                }
            }

            return outCashModel.dataList.Last();
        }

        public static void GetRewardExtra(int rewardTypeId, decimal value, int cont_index = 0,
            Action<bool> onCompleted = null, Vector3 startPosition = default)
        {
            Debug.Log(rewardTypeId);
            Debug.Log("????????????????????");
            var val = RewardedVal.Get(rewardTypeId, (double)value);
            val.cont_index = cont_index;
            val.IsMulti = true;
            //val.StartPot = startPosition;

            val.onfinish = onCompleted;
            //Debug.Log(JsonConvert.SerializeObject(val));
            UICtrlDispatcher.Instance.Dispatch(SkinInfo.ExtraItemUI_Open, val);
        }

        public static AdReward GetChanceByIdAndNum(int id, int num = 0)
        {
            if (id == 102) id = 101;
            var adRewardModel = GetConfig<AdRewardModel>();
            return adRewardModel.GetDataList().FirstOrDefault(vo =>
                vo.reward == id && (vo.rewardAmount == 0 || vo.rewardAmount == num));
        }

        public static float GetDynamicReward(int id, float[] rewardArr)
        {
            if (rewardArr == null || rewardArr.Length == 0)
            {
                return 0;
            }

            var rewardIndex = GetDynamicIndex(id);
            if (rewardIndex < rewardArr.Length)
            {
                return rewardArr[rewardIndex];
            }

            return rewardArr[rewardArr.Length - 1];
        }

        public static int GetDynamicIndex(int id)
        {
            if (id == 101)
            {
                return GetDynamicVersion_Coin().id - 1;
            }

            if (id == 102)
            {
                return GetDynamicVersion_Cash().id - 1;
            }

            return 0;
        }

        public static bool IsCanSignInToday()
        {
            var signInModel = ModuleBoardk.Instance.GetModel(ModelConst.JTodModel) as JTodModel;
            if (signInModel == null)
            {
                return false;
            }

            var signInDay = signInModel.GetDailyDonusDay();
            var dailyBonusItem = PreferencesMgr.Instance.DailyBonusItemLst[signInDay - 1];

            return !dailyBonusItem.IsCollect;
        }

        public static string GetDynamicVersion()
        {
            return GetDynamicVersion_Coin().id + GetDynamicVersion_Cash().id.ToString();
        }

        public const int sunSecond = 86400;
        private static Dictionary<float, string> numDic = new();
        public static string trace_id;
        private static LoginModel loginModel;
        public static Dictionary<string, bool> statusDic = new Dictionary<string, bool>();
        public static Dictionary<string, Dictionary<string, bool>> statusDic2 = new Dictionary<string, Dictionary<string, bool>>();
        internal static void PostFunnelLogin(string str, bool payload = false)
        {
            //Debug.Log(str);
            if (statusDic.TryGetValue(str, out var status))
            {
                if (status)
                {
                    return;
                }
            }
            loginModel = GetLoginModel();
            if (str == "bootstrap")
            {
                long timestamp = DateTime.Now.ToUniversalTime().Ticks - 621355968000000000;
                trace_id = timestamp.ToString();
            }
            long user_id = 0;
            if (loginModel != null && loginModel.uid != 0) user_id = loginModel.uid;
            string play_object = "";
            if (str == "afRecv" || str == "loginRecv")
            {
                play_object = payload ? "success" : "fail";
            }

            login_class requestData = new login_class()
            {
                uid = user_id,
                trace_id = trace_id,
                device_id = SystemInfo.deviceUniqueIdentifier,
                pack_name = NetworkMsg.Identifier,
                version = Application.version,
                channel = BingoBea.Instance.attribution,
                type = str,
                payload = play_object
            };


            Debug.Log(user_id);
            statusDic.Add(str, true);
            NetworkKit.Post("event/funnelLogin", requestData, (isSuccess, data) =>
               {
               });
        }
        public static LoginModel GetLoginModel()
        {
            return LoginModel.Instance;
        }
        public static void ShowTips(string val, bool isLangue = false)
        {
            var valStr = val;
            if (isLangue)
            {
            }

            var tipsData = TipsData.GetTips(valStr);
            UICtrlDispatcher.Instance.Dispatch(SkinInfo.JTipsUI_Open, tipsData);
        }
        public static bool CheckAccountValidly(string account)
        {
            return CheckEMailValidly(account);
        }

        public static bool CheckEMailValidly(string eMail)
        {
            if (eMail.IsNullOrWhiteSpace())
            {
                return false;
            }


            const string expression =
                @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";
            return Regex.IsMatch(eMail, expression);
        }
        public static bool CheckNameValidly(string name)
        {
            if (string.IsNullOrEmpty(name))
            {
                return false;
            }


            const string expression = @"^[a-zA-Z]*$";
            return Regex.IsMatch(name, expression);
        }

        public static void ShowLoading(float min = 0.2f, float max = 1f, Action onCompleted = null)
        {
            ShowLoading(UnityEngine.Random.Range(min, max), onCompleted);
        }
        public static void ShowLoading(float time, Action onCompleted = null)
        {
            UICtrlDispatcher.Instance.Dispatch(SkinInfo.NetLoadingUI_Open);
            // TimerHelper.mEasy.AddTimer(time, () =>
            // {
            DOVirtual.DelayedCall(time, () =>
            {
                UICtrlDispatcher.Instance.Dispatch(SkinInfo.NetLoadingUI_Close);
                onCompleted?.Invoke();
            });

            //});
        }
        public static string TimeFormat(int second, CountDownType countDownType = CountDownType.Second,
    string dayFormat = "")
        {
            var result = new StringBuilder();
            if (second < 0)
            {
                second = 0;
            }

            if (countDownType == CountDownType.Second)
            {
                result.Append(second);
                return result.ToString();
            }

            int tmpSecond;


            if (second >= 60)
            {
                tmpSecond = second % 60;
            }
            else
            {
                tmpSecond = second;
            }

            result.Append(tmpSecond);

            if (tmpSecond < 10)
            {
                result.Insert(0, 0);
            }


            int tmpMin = second / 60;

            if (countDownType == CountDownType.Minute)
            {
                result.Insert(0, ":");
                result.Insert(0, tmpMin);
                return result.ToString();
            }


            int tmpHour = tmpMin / 60;

            if (countDownType == CountDownType.Hour)
            {
                if (tmpMin >= 60)
                {
                    tmpMin %= 60;
                }

                result.Insert(0, ":");
                result.Insert(0, tmpMin);
                if (tmpMin < 10)
                {
                    result.Insert(0, 0);
                }

                result.Insert(0, ":");
                result.Insert(0, tmpHour);
                if (tmpHour < 10)
                {
                    result.Insert(0, 0);
                }

                return result.ToString();
            }

            int tmpDay = tmpHour / 24;

            if (countDownType == CountDownType.Day)
            {
                if (tmpMin >= 60)
                {
                    tmpMin %= 60;
                }

                result.Insert(0, ":");
                result.Insert(0, tmpMin);
                if (tmpMin < 10)
                {
                    result.Insert(0, 0);
                }

                if (tmpHour >= 24)
                {
                    tmpHour %= 24;
                }

                result.Insert(0, ":");
                result.Insert(0, tmpHour);

                if (tmpHour < 10)
                {
                    result.Insert(0, 0);
                }

                if (string.IsNullOrEmpty(dayFormat))
                {
                    dayFormat = "Days";
                }

                result.Insert(0, $" {dayFormat} ");
                result.Insert(0, tmpDay);
            }

            return result.ToString();
        }
        public static void SendLogToServer(string message, string stacktrace, LogType type)
        {
            // 如果只需要日期部分，可以使用ToShortDateString()或ToString("yyyy-MM-dd")等进行格式化
            if (!GameHelper.GetLoginModel().debug_log) return;
            System.DateTime currentDate = System.DateTime.Now;
            // Debug.Log("1111111111111111");
            var formattedDate = currentDate.ToString("yyyy_MM_dd_HH_mm");
            var md5Str = MD5Kit.GetStringMD5(message + stacktrace);
            if (!statusDic2.ContainsKey(formattedDate))
            {
                statusDic2.Add(formattedDate, new Dictionary<string, bool>());
            }
            if (!statusDic2[formattedDate].ContainsKey(md5Str))
            {
                statusDic2[formattedDate].Add(md5Str, false);
            }
            //Debug.Log($"SendLogToServer requestData========={formattedDate} \nmd5Str=== {md5Str}");
            if (statusDic2[formattedDate][md5Str])
            {
                return;
            }
            long user_id = 0;
            if (loginModel != null && loginModel.uid != 0) user_id = loginModel.uid;

            ErrorClass requestData = new ErrorClass
            {
                uid = user_id,
                device = SystemInfo.deviceModel,
                os_ver = SystemInfo.operatingSystem,
                network = GetNetworkType(),
                device_id = SystemInfo.deviceUniqueIdentifier,
                pack_name = NetworkMsg.Identifier,
                version = Application.version,
                channel = BingoBea.Instance.attribution,
                level = type == 0 ? "error" : "warn",
                message = message,
                stacktrace = stacktrace
            };
            statusDic2[formattedDate][md5Str] = true;

            //  Debug.Log($"SendLogToServer requestData1========={JsonConvert.SerializeObject(requestData)}");
            NetworkKit.Post("event/cliDebugLog", requestData, (isSuccess, data) =>
             {

             });
        }
        private static string GetNetworkType()
        {
            string types = "Not Connected";
            switch (Application.internetReachability)
            {
                case NetworkReachability.ReachableViaCarrierDataNetwork:
                    types = "Mobile Data";
                    break;
                case NetworkReachability.ReachableViaLocalAreaNetwork:
                    types = "Wi-Fi";
                    break;
            }
            return types;
        }
        public static bool showGameUI = true;
        public static int GetItemNumber(int type)
        {
            if (type == 0)
            {
                return PlayerPrefs.GetInt("_out", 0);
            }
            else if (type == 1)
            {
                return PlayerPrefs.GetInt("_back", 0);
            }
            else if (type == 2)
            {
                return PlayerPrefs.GetInt("_refresh", 0);
            }
            return 0;
        }
        public static void SetItemNumber(int type, int value)
        {
            if (type == 0)
            {
                PlayerPrefs.SetInt("_out", value);
            }
            else if (type == 1)
            {
                PlayerPrefs.SetInt("_back", value);
            }
            else if (type == 2)
            {
                PlayerPrefs.SetInt("_refresh", value);
            }

        }
        public static void AddItemNumber(int type, int change)
        {
            if (type == 0)
            {
                PlayerPrefs.SetInt("_out", PlayerPrefs.GetInt("_out", 0) + change);
            }
            else if (type == 1)
            {
                PlayerPrefs.SetInt("_back", PlayerPrefs.GetInt("_back", 0) + change);
            }
            else if (type == 2)
            {
                PlayerPrefs.SetInt("_refresh", PlayerPrefs.GetInt("_refresh", 0) + change);
            }

        }

        public static int GetLevel()
        {
            return 30;  //zhushi
            return PlayerPrefs.GetInt("_level", 1);

        }
        public static void SetLevel(int level)
        {
            PlayerPrefs.SetInt("_level", level);
        }
        public static int GetLevelstate()
        {
            return PlayerPrefs.GetInt("_lvstate", 3);//4种，数字3为可以用广告和金币复活，2为只能用广告，1为只能用金币。0为不能复活
        }

        public static void SetLevelstate(int state)
        {
            PlayerPrefs.SetInt("_lvstate", state);
        }

        public static int GetGoldNumber()
        {
            // return PlayerPrefs.GetInt("_gold", 50);
            int goldNum = (int)Get101();

            return goldNum;
        }
        public static void AddGoldNumber(int value)
        {
            AddGold(value);
        }
        public static void AddGold(int a)
        {
            PreferencesMgr.Instance.Currency101 += a;

        }
        public static void AddGold(float a)
        {
            PreferencesMgr.Instance.Currency101 = (int)((float)PreferencesMgr.Instance.Currency101 + a);

        }

        public static bool CheckGoldNumber(int target)
        {
            return GetGoldNumber() >= target;
        }

        public static void AddGameTime()
        {
            int a = PlayerPrefs.GetInt("_time", 0) + 1;
            PlayerPrefs.SetInt("_time", a);

        }
        public static int GetGameTime()
        {
            //  return 9999;
            return PlayerPrefs.GetInt("_time", 0);

        }

        public static void SetGameday()
        {

            PlayerPrefs.SetInt("_day", DateTime.Now.Day);

        }
        public static int GetGameday()
        {
            return PlayerPrefs.GetInt("_day", 0);
        }


        public static int GetGameExp()
        {
            //   return 9999;
            return PlayerPrefs.GetInt("_exp", 0);

        }
        public static void AddGameExp(int change)
        {
            PlayerPrefs.SetInt("_exp", GetGameExp() + change);
        }
        public static void ResetGameExp()
        {
            PlayerPrefs.SetInt("_exp", 0);
        }

        public static int look_interad_numbers = 0;
        public static bool is_first_login = true;
        public static void addInterAdnumber()
        {
            look_interad_numbers++;
            if (!SaveData.GetSaveobject().is_get_removead && look_interad_numbers >= ConfigSystem.GetConfig<CommonModel>().playtimes)
            {
                look_interad_numbers = 0;
                if (UnityEngine.Random.Range(0, 100) < ConfigSystem.GetConfig<CommonModel>().interstitialtype)
                {
                    // if (UI.Instance.IsExistUI(UIConst.H5UI)) GameHelper.ShowInterstitial("interstitial_h5reward");
                    // else UICtrlDispatcher.Instance.Dispatch(UICtrlMsg.AdcomingUI_Open);
                    GameHelper.ShowInterstitial("interstitial_Ad");
                }
            }
        }
        public static int getBattleLv()
        {
            int exp = GetGameExp();
            List<Passportrewards> list = ConfigSystem.GetConfig<PassportrewardsModel>().dataList;
            for (int i = 0; i < list.Count; i++)
            {
                if (exp < list[i].Eliminating_quantity)
                {
                    return i;

                }
            }
            return list.Count;
        }
        public static float[] GetRewardValue(int type)
        {
            var currentRedeemLevel = 1;

            // for (var i = 0; i < PreferencesMgr.Instance.MakeupTaskHistory.Count; i++)
            // {
            //     var task = PreferencesMgr.Instance.MakeupTaskHistory[i];

            //     // if (task.status == MakeupTaskStatus.Inline)
            //     // {
            //     //     currentRedeemLevel++;

            //     // }
            // }

            // Debug.Log($"GetRewardValue=====================currentRedeemLevel {currentRedeemLevel} \n type: {type}");

            if (currentRedeemLevel > 3)
            {
                currentRedeemLevel = 3;
            }

            var currentIndex = GetValueIndex(currentRedeemLevel);
            Debug.Log("++++++++++++++++++++++++++++==" + currentIndex);
            if (currentIndex != -1)
            {
                if (type == 0)
                {
                    var vos = ConfigSystem.GetConfig<SmallrewardNumModel>().dataList;
                    SmallrewardNum rewardNumVo = vos[currentIndex];
                    return GetValue(rewardNumVo, currentRedeemLevel);

                }
                else if (type == 1)
                {
                    var vos = ConfigSystem.GetConfig<LargerewardNumModel>().dataList;
                    LargerewardNum rewardNumVo = vos[currentIndex];
                    return GetValue(rewardNumVo, currentRedeemLevel);

                }
                else if (type == 2)
                {
                    var vos = ConfigSystem.GetConfig<RewardNumModel>().dataList;
                    rewardNum rewardNumVo = vos[currentIndex];
                    return GetValue(rewardNumVo, currentRedeemLevel);

                }

            }
            return new float[] { 0, 0 };



        }
        private static int GetValueIndex(int index)
        {
            var cash = Get102();
            var vos = ConfigSystem.GetConfig<RewardNumModel>().dataList;

            var currentIndex = -1;
            if (cash < 0)
            {
                currentIndex = 0;
            }
            else
            {
                for (var i = 0; i < vos.Count; i++)
                {
                    var rewardNumVo = vos[i];
                    var cashArray = index switch
                    {
                        1 => rewardNumVo.cash_1,
                        2 => rewardNumVo.cash_2,
                        3 => rewardNumVo.cash_3,
                        _ => default
                    };

                    if (i < vos.Count - 1)
                    {
                        if (cash >= (decimal)cashArray[0] && cash < (decimal)cashArray[1])
                        {
                            currentIndex = i;
                            break;
                        }
                    }
                    else
                    {
                        if (cash >= (decimal)cashArray[0])
                        {
                            currentIndex = i;
                            break;
                        }
                    }
                }
            }

            return currentIndex;
        }
        private static float[] GetValue(SmallrewardNum rewardNumVo, int level)
        {

            float[] normalArray = null;
            var videoRewardRate = 0f;
            switch (level)
            {
                case 1:

                    normalArray = rewardNumVo.nor_1;
                    videoRewardRate = rewardNumVo.rv_1;

                    break;
                case 2:

                    normalArray = rewardNumVo.nor_2;
                    videoRewardRate = rewardNumVo.rv_2;
                    break;
                case 3:

                    normalArray = rewardNumVo.nor_3;
                    videoRewardRate = rewardNumVo.rv_3;

                    break;
            }
            float normalValue = UnityEngine.Random.Range(normalArray[0], normalArray[1]);
            normalValue = (float)Math.Round(normalValue, 2);
            return new float[] { normalValue, videoRewardRate };
        }
        private static float[] GetValue(LargerewardNum rewardNumVo, int level)
        {

            float[] normalArray = null;
            var videoRewardRate = 0f;
            switch (level)
            {
                case 1:

                    normalArray = rewardNumVo.nor_1;
                    videoRewardRate = rewardNumVo.rv_1;

                    break;
                case 2:

                    normalArray = rewardNumVo.nor_2;
                    videoRewardRate = rewardNumVo.rv_2;
                    break;
                case 3:

                    normalArray = rewardNumVo.nor_3;
                    videoRewardRate = rewardNumVo.rv_3;

                    break;
            }
            float normalValue = UnityEngine.Random.Range(normalArray[0], normalArray[1]);
            normalValue = (float)Math.Round(normalValue, 2);
            return new float[] { normalValue, videoRewardRate };
        }
        private static float[] GetValue(rewardNum rewardNumVo, int level)
        {

            float[] normalArray = null;
            var videoRewardRate = 0f;
            switch (level)
            {
                case 1:

                    normalArray = rewardNumVo.nor_1;
                    videoRewardRate = rewardNumVo.rv_1;

                    break;
                case 2:

                    normalArray = rewardNumVo.nor_2;
                    videoRewardRate = rewardNumVo.rv_2;
                    break;
                case 3:

                    normalArray = rewardNumVo.nor_3;
                    videoRewardRate = rewardNumVo.rv_3;

                    break;
            }
            float normalValue = UnityEngine.Random.Range(normalArray[0], normalArray[1]);
            normalValue = (float)Math.Round(normalValue, 2);
            return new float[] { normalValue, videoRewardRate };
        }
        public static bool IsTemporaryEnd;
        public static void ShowVideoAd(string adId, Action<bool> onCompleted)
        {
            MaxADKit.ShowVideo(adId, isSuccess =>
            {
                if (isSuccess)
                {
                    CtrlDispatcher.Instance.Dispatch(CtrlMsg.WatchVideoFinish);
                    look_interad_numbers = 0;

                    AdOverEvent(1);

                }
                else
                {
                    ShowTips("Ads Not Ready", true);
                }

                onCompleted?.Invoke(isSuccess);
            });
        }
        public static Dictionary<string, string> adCallbackInfo = new Dictionary<string, string>();
        public static void sendHighRevenueToAF()
        {
            float purch_number = GameHelper.GetCommonModel().afSendNum;
            string countryCode = "USD";
            adCallbackInfo.Clear();
            adCallbackInfo.Add("appsflyer_id", AppsFlyer.getAppsFlyerId());
            adCallbackInfo.Add("customer_user_id", GameHelper.GetLoginModel().uid.ToString());
            adCallbackInfo.Add("af_currency", countryCode);
            adCallbackInfo.Add("af_revenue", purch_number.ToString());

            AppsFlyer.sendEvent("af_new_purchase", adCallbackInfo);

            Debug.Log($"AppsFlyer sendEvent af_new_purchase {purch_number}");
        }
        public static void SetSelfAvatar(GLoader gLoader)
        {
            var avatarId = PreferencesMgr.Instance.PlayerAvatarId;
            EyesHarmony.SetAvatarToLoader(avatarId, gLoader);
        }
        // public static bool needShowLevelstate(int id = -1)
        // {

        //     var makeupTaskData = PreferencesMgr.Instance.MakeupTaskHistory.Last();
        //     Debug.Log(makeupTaskData.tableId);
        //     var vo = ConfigSystem.GetConfig<MakeupModel>().GetData(makeupTaskData.tableId);
        //     Debug.Log(vo);
        //     int lv = vo.id;
        //     int a = PlayerPrefs.GetInt("cash_lv", 0);
        //     if (id != -1) lv = id + 1;
        //     if (a < lv)
        //     {
        //         return true;
        //     }

        //     return false;
        // }
        public static bool checkGoldNumber(int target)
        {
            return PreferencesMgr.Instance.Currency101 >= target ? true : false;
        }
        public static Dictionary<int, int> activeTimes = new Dictionary<int, int>();
        public static Dictionary<int, int> activeTimes_saveingpot = new Dictionary<int, int>();
        public static int GetBattleLv_Index()
        {
            int exp = GetGameExp();
            List<Passportrewards> list = ConfigSystem.GetConfig<PassportrewardsModel>().dataList;
            for (int i = 0; i < list.Count; i++)
            {
                if (exp < list[i].Eliminating_quantity)
                {
                    return i;

                }
            }
            return list.Count - 1;
        }

        /// <summary>
        /// 检查是否有网络
        /// </summary>
        /// <returns>true：有网， false：没网 </returns>
        public static bool IsConnect()
        {
            return NetworkKit.GetNetworkType() != NetworkType.notConnected;
        }

        /// <summary>
        /// 看完广告事件上报
        /// </summary>
        /// <param name="type">1:激励 2:插屏</param>
        public static void AdOverEvent(int type)
        {

            RespAdEventData respData = new()
            {
                type = type
            };

            NetworkKit.PostWithHeader<RespAdEventData>("event/adWatchOver", respData, (isSuccess, obj) =>
            {

            });
        }

        /// <summary>
        /// 玩法时长上报
        /// </summary>
        /// <param name="gameType">玩法类型：1:羊了个羊 2:单词接龙 3:关不住我</param>
        public static void PlayGameTimeEvent(int gameType, Action action = null)
        {
            m_gameTimes = GetPlayGameTimes();

            if (m_gameTimes == 0) return;
            RespGameTimeEventData respData = new()
            {
                type = gameType,
                second = m_gameTimes
            };

            m_gameTimes = 0;

            PlayerPrefs.SetInt("game_times", m_gameTimes);

            NetworkKit.PostWithHeader<RespGameTimeEventData>("event/gameTime", respData, (isSuccess, obj) =>
            {
                // Debug.Log($"PlayGameTimeEvent==== {m_gameTimes}");
                action?.Invoke();
            });
        }
        private static int m_gameTimes = 0;

        public static void SetGameTimes()
        {
            m_gameTimes++;
            PlayerPrefs.SetInt("game_times", m_gameTimes);
        }

        public static int GetPlayGameTimes()
        {
            return PlayerPrefs.GetInt("game_times", 0);
        }


        /// <summary>
        /// 是否能关闭结算界面（必须等调控接口返回数据后才能关闭）
        /// </summary>
        private static bool isCanCloseResultView = false;

        public static bool GetCloseResult()
        {
            if (!IsConnect())
            {
                ShowTips("The network connection is abnormal.");
            }

            return isCanCloseResultView;
        }
        public static void SetCloseResult(bool isCan)
        {
            isCanCloseResultView = isCan;
        }

        /// <summary>
        /// 第几个玩法调控表
        /// </summary>
        public static int conf_num = 1;
        /// <summary>
        /// 玩法调控，请求配置
        /// </summary>
        public static void RequestGameConfig()
        {
            NetworkKit.PostWithHeader<ResGameConfigData>("game/regulate", null, (isSuccess, obj) =>
            {
                if (isSuccess)
                {
                    Debug.Log($"RequestGameConfig==== {obj.conf_num}");
                    PlayerPrefs.SetInt("game_conf_num", obj.conf_num);
                    conf_num = obj.conf_num;
                }

                isCanCloseResultView = true;
                UICtrlDispatcher.Instance.Dispatch(UICtrlMsg.PayloadingUI_Close);
            });
        }

        /// <summary>
        /// 是否是广告兑换模式
        /// </summary>
        /// <returns>true:广告兑换  -- false:三方支付</returns>
        public static bool IsAdModelOfPay()
        {
            bool isAd = true;

            if (IsGiftSwitch() && GetLoginModel().enwp == 1)
            {
                isAd = false;
            }

            return isAd;
        }
        public static List<int> makeupLevels = new();
        public static void SetLevelsList()
        {
            makeupLevels.Clear();
            List<makeup> makeup_list = ConfigSystem.GetConfig<MakeupModel>().dataList;
            for (int i = 0; i < makeup_list.Count; i++)
            {
                makeupLevels.Add(makeup_list[i].levels_need);
            }
            // Debug.Log($"barry makeupLevels-======== {SerializeUtil.ToJson(makeupLevels)}");
        }

        /// <summary>
        /// 特定等级的
        /// </summary>
        /// <returns></returns>
        public static bool IsShowLevelTips()
        {
            SetLevelsList();
            bool isShow = false;
            for (int i = 0; i < makeupLevels.Count; i++)
            {
                if (IsGiftSwitch() && GetLevel() == makeupLevels[i])
                {
                    isShow = true;
                    break;
                }

            }

            return isShow;
        }
        public static long getNowTimeByMillisecond()
        {
#if !JarvisRelease
            return DateTimeBoardk.Instance.GetCurrTimesTampByMillisecond();
            // return DateTimeManager.Instance.GetServerCurrTimestamp();
#else
                return DateTimeBoardk.Instance.GetServerCurrTimestampByMillisecond();
#endif
        }
        public static void sendRevenueToServer(string eventname, string eventproperty, int integer)
        {
            NetworkKit.BuriedPoint(eventname, eventproperty, integer);
        }
        public static bool InToday(long time, int offset = 0, bool isInclude = false)
        {
            DateTime oldDate = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
            oldDate = oldDate.AddSeconds(time);
            oldDate = new DateTime(oldDate.Year, oldDate.Month, oldDate.Day);


            var yesterday = DateTimeBoardk.Instance.GetCurrDateTime().AddDays(offset);

            yesterday = new DateTime(yesterday.Year, yesterday.Month, yesterday.Day);
            if (isInclude)
            {
                return oldDate >= yesterday;
            }

            return oldDate > yesterday;
        }
        public static bool isRDExchangeMode()
        {
            //  return false;//zhushi
            //return true;//zhushi
            return SaveData.GetSaveobject().ExchangeModeToggle == 1;
        }
        public static string getDesByKey(string key)
        {
            Debug.Log(key);
            Debug.Log(JsonConvert.SerializeObject(ConfigSystem.GetConfig<ExchangeDesModel>().dataList));
            if (isRDExchangeMode())
            {
                string str = ConfigSystem.GetConfig<ExchangeDesModel>().dataList.FirstOrDefault(data => data.des_key == key)?.Mode_1 ?? "";
                if (str != "")
                {
                    str = str.Replace("<img1>", "<img src='ui://pmf3wbji112epi7'/>")
                            .Replace("<img2>", "<img src='ui://o9974uc5t9w7c3'/>");
                }
                return str;
            }
            else
            {
                return ConfigSystem.GetConfig<ExchangeDesModel>().dataList.FirstOrDefault(data => data.des_key == key)?.Mode_0 ?? "";
            }
        }
        public static string getChString(decimal ch)
        {
            if (GameHelper.isRDExchangeMode())
            {
                string str = "<img src='ui://pmf3wbji112epi7'/>";
                return str + $" {ch:N}";
            }
            else
            {
                return $"${ch:N}";
            }
        }
        public static string GenerateUniqueKey()
        {
            const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

            string key;
            do
            {
                StringBuilder sb = new StringBuilder();

                sb.Append(GenerateRandomString(chars, 4));
                sb.Append("-");
                sb.Append(GenerateRandomString(chars, 6));
                sb.Append("-");
                sb.Append(GenerateRandomString(chars, 4));

                key = sb.ToString();
            } while (generatedKeys.Contains(key)); // 如果重复就重新生成

            generatedKeys.Add(key); // 添加到集合中
            return key;
        }
        static string GenerateRandomString(string charSet, int length)
        {
            StringBuilder sb = new StringBuilder();
            System.Random random = new System.Random();
            for (int i = 0; i < length; i++)
            {
                int index = random.Next(charSet.Length);
                sb.Append(charSet[index]);
            }
            return sb.ToString();
        }
        private static HashSet<string> generatedKeys = new HashSet<string>();
        public static string getPrice(decimal ch)
        {
            return $"${ch:N}";
        }
        public static string GetPriceInt(decimal ch)
        {
            return $"${ch:N0}";
        }
        public static void CopyText(string text)
        {
#if UNITY_EDITOR_WIN || UNITY_EDITOR_OSX || UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_STANDALONE_LINUX
            GUIUtility.systemCopyBuffer = text;
#elif UNITY_ANDROID
            // CopyToClipboardAndroid(text);

#elif UNITY_IOS
            BrigdeIOS.copyText(text);
#else
            Debug.LogWarning("当前平台不支持复制到剪贴板功能");
#endif
            GameHelper.ShowTips("Copy Succeed");
        }
    }
}

public class RespAdEventData
{
    public int type;
}

public class RespGameTimeEventData
{
    public int type;
    public int second;
}

public class ResGameConfigData
{
    public int conf_num;
}

public class login_class
{

    public long uid;
    public string trace_id;
    public string device_id;
    public string pack_name;
    public string version;
    public string channel;
    public string type;
    public string payload;

}