using ESBasic.ObjectManagement.Managers;
using Newtonsoft.Json;
using OMCS.Passive;
using Oraycn.ChatRendering;
using OVCS.Core;
using System;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace OVCS.ClientWpf
{
    /// <summary>
    /// 文本聊天 控件容器。
    /// </summary>
    public partial class TextChatContainer : UserControl
    {
        private ObjectManager<string, ChatMessageRecord> chatMessageManager = new ObjectManager<string, ChatMessageRecord>();
        private string roomId;
        private string chatID;
        private DateTime lastMessageTime = DateTime.MinValue; 
        private IMultimediaManager multimediaManager;
        private ObjectManager<string, int> unReadMsgCount = new ObjectManager<string, int>();
        private object locker = new object();

        JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings();
        
        public TextChatContainer()
        {
            InitializeComponent();
            jsonSerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
            this.Loaded += TextChatContainer_Loaded;
            this.inputbox.SendTextEvent += Inputbox_SendTextEvent;
            this.emotionPanel.EmotionClicked += EmotionPanel_EmotionClicked;
            this.inputbox.Initialize(this.emotionPanel.EmojiDic);
        }

        private void Inputbox_SendTextEvent(string obj)
        {
            this.sendMessage2_Click(null, null);
        }

        private void TextChatContainer_Loaded(object sender, RoutedEventArgs e)
        {
            this.InvalidateVisual();
        }

        private void EmotionPanel_EmotionClicked(int _emotionIndex, ImageSource _imageSource)
        {
            this.inputbox.InsertEmoji(_emotionIndex);
        }
        private IChatRender chatRender;
        public void Initialize(string _roomId,IMultimediaManager _multimediaManager)
        {
            this.roomId = _roomId; 
            this.multimediaManager = _multimediaManager;
            this.chatID = this.multimediaManager.CurrentUserID;
            this.chatRender = ChatRenderFactory.CreateChatRender(new RenderDataProvider(), this.chatBox.ChatControl, this.multimediaManager.CurrentUserID, this.roomId, true);
            this.chatBox.Initialize(chatRender);
        }
        private void emotionButton_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (emotionPanel.Visibility == Visibility.Visible)
            {
                this.emotionPanel.Visibility = Visibility.Hidden;
            }
            else
            {
                this.emotionPanel.Visibility = Visibility.Visible;
            }
            inputbox.Focus();
        }

        /// <summary>
        /// 插入一条文字消息
        /// </summary> 
        internal void InsertEmtionText(ChatMessageRecord contact, bool isMySend = true)
        {
            if (contact == null)
            {
                contact = GetInputContent();
                if (string.IsNullOrEmpty(contact.ContentStr))
                {
                    MessageBox.Show("请输入文本再发送");
                    return;
                }
            }
            if (isMySend)
            {
                SendEmotionTextChatMsg2Server(contact);
                ClearInput(); 
            }
            RenderEmotionText(contact);
            this.chatMessageManager.Add(contact.Guid, contact); 
        } 
         

        #region 输入框操作

        /// <summary>
        /// 将输入框的内容转换为EmotionTextChatContract
        /// </summary> 
        private ChatMessageRecord GetInputContent()
        {
            string content = this.inputbox.GetInputBoxContent();
            ChatMessageRecord chatContact = this.GetChatContact(chatID);
            chatContact.ContentStr = content;
            return chatContact;
        }

         /// <summary>
        /// 清空输入框
        /// </summary> 
        internal void ClearInput()
        {
            inputbox.Clear();
            inputbox.Focus();
        }

        /// <summary>
        /// 使输入框获得焦点
        /// </summary>
        internal void FocusInputBox()
        {
            Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Render,
             new Action(() => inputbox.Focus()));
        }
        #endregion

        /// <summary>
        /// 发送给广播聊天消息
        /// </summary> 
        private void SendEmotionTextChatMsg2Server(ChatMessageRecord chatContact)
        {
            try
            {
                string cont = JsonConvert.SerializeObject(chatContact,Formatting.None, this.jsonSerializerSettings);
                byte[] recordInfo = Encoding.UTF8.GetBytes(cont);
                //使用Tag携带 接收者的ID
                this.multimediaManager.SendCustomizedMessage(App.ServerID, InformationTypes.BroadcastChat, recordInfo, this.roomId);
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message);
            }
        }

        private void RenderEmotionText(ChatMessageRecord contact)
        {
            if (contact == null)
            {
                return;
            }
            AppendSendTime(DateTime.Now);
            this.chatRender.AddChatItemText(contact.Guid, contact.SpeakerID, contact.ContentStr);
            Window_Changed();
        }

        internal ChatMessageRecord GetChatContact(string destID)
        {
            return new ChatMessageRecord() { Guid = Guid.NewGuid().ToString(), SpeakerID = this.multimediaManager.CurrentUserID, ListenerID = destID, MessageTime = DateTime.Now, ChatMessageType = (int)ChatMessageType.TextEmotion};
        }

 
        /// <summary>   
        /// 追加系统时间
        /// </summary> 
        private void AppendSendTime(DateTime time)
        {
            lock (this.locker)
            {
                if (time.Subtract(this.lastMessageTime) > TimeSpan.FromMinutes(5))
                {
                    this.lastMessageTime = time;
                    this.chatRender.AddChatItemTime(time);
                }
            }
        }

        internal void Window_Changed()
        {
            this.chatBox.ChangeRenderSurfaceSize();
            this.chatBox.InvalidateVisual();
            this.chatBox.ScrollToEnd(); 
        }

        private void sendMessage2_Click(object sender, RoutedEventArgs e)
        { 
            //if (this.multimediaManager == null)
            //{
            //    MessageBox.Show("连接已断开");
            //    return;
            //}
            InsertEmtionText(null);
            this.emotionPanel.Visibility = Visibility.Hidden;
        }

        /// <summary>
        /// 在对应的ChatPanel中插入收到的消息
        /// </summary> 
        public void InsertMsg2ChatRoom(int informationType, byte[] info)
        {
            try
            {
                string content = Encoding.UTF8.GetString(info);

                ChatMessageRecord record = JsonConvert.DeserializeObject<ChatMessageRecord>(content, this.jsonSerializerSettings);
                string speakID = record.SpeakerID;
                if (informationType == InformationTypes.BroadcastChat)
                {
                    this.InsertEmtionText(record, false);
                }
                TextChatContainer chat = this;
                if (chat == null || chat.chatID != speakID)
                {
                    int? unReadCount = this.unReadMsgCount.Get(speakID);
                    if (unReadCount != null)
                    {
                        unReadCount++;
                    }
                    else
                    {
                        unReadCount = 1;
                    }
                    this.unReadMsgCount.Add(speakID, (int)unReadCount);
                }
            }
            catch(Exception ex)
            {

            }
        }

        /// <summary>
        /// 增加系统消息
        /// </summary>
        public void AddSystemMessage(string msg)
        {
            this.chatRender.AddChatItemSystemMessage(msg);
        }

        SettingWindow settingWindow;
        private void Image_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if(settingWindow != null)
            {
                settingWindow.Close();
                settingWindow = null;
            }
            settingWindow = new SettingWindow(this.multimediaManager); 
            settingWindow.Show();
        }
         
    }
}
