namespace ScrewsMaster
{
    using System.Text;
    using UnityEngine.Events;
    using System.Collections;
    using UnityEngine.Networking;
    using System.Collections.Generic;
    using Newtonsoft.Json;
    using UnityEngine;
    using System;

    public class NetworkKit
    {
        public static string CDNUrl;

        //打点需要的值-----began----
        public static string trace_id;
        public static string channel_id;
        public static long userId;
        //打点需要的值-----end----
        public static Dictionary<string, bool> statusDic = new Dictionary<string, bool>();
        public static Dictionary<string, Dictionary<string, bool>> statusDic2 = new Dictionary<string, Dictionary<string, bool>>();

        public static string GetCacheToken()
        {
            string token = null;
            if (PlayerPrefsKit.HasKey(PrefsKeyConst.JarvisToken))
            {
                token = PlayerPrefsKit.ReadString(PrefsKeyConst.JarvisToken);
            }

            return token;
        }

        public static void SetCacheToken(string token)
        {
            PlayerPrefsKit.WriteString(PrefsKeyConst.JarvisToken, token);
        }

        private static IEnumerator PostInternal<T>(string url, object requestData, UnityAction<bool, T> onCompleted,
            Dictionary<string, string> header = null)
        {
            //判断token是否失效
            // ReSetToken();

            var requestJson = SerializeUtil.ToJsonIndented(requestData);
            var url2 = url;
#if JarvisRelease
            url2 = Base64Kit.Encode(url);
            requestJson = Base64Kit.Encode(requestJson);
#endif
            var bytes = Encoding.UTF8.GetBytes(requestJson);
            var url1 = NetworkManager.CrazyUrl + url2;
            var loginRequest = new UnityWebRequest(url1, UnityWebRequest.kHttpVerbPOST)
            {
                uploadHandler = new UploadHandlerRaw(bytes),
                downloadHandler = new DownloadHandlerBuffer()
            };

            if (header != null)
            {
                foreach (var keyValuePair in header)
                {
                    loginRequest.SetRequestHeader(keyValuePair.Key, keyValuePair.Value);
                }
            }

            SetRequestContentType(loginRequest);
            Debug.Log($"request url1======= {url1}");
            yield return loginRequest.SendWebRequest();
            Debug.Log($"requestData11111======={url1}=={requestJson}");
            Debug.Log($"requestData22222====={url1}==={JsonConvert.SerializeObject(loginRequest)}");
            if (loginRequest.result is not UnityWebRequest.Result.Success)
            {
                onCompleted?.Invoke(false, default);
            }
            else
            {
                var receiveContent = loginRequest.downloadHandler.text;
#if JarvisRelease
                if (!receiveContent.IsNullOrWhiteSpace())
                {
                    receiveContent = receiveContent.Substring(0, receiveContent.Length - 1);
                    receiveContent = receiveContent.Substring(1);
                    receiveContent = Base64Kit.Decode(receiveContent);
                }
#endif
                Debug.Log(receiveContent);
                var response = SerializeUtil.ToObject<ResponseData>(receiveContent);


#if UNITY_EDITOR
                var respJson = JsonConvert.SerializeObject(response);

                // Debug.Log($"requestData======={url1}=={requestJson}");
                //   Debug.Log($"response========={url1}=={respJson}");
#endif
                if (response?.code == 0)
                {
                    var responseData = SerializeUtil.ToObject<T>(response.data.ToString());
                    onCompleted?.Invoke(true, responseData);
                }
                else
                {
                    onCompleted?.Invoke(false, default);
                }
            }

            loginRequest.Dispose();
        }

        public static void SetRequestContentType(UnityWebRequest request)
        {
            request.SetRequestHeader("Content-Type", "application/json;charset=utf-8");
        }

        public static Coroutine Post<T>(string url, object requestData, UnityAction<bool, T> onCompleted)
        {
            return CrazyAsyKit.StartCoroutine(PostInternal(url, requestData, onCompleted));
        }

        public static Coroutine PostWithHeader<T>(string url, object requestData = null,
            UnityAction<bool, T> onCompleted = null)
        {
            var headers = new Dictionary<string, string> { { "x-token", GetCacheToken() } };
            return CrazyAsyKit.StartCoroutine(PostInternal(url, requestData, onCompleted, headers));
        }

        public static void PostWithHeader<T>(string url, UnityAction<bool, T> onCompleted)
        {
            if (onCompleted != null)
            {
                PostWithHeader<T>(url, null, (isSuccess, obj) => { onCompleted.Invoke(isSuccess, obj); });
            }
            else
            {
                PostWithHeader<T>(url);
            }
        }

        public static void PostWithHeader(string url, object requestData = null, UnityAction<bool> onCompleted = null)
        {
            if (onCompleted != null)
            {
                PostWithHeader<object>(url, requestData, (isSuccess, obj) => { onCompleted?.Invoke(isSuccess); });
            }
            else
            {
                PostWithHeader<object>(url, requestData);
            }
        }

        public static void PostFunnelLogin(RespLoginFunnelData reqData = null)
        {
            if (statusDic.TryGetValue(reqData.type, out var status))
            {
                if (status)
                {
                    return;
                }
            }


            if (reqData.type == "bootstrap")
            {
                long timestamp = DateTime.Now.ToUniversalTime().Ticks - 621355968000000000;
                trace_id = timestamp.ToString();
            }

            var requestData = new RespLoginFunnelData
            {
                uid = userId,
                trace_id = trace_id,
                device_id = SystemInfo.deviceUniqueIdentifier,
                // pack_name = Application.identifier,
                pack_name = NetworkManager.packName,
                version = Application.version,
                channel = SuperApplication.Instance.attribution,
                type = reqData.type,
                payload = reqData.payload
            };

            statusDic.Add(reqData.type, true);
            Debug.Log($"PostFunnelLogin requestData1111========={reqData.type}");
            Post<RespLoginFunnelData>("event/funnelLogin", requestData, (isSuccess, data) =>
            {
                Debug.Log($"PostFunnelLogin responseData2222========={isSuccess}  {reqData.type}");
            });
        }
        public static void SendLogToServer(RespDebugData reqData)
        {
            if (!GameHelper.GetLoginModel().debug_log) return;

            // 如果只需要日期部分，可以使用ToShortDateString()或ToString("yyyy-MM-dd")等进行格式化
            System.DateTime currentDate = System.DateTime.Now;
            var formattedDate = currentDate.ToString("yyyy_MM_dd_HH_mm");

            var md5Str = MD5Kit.GetStringMD5(reqData.message + reqData.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;
            }

            var requestData = new RespDebugData
            {
                uid = userId,
                device = SystemInfo.deviceModel,
                os_ver = SystemInfo.operatingSystem,
                network = GetNetworkType(),
                device_id = SystemInfo.deviceUniqueIdentifier,
                pack_name = NetworkManager.packName,
                version = Application.version,
                channel = SuperApplication.Instance.attribution,
                level = reqData.level,
                message = reqData.message,
                stacktrace = reqData.stacktrace
            };

            statusDic2[formattedDate][md5Str] = true;

            //Debug.Log($"SendLogToServer requestData1========={JsonConvert.SerializeObject(requestData)}");
            Post<RespDebugData>("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 AndroidPointObject androidPointObject = new();
        /*
        * 打点        
        */
        public static void BuriedPoint(string eventname, string eventproperty, int integer)
        {
            if (eventname == BuriedPointEvent.Apple_AD_event || eventname == BuriedPointEvent.Apple_pay_event)
            {
                if (GameHelper.IsAdModelOfPay())
                {
                    eventname = BuriedPointEvent.Apple_AD_event;
                }
                else
                {
                    eventname = MaxPayManager.isIOSPay ? BuriedPointEvent.Apple_ios_pay_event : BuriedPointEvent.Apple_pay_event;
                }
            }

            androidPointObject.@event = eventname;
            androidPointObject.property = eventproperty;
            androidPointObject.n = integer;
            Debug.Log("打点" + JsonConvert.SerializeObject(androidPointObject));
            PostWithHeader<AndroidPointObject>("/event/incrN", androidPointObject, (isSuccess, obj) =>
            {
            });
        }

        private static bool isReqToken = false;
        public static void ReSetToken()
        {
            if (isReqToken) return;
            var nowTimes = GameHelper.GetCurrentTimestamp();
            var passtime = GameHelper.GetLoginModel().expires_at;
            if (passtime - nowTimes > 3600) return;
            isReqToken = true;
            var requestLoginData = new RequestLoginData
            {
#if !UNITY_EDITOR
                device_id = SystemInfo.deviceUniqueIdentifier,
#else
                device_id = "test004010",
#endif
                // device_id = SystemInfo.deviceUniqueIdentifier,
                pack_name = NetworkManager.packName,
                app_version = Application.version,
                //is debug test--------
                channel = SuperApplication.Instance.attribution,
                sim = NetworkManager.haveSimCard
            };
            Post<LoginModel>("login", requestLoginData, (isSuccess, loginData) =>
            {
                if (isSuccess)
                {
                    var loginModel = GameHelper.GetLoginModel();
                    loginModel.token = loginData.token;
                    loginModel.expires_at = loginData.expires_at;
                    SetCacheToken(loginData.token);
                }
                isReqToken = false;
            });
        }

        public class AndroidPointObject
        {
            public string @event;
            public string property;
            public int n;
        }
    }


    public class AndroidPointEvent
    {
        public static string Google_pay_event = "Google_pay_event";

        public static string first_pack_show = "first_pack_show";
        public static string first_pack_click = "first_pack_click";
        public static string first_pack_open = "first_pack_open";
        public static string first_pack_success = "first_pack_success";

        public static string remove_ad_show = "remove_ad_show";
        public static string remove_ad_click = "remove_ad_click";
        public static string remove_ad_open = "remove_ad_open";
        public static string remove_ad_success = "remove_ad_success";

        public static string pass_show = "pass_show";
        public static string pass_click = "pass_click";
        public static string pass_open = "pass_open";
        public static string pass_success = "pass_success";

        public static string buyslot_show = "buyslot_show";
        public static string buyslot_click = "buyslot_click";
        public static string buyslot_open = "buyslot_open";
        public static string buyslot_success = "buyslot_success";

        public static string gold_show = "gold_show";
        public static string gold_click_1 = "gold_click_1";
        public static string gold_click_2 = "gold_click_2";
        public static string gold_click_3 = "gold_click_3";
        public static string gold_click_4 = "gold_click_4";
        public static string gold_open_1 = "gold_open_1";
        public static string gold_open_2 = "gold_open_2";
        public static string gold_open_3 = "gold_open_3";
        public static string gold_open_4 = "gold_open_4";
        public static string gold_success_1 = "gold_success_1";
        public static string gold_success_2 = "gold_success_2";
        public static string gold_success_3 = "gold_success_3";
        public static string gold_success_4 = "gold_success_4";
    }

    public class BuriedPointEvent
    {
        public static string play_event = "Number_of_people_play";
        public static string play_property = "Number_of_people_playing";

        public static string playing_event = "Playing_time";
        public static string playing_property = "Room_type";

        public static string ad_task = "ad_task";
        public static string watch_ad_number = "watch_ad_number";
        public static string finish_ad_number = "finish_ad_number";

        public static string h5_event = "H5_task";
        public static string h5_event_time = "H5_time";
        public static string h5_event_numbers = "finish_H5_number";

        public static string withdraw_behavior = "withdraw_behavior";
        public static string withdraw_message = "withdraw_message";
        public static string withdraw_cash1 = "withdraw_cash1";
        public static string withdraw_cash2 = "withdraw_cash2";
        public static string withdraw_cash3 = "withdraw_cash3";

        public static string Hall_behavior = "Hall_behavior";
        public static string open_hall_number = "open_hall_number";
        //public static string open_hall_people = "open_hall_people";
        public static string collect_fly_number = "collect_fly_number";
        //public static string collect_fly_people = "collect_fly_people";
        public static string fly_ct_number = "fly_ct_number";
        //public static string fly_ct_people = "fly_ct_people";
        public static string annular_finish_number = "annular_finish_number";
        public static string annular_get_number = "annular_get_number";
        public static string annular_ct_number = "annular_ct_number";
        //public static string annular_ct_people = "annular_ct_people";

        public static string video_behavior = "video_behavior";
        public static string watch_ad_people = "watch_ad_people";
        public static string watch_success_ad_people = "watch_success_ad_people";

        public static string video_type = "video_type";
        public static string Rewarded_videos_trigger_number = "Rewarded_videos_trigger_number";
        public static string Rewarded_videos_fill_number = "Rewarded_videos_fill_number";
        public static string Rewarded_videos_dinish_number = "Rewarded_videos_dinish_number";
        public static string Interstitial_videos_trigger_number = "Interstitial_videos_trigger_number";
        public static string Interstitial_videos_fill_number = "Interstitial_videos_fill_number";
        public static string Interstitial_videos_dinish_number = "Interstitial_videos_dinish_number";

        public static string Apple_pay_event = "Pay_Event";

        public static string first_pack_show = "first_pack_show";
        public static string first_pack_click = "first_pack_click";
        public static string first_pack_open = "first_pack_open";
        public static string first_pack_success = "first_pack_success";

        public static string remove_ad_show = "remove_ad_show";
        public static string remove_ad_click = "remove_ad_click";
        public static string remove_ad_success = "remove_ad_success";

        public static string pass_show = "master_pass_show";
        public static string pass_click = "master_pass_click";
        public static string pass_open = "pass_open";
        public static string pass_success = "master_pass_receive";

        public static string AddBoxShow = "add_block_show";
        public static string AddBoxClick = "add_block_click";
        public static readonly string AddBoxPay = "add_block_receive";

        public static string buyslot_show = "buyslot_show";
        public static string buyslot_click = "buyslot_click";
        public static string buyslot_open = "buyslot_open";
        public static string buyslot_success = "buyslot_receive";

        public static string gold_show = "gold_show";
        public static string gold_click = "gold_click";
        // public static string gold_click_2 = "gold_click_2";
        // public static string gold_click_3 = "gold_click_3";
        // public static string gold_click_4 = "gold_click_4";
        // public static string gold_open_1 = "gold_open_1";
        // public static string gold_open_2 = "gold_open_2";
        // public static string gold_open_3 = "gold_open_3";
        // public static string gold_open_4 = "gold_open_4";
        public static string GoldSuccess = "gold_success";
        // public static string gold_success_2 = "gold_success_2";
        // public static string gold_success_3 = "gold_success_3";
        // public static string gold_success_4 = "gold_success_4";
        public static string afterRewardAdShow = "afterRewardAdShow";
        public static string afterRewardAdEnd = "afterRewardAdEnd";
        public static string fail_show = "fail_show";
        public static string fail_click = "fail_click";
        public static string fail_buy_success = "fail_buy_success";
        public static string three_days_gift_show = "three_days_gift_show";
        public static string three_days_gift_click = "three_days_gift_click";
        public static string three_days_gift_buy_success = "three_days_gift_buy_success";
        public static string three_days_gift_open = "three_days_gift_open";
        public static string three_day1_success = "three_day1_success";
        public static string three_day2_success = "three_day2_success";
        public static string three_day3_success = "three_day3_success";
        public static string Three_days_gift_event = "Three_days_gift_event";
        public static string BuyProp = "buy_prop";




        //public static string annular_ct_people = "annular_ct_people";

        public static string Apple_ios_pay_event = "IOS_Pay_Event";
        public static string Apple_AD_event = "AD_Event";


        public static string pack_show = "pack_show";
        public static string pack_click = "pack_click";
        public static string pack_open = "pack_open";
        public static string pack__success = "pack_receive";

        public static string buy_one_show = "buy_one_show";
        public static string buy_one_click = "buy_one_click";
        public static string buy_one_open = "buy_one_open";
        public static string buy_one_success = "buy_one_success";
        public static string gold_click_1 = "shop_click";
        // public static string gold_click_2 = "gold_click_2";
        // public static string gold_click_3 = "gold_click_3";
        // public static string gold_click_4 = "gold_click_4";
        // public static string gold_open_1 = "gold_open_1";
        // public static string gold_open_2 = "gold_open_2";
        // public static string gold_open_3 = "gold_open_3";
        // public static string gold_open_4 = "gold_open_4";
        public static string gold_success_1 = "shop_receive";
        // public static string gold_success_2 = "gold_success_2";
        // public static string gold_success_3 = "gold_success_3";
        // public static string gold_success_4 = "gold_success_4";

        public const string remove_ad_open = "remove_ad_open";
        public const string pack_success = "pack_success";
        public static string gold_click_ad = "gold_click_ad";
        public static string fail_open = "fail_open";

    }
}