using CommonLang;
using CommonLang.Concurrent;
using CommonLang.IO;
using CommonLang.Property;
using CommonNetwork.Http;
using pomelo.chat;
using SimpleJson;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace XmdsBattleClientBot.Bot
{
    partial class BotClient
    {
        public ChatManager CurrentChatManager { get; private set; }
        public GetChatServerIdResponse LastGetChatServerIdResponse { get; private set; }

        /// <summary>
        /// 0综合,1世界,2区域,3交易,4公会,5队伍,6系统,7喇叭,8私聊
        /// </summary>
        public enum ChatChannel
        {
            [Desc("世界")]
            WORLD = 1,       // 世界

            [Desc("公会")]
            SOCIETY = 2,     // 公会

            [Desc("队伍")]
            GROUPS = 3,      // 队伍

            [Desc("私聊")]
            PRIVATE = 4,    // 私聊

            [Desc("连服")]
            ZONE = 5,        // 连服(跨服)

            [Desc("附近")]
            NEARBY = 6,      // 附近

            [Desc("喇叭")]
            HORM = 8        // 喇叭
        }
        public enum ChatAt
        {
            Normal = 0,
            All = 1,
            Single = 2,
        }
        public enum ChatFunType
        {
            NA = 0,
            Roll = 1,
        }

        public void chat_SendChat(Action<Exception, JsonObject> callback,
            string content,
            string titleMsg = "",
            ChatChannel ch = ChatChannel.WORLD,
            string acceptRoleId = "",
            ChatAt at = ChatAt.Normal,
            ChatFunType funtype = ChatFunType.NA)
        {
            dynamic input = new
            {
                s2c_name = this.PlayerData.name,//DataMgr.Instance.UserData.Name
                s2c_level = this.PlayerData.level, // DataMgr.Instance.UserData:TryToGetIntAttribute(UserData.NotiFyStatus.LEVEL, 0);
                s2c_pro = this.PlayerData.pro,// DataMgr.Instance.UserData.Pro;
                s2c_zoneId = this.PlayerData.zoneId,//DataMgr.Instance.UserData:GetAttribute(UserData.NotiFyStatus.ZONEID);
                s2c_vip = this.PlayerData.vip,// DataMgr.Instance.UserData:GetAttribute(UserData.NotiFyStatus.VIP);
                s2c_isAtAll = (int)at,
                s2c_titleMsg = titleMsg,
                s2c_funtype = (int)funtype,
                s2c_color = (uint)0xFFFFFFFF,
                acceptRoleId = acceptRoleId,
            };
            string msg = SimpleJson.SimpleJson.SerializeObject(input);

            new ChatManager.ChatRequest(this)
            {
                channel = ch,
                chatContent = content,
                acceptRoleId = acceptRoleId,
                serverData = msg,
            }.Send(callback);
        }
        public virtual string FormatChat(OnChatPush push)
        {
            StringBuilder sb = new StringBuilder();
            var ch = (BotClient.ChatChannel)push.s2c_scope;
            var desc = PropertyUtil.GetEnumAttribute<DescAttribute>(ch);
            dynamic input = SimpleJson.SimpleJson.DeserializeObject(push.s2c_serverData);
            sb.Append(push.s2c_time);
            sb.Append(" ");
            sb.Append(string.Format("[{0}]", desc.Desc));
            try
            {
                sb.Append(string.Format("{0}(Lv{1})", input["s2c_name"], input["s2c_level"]));
                string s2c_titleMsg = input["s2c_titleMsg"];
                if (!string.IsNullOrEmpty(s2c_titleMsg))
                {
                    sb.Append(string.Format(":\"{0}\"", s2c_titleMsg));
                }
            }
            catch (Exception err)
            {
                sb.Append(err.Message);
            }
            sb.Append(": " + push.s2c_content);
            return sb.ToString();
        }

        public class ChatManager
        {
            public ChatManager(BotClient bot)
            {
                bot.client.GameSocket.chatHandler.getChatServerIdRequest((err, rsp) =>
                {
                    bot.LastGetChatServerIdResponse = rsp;
                });
            }

            public class ChatRequest
            {
                private readonly BotClient bot;

                public static string BOUNDARY = "---------------------------123821742118716"; //boundary就是request头和上传文件内容的分隔符

                public ChatChannel channel = ChatChannel.WORLD;
                public string chatContent = "0";
                public string acceptRoleId = "1";
                public string serverData = "0";
                public string chatType = "1";//0 is sound

                public bool Result { get; private set; }

                public ChatRequest(BotClient bot)
                {
                    this.bot = bot;
                }

                public void Send(Action<Exception, JsonObject> callback)
                {
                    if (bot.LastGetChatServerIdResponse == null)
                    {
                        callback(new Exception("No Server ID"), null);
                        return;
                    }

                    try
                    {
#if OLD_CHAT
                        HttpWebRequest webRequest = System.Net.WebRequest.Create(bot.LastGetChatServerIdResponse.s2c_clientHttp) as HttpWebRequest;
                        webRequest.Method = "POST";
                        webRequest.BeginGetRequestStream(new System.AsyncCallback((System.IAsyncResult asynchronousResult) =>
                        {
                            try
                            {

                                HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
                                request.Timeout = 1000 * 300;
                                request.ContentType = "multipart/form-data; boundary=" + BOUNDARY;
                                request.KeepAlive = true;
                                request.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)";
                                Stream stream = request.EndGetRequestStream(asynchronousResult);
                                StreamWriter postStream = new StreamWriter(stream);
                                Dictionary<string, string> textMap = new Dictionary<string, string>();
                                {
                                    textMap.Add("account", bot.Account);
                                    textMap.Add("appid", bot.config.Appid.ToString());
                                    ///************************/
                                    //textMap.Add("serverId", DataMgr.Instance.AccountData.CurSrvInfo.ServerId.ToString());
                                    textMap.Add("serverId", bot.LastGetChatServerIdResponse.s2c_serverId);
                                    string zoneid = bot.PlayerData.zoneId;//(string)DataMgr.Instance.UserData.GetAttribute(UserData.NotiFyStatus.ZONEID);
                                    string[] array = zoneid.Split('-');
                                    int zoneidnum = int.Parse(array[0]) * 1000000 + int.Parse(array[1]);
                                    textMap.Add("realServerId", zoneidnum + "");
                                    textMap.Add("myRoleId", bot.PlayerData.id/*DataMgr.Instance.UserData.RoleID.ToString()*/);
                                    textMap.Add("acceptRoleId", acceptRoleId);
                                    textMap.Add("channel", ((int)channel).ToString());
                                    textMap.Add("chatContent", chatContent);
                                    textMap.Add("chatType", chatType);
                                    textMap.Add("serverData", serverData);
                                }
                                {
                                    var strBuf = new StringBuilder();
                                    foreach (string key in textMap.Keys)
                                    {
                                        string inputName = key;
                                        string inputValue = "";
                                        if (textMap[key] == null)
                                        {
                                            continue;
                                        }
                                        inputValue = (string)textMap[key];
                                        strBuf.Append("\r\n" + "--" + BOUNDARY + "\r\n");
                                        strBuf.Append("Content-Disposition: form-data; name=\"" + inputName + "\"\r\n\r\n");
                                        strBuf.Append(inputValue);
                                    }
                                    postStream.Write(strBuf);
                                }
                                postStream.Write("\r\n--" + BOUNDARY + "--\r\n");
                                postStream.Flush();
                                postStream.Close();
                                postStream = null;
                                WebResponse wrp = request.GetResponse();
                                StreamReader respRs = new StreamReader(wrp.GetResponseStream());
                                string responseData = "";
                                string readCallBackFileResponse = "";
                                while ((responseData = respRs.ReadLine()) != null)
                                {
                                    readCallBackFileResponse += responseData + "\n";
                                }
                                JsonObject obj = (JsonObject)SimpleJson.SimpleJson.DeserializeObject(readCallBackFileResponse);
                                object status;
                                if (obj.TryGetValue("status", out status) && (status as string) == "1")
                                {
                                    Result = (true);
                                }
                                else
                                {
                                    Result = (false);
                                }
                                bot.QueueTask(() =>
                                {
                                    callback(null, obj);
                                });
                            }
                            catch (Exception err)
                            {
                                bot.log.Error(err.Message, err);
                                bot.QueueTask(() =>
                                {
                                    callback(err, null);
                                });
                            }
                        }), webRequest);
#else
                        var url = new Uri(bot.LastGetChatServerIdResponse.s2c_clientHttp);
                        using (WebClient client = new WebClient(url))
                        {
                            client.Request.Method = HttpRequest.METHOD_POST;
                            client.Request.Referer = url.AbsoluteUri;
                            {
                                StringBuilder postStream = new StringBuilder();
                                Dictionary<string, string> textMap = new Dictionary<string, string>();
                                {
                                    textMap.Add("account", bot.Account);
                                    textMap.Add("appid", bot.config.Appid.ToString());
                                    ///************************/
                                    //textMap.Add("serverId", DataMgr.Instance.AccountData.CurSrvInfo.ServerId.ToString());
                                    textMap.Add("serverId", bot.LastGetChatServerIdResponse.s2c_serverId);
                                    string zoneid = bot.PlayerData.zoneId;//(string)DataMgr.Instance.UserData.GetAttribute(UserData.NotiFyStatus.ZONEID);
                                    string[] array = zoneid.Split('-');
                                    int zoneidnum = int.Parse(array[0]) * 1000000 + int.Parse(array[1]);
                                    textMap.Add("realServerId", zoneidnum + "");
                                    textMap.Add("myRoleId", bot.PlayerData.id/*DataMgr.Instance.UserData.RoleID.ToString()*/);
                                    textMap.Add("acceptRoleId", acceptRoleId);
                                    textMap.Add("channel", ((int)channel).ToString());
                                    textMap.Add("chatContent", chatContent);
                                    textMap.Add("chatType", chatType);
                                    textMap.Add("serverData", serverData);
                                }
                                {
                                    foreach (string key in textMap.Keys)
                                    {
                                        string inputName = key;
                                        string inputValue = "";
                                        if (textMap[key] == null)
                                        {
                                            continue;
                                        }
                                        inputValue = (string)textMap[key];
                                        postStream.Append("\r\n" + "--" + BOUNDARY + "\r\n");
                                        postStream.Append("Content-Disposition: form-data; name=\"" + inputName + "\"\r\n\r\n");
                                        postStream.Append(inputValue);
                                    }
                                }
                                postStream.Append("\r\n--" + BOUNDARY + "--\r\n");
                                var content = postStream.ToString();
                                client.Request.Content = CUtils.UTF8.GetBytes(content);
                                client.Request.ContentType = "multipart/form-data; boundary=" + BOUNDARY;
                            }
                            client.ConnectAsync((www)=>
                            {
                                try
                                {
                                    byte[] data = client.Response.ReadContentToEnd();
                                    string ret = CUtils.UTF8.GetString(data);
                                    JsonObject obj = (JsonObject)SimpleJson.SimpleJson.DeserializeObject(ret);
                                    object status;
                                    if (obj.TryGetValue("status", out status) && (status as string) == "1")
                                    {
                                        Result = (true);
                                    }
                                    else
                                    {
                                        Result = (false);
                                    }
                                    bot.QueueTask(() =>
                                    {
                                        callback(null, obj);
                                    });
                                }
                                catch (Exception err)
                                {
                                    bot.log.Error(err.Message, err);
                                    bot.QueueTask(() =>
                                    {
                                        callback(err, null);
                                    });
                                }
                            });
                        }
#endif
                    }
                    catch (Exception err)
                    {
                        bot.log.Error(err.Message, err);
                        callback(err, null);
                    }
                }
            }
        }

    }
}