using System;
using System.Collections.Concurrent;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using MrWu.Debug;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Server.Core;
using Server.DB.Redis;
using StackExchange.Redis;

namespace Server
{
    public class IPManager : SingleInstance<IPManager>
    {
        private ConcurrentDictionary<string, IpInfo> _ipInfos = new ConcurrentDictionary<string, IpInfo>();

        private static string GetHashKey(string ip)
        {
            return $"GameIpAddress:{ip}";
        }

        /// <summary>
        /// 加载IP信息
        /// </summary>
        /// <param name="ip"></param>
        public void LoadIpInfo(string ip)
        {
            GetIpInfoAsync(ip);
        }

        /// <summary>
        /// 获取IP信息 异步的
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        public Task<IpInfo> GetIpInfoAsync(string ip)
        {
            return Task.Run(() => GetIpInfo(ip));
        }

        /// <summary>
        /// 获取IP信息
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        public IpInfo GetIpInfo(string ip)
        {
            if (_ipInfos.TryGetValue(ip, out IpInfo ipInfo))
            {
                Debug.Info($"本地取定位:{ipInfo}");
                return ipInfo;
            }

            //去redis拿
            IpInfo result = GetIpInfoByRedis(ip);
            if (result != null)
            {
                return result;
            }

            //进行ip定位
            return GetIpInfoByAPI(ip);
        }

        private IpInfo GetIpInfoByRedis(string ip)
        {
            string key = GetHashKey(ip);
            try
            {
                HashEntry[] locationData = redisManager.db.HashGetAll(key);
                if (locationData != null && locationData.Length > 0)
                {
                    IpInfo ipInfo = new IpInfo();
                    foreach (var he in locationData)
                    {
                        switch (he.Name)
                        {
                            case "address": //上次创建的时间
                                ipInfo.Address = he.Value;
                                break;
                            case "city":
                                ipInfo.City = he.Value;
                                break;
                            case "province":
                                ipInfo.Province = he.Value;
                                break;
                            case "district":
                                ipInfo.District = he.Value;
                                break;
                            case "x":
                                ipInfo.Longitude = double.Parse(he.Value);
                                break;
                            case "y":
                                ipInfo.Latitude = double.Parse(he.Value);
                                break;
                        }
                    }

                    _ipInfos.TryAdd(ip, ipInfo);

                    Debug.Info($"从redis中取定位:{ipInfo}");
                    return ipInfo;
                }
            }
            catch (Exception e)
            {
                Debug.Error($"GetIpInfoByRedis ERROR:{e}");
                return null;
            }

            return null;
        }
        
        private const string ak = "";

        private const string GaoDeKey = "";

        //高德定位
        private IpInfo GetIpInfoByAPI(string ip)
        {
            return null;
            
        }

        //百度定位
//         private IpInfo GetIpInfoByAPI(string ip)
//         {
// #if DEBUG
//             return null;
// #endif
//             try
//             {
//                 //进行ip定位
//                 string jsonData = HttpHelper.Get(
//                     $"http://172.16.52.118/location/ip?ip={ip}&coor=gcj02&ak={ak}");
//                     //$"https://api.map.baidu.com/location/ip?ip={ip}&coor=gcj02&ak={ak}");
//                 jsonData = Regex.Unescape(jsonData);
//                 Debug.Info("jsonData:" + jsonData);
//                 JObject jObject = JsonConvert.DeserializeObject<JObject>(jsonData);
//
//                 if ((int)jObject["status"] == 0)
//                 {
//                     IpInfo ipInfo = new IpInfo();
//                     JObject contentJobj = jObject["content"] as JObject;
//                     ipInfo.Address = string.Empty;
//
//                     JObject detailJobj = contentJobj["address_detail"] as JObject;
//                     ipInfo.City = detailJobj["city"].ToString();
//                     ipInfo.Province = detailJobj["province"].ToString();
//                     ipInfo.District = detailJobj["district"].ToString();
//
//                     JObject locationJobj = contentJobj["point"] as JObject;
//                     ipInfo.Longitude = double.Parse(locationJobj["x"].ToString());
//                     ipInfo.Latitude = double.Parse(locationJobj["y"].ToString());
//
//                     //写入缓存
//                     HashEntry[] hes = new HashEntry[]
//                     {
//                         new HashEntry("address", ipInfo.Address),
//                         new HashEntry("city", ipInfo.City),
//                         new HashEntry("province", ipInfo.Province),
//                         new HashEntry("district", ipInfo.District),
//                         new HashEntry("x", ipInfo.Longitude),
//                         new HashEntry("y", ipInfo.Latitude)
//                     };
//
//                     string key = GetHashKey(ip);
//                     //设置一个小时过期
//                     redisManager.db.HashSet(key, hes);
//                     redisManager.db.KeyExpire(key, TimeSpan.FromDays(15));
//
//                     _ipInfos.TryAdd(ip, ipInfo);
//                     Debug.Info($"进行百度定位! {ipInfo}");
//                     return ipInfo;
//                 }
//             }
//             catch (Exception e)
//             {
//                 Debug.Error($"进行百度定位失败!{e.Message}");
//                 return null;
//             }
//
//             return null;
//         }

        public class IpInfo
        {
            /// <summary>
            /// 省份
            /// </summary>
            public string Province;

            /// <summary>
            /// 城市
            /// </summary>
            public string City;

            /// <summary>
            /// 街道
            /// </summary>
            public string District;

            /// <summary>
            /// 详细地址
            /// </summary>
            public string Address;

            /// <summary>
            /// 纬度
            /// </summary>
            public double Latitude;

            /// <summary>
            /// 精度
            /// </summary>
            public double Longitude;

            public override string ToString()
            {
                return $"省份:{Province}, 城市:{City}, 街道:{District}, 详细地址:{Address}, 纬度:{Latitude}, 精度:{Longitude}";
            }
        }
    }
}