using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Scripting;

namespace TyphoonUnitySDK
{
    /// <summary>
    /// oppo mini sdk
    /// </summary>
    [Preserve]
    public class OppoMiniSdk : BaseSdk
    {
        [Serializable]
        public class HttpRspData
        {
            public string ret;
            public object data;
            public Dictionary<string, string> header;
            public long statusCode;
        }

        public const string CALL_BACK_GAME_OBJECT_NAME = "TYPHOON_SDK_CALL_BACK";

        public OppoMiniSdkCallBack CallBack;

        //缓存的sessionId
        private long _showVideoSessionId = -1;

        public override void OnCreate()
        {
            Debug.Log("[OppoMiniSdk] OnCreate");
            //创建回调对象
            CallBack = new GameObject(CALL_BACK_GAME_OBJECT_NAME).AddComponent<OppoMiniSdkCallBack>();
            CallBack.Initialize();
            GameObject.DontDestroyOnLoad(CallBack.gameObject);
            HttpGet("http://127.0.0.1:51824/home", (ret) =>
            {
                if (ret.StatusCode == 200 && ret.DataString == "ok")
                {
                    Debug.Log("[OppoMiniSdk] 请求调试服务器成功！ 开启调试日志");
                    SdkDebug.IsDebug = true;
                }
            }, null, null);
        }

        #region 初始化SDK

        /*初始化sdk*/
        public override void InitSdk(Action success, Action<string> fail)
        {
            //初始化逻辑
            Action exec = () =>
            {
                SdkDebug.Log("[OppoMiniSdk] InitSdk");
                var session = new SessionItem("initSdk", null, (res) =>
                {
                    if (res == "ok")
                    {
                        SdkDebug.Log("[OppoMiniSdk] InitSdk success");
                        success?.Invoke();
                    }
                    else
                    {
                        SdkDebug.Log($"[OppoMiniSdk] InitSdk fail : {res}");
                        //TODO//输出错误信息
                        fail?.Invoke(res);
                    }
                });
                UnityToJs.Call(session);
            };

            //判断是否已经同意隐私政策
            var key = $"$oppo_mini_privacy_apply_flag$";
            if (PlayerPrefs.GetInt(key) == 1)
            {
                //同意了隐私政策,执行初始化
                exec?.Invoke();
            }
            else
            {
                //弹出隐私政策协议
                PrivacyGUI.Instance.PopUp(() =>
                {
                    //同意隐私政策
                    PlayerPrefs.SetInt(key, 1);
                    PlayerPrefs.Save();
                    exec?.Invoke();
                }, ExitGame, true);
            }
        }

        #endregion

        #region 登录

        /*登录*/
        public override void Login(Action success, Action<string> fail)
        {
            SdkDebug.Log("[OppoMiniSdk] Login");
            var session = new SessionItem("login", null, (res) =>
            {
                if (res == "ok")
                {
                    SdkDebug.Log("[OppoMiniSdk] Login success");
                    success?.Invoke();
                }
                else
                {
                    SdkDebug.Log($"[OppoMiniSdk] Login fail : {res}");
                    fail.Invoke(res);
                }
            });
            UnityToJs.Call(session);
        }

        #endregion

        #region banner

        /*展示Banner*/
        public override void ShowBanner(string scene, BannerPosition position)
        {
            //0是下banner，1是上banner
            UnityToJs.Call("showBanner", new { scene, pos = (int)position });
        }

        /*隐藏banner*/
        public override void HideBanner(string scene = "")
        {
            UnityToJs.Call("hideBanner", scene);
        }

        #endregion

        #region 插页广告

        public override void ShowInters(string scene)
        {
            SdkDebug.Log($"[OppoMiniSdk] ShowInters,scene:{scene}");
            UnityToJs.Call("showInters", new { scene });
        }

        #endregion

        #region 视频广告

        /*视频广告flag*/
        public override bool GetVideoFlag()
        {
            SdkDebug.Log("[OppoMiniSdk] GetVideoFlag...");
            var flag = UnityToJs.CallReturn("getVideoFlag", null) == "1";
            SdkDebug.Log($"[OppoMiniSdk] GetVideoFlag:{flag}");
            return flag;
        }

        /*播放视频广告*/
        public override void ShowVideo(string scene, Action success, Action<string> fail)
        {
            SdkDebug.Log($"[OppoMiniSdk] ShowVideo,scene:{scene}");
            SessionItem.ClearSession(_showVideoSessionId);
            var session = new SessionItem("showVideo", new { scene }, (res) =>
            {
                if (res == "ok")
                {
                    success?.Invoke();
                }
                else
                {
                    fail?.Invoke(res);
                }
            });
            _showVideoSessionId = session.SessionId;
            UnityToJs.Call(session);
        }

        #endregion

        #region 退出游戏

        public override bool IsSupportExitGame()
        {
            SdkDebug.Log($"[OppoMiniSdk] IsSupportExitGame,flag: true");
            return true;
        }

        public override void ExitGame()
        {
            SdkDebug.Log($"[OppoMiniSdk] ExitGame");
            var session = new SessionItem("exitGame", "", null);
            UnityToJs.Call(session);
        }

        #endregion

        #region Toast

        public override void ShowToast(string message)
        {
            SdkDebug.Log($"[OppoMiniSdk] ShowToast message:{message}");
            var session = new SessionItem("showToast", new { message }, null);
            UnityToJs.Call(session);
        }

        #endregion

        #region HTTP 请求

        public override void HttpPost(string url, string data, Action<HttpPostSuccessResult> success,
            Action<string> fail, Dictionary<string, string> header = null, int timeOut = 60)
        {
            SdkDebug.Log($"[OppoMiniSdk] HttpPost url:{url},data:{data} header:{header} timeOut:{timeOut}");
            var session = new SessionItem("httpPost", new { url, data, header, timeOut }, (res) =>
            {
                SdkDebug.Log($"[OppoMiniSdk] HttpPost响应结果： {res} [请求参数]：url:{url} data:{data}");
                try
                {
                    var rsp = res.ToXObject<HttpRspData>();
                    if (rsp.ret == "ok")
                    {
                        SdkDebug.Log($"[OppoMiniSdk] 响应成功");
                        success?.Invoke(new HttpPostSuccessResult(rsp.data, rsp.header, rsp.statusCode));
                    }
                    else
                    {
                        SdkDebug.Log($"[OppoMiniSdk] 响应失败");
                        //触发失败回调
                        fail?.Invoke(rsp.ret);
                    }
                }
                catch (Exception e)
                {
                    fail?.Invoke($"解析参数失败:{res}");
                }
            });
            UnityToJs.Call(session);
        }

        public override void HttpGet(string url, Action<HttpGetSuccessResult> success, Action<string> fail,
            Dictionary<string, string> header, int timeOut = 60)
        {
            SdkDebug.Log($"[OppoMiniSdk] HttpGet url:{url},header:{header} timeOut:{timeOut}");
            var session = new SessionItem("httpGet", new { url, header, timeOut }, (res) =>
            {
                SdkDebug.Log($"[OppoMiniSdk] HttpGet 响应结果： {res} [请求参数]：url:{url} ");
                try
                {
                    var rsp = res.ToXObject<HttpRspData>();
                    if (rsp.ret == "ok")
                    {
                        SdkDebug.Log($"[OppoMiniSdk] 响应成功");
                        success?.Invoke(new HttpGetSuccessResult(rsp.data, rsp.header, rsp.statusCode));
                    }
                    else
                    {
                        SdkDebug.Log($"[OppoMiniSdk] 响应失败");
                        //触发失败回调
                        fail?.Invoke(rsp.ret);
                    }
                }
                catch (Exception e)
                {
                    fail?.Invoke($"解析参数失败:{res}");
                }
            });
            UnityToJs.Call(session);
        }

        #endregion

        #region 事件上报

        public override void Track(string eventName, KvMap map)
        {
            SdkDebug.Log($"[OppoMiniSdk] Track eventName:{eventName},map:{map.ToXJson()} ");
            var output = new Dictionary<string, object>();
            //二次处理数据
            foreach (var pair in map)
            {
                var key = pair.Key;
                var value = pair.Value;
                //无值，默认取整数1
                if (value == null)
                {
                    output.Add(key, 1);
                    continue;
                }

                //如果是基础类型
                if (value is bool)
                {
                    //如果是bool类型
                    output.Add(key, (bool)value ? 1 : 0);
                    continue;
                }

                //浮点数
                if (value is float || value is double || value is decimal)
                {
                    output.Add(key, value);
                    continue;
                }

                //整数
                if (value is int || value is long || value is short || value is ushort || value is uint ||
                    value is ulong)
                {
                    output.Add(key, value);
                    continue;
                }

                //其它类型
                output.Add(key, value.ToString());
            }

            var session = new SessionItem("track", new { eventName, eventData = output }, null);
            UnityToJs.Call(session);
        }

        #endregion
    }
}