using CPF;
using CPF.Controls;
using CPF.Drawing;
using CPF.Input;
using ESBasic.ObjectManagement.Managers;
using Newtonsoft.Json;
using OMCS.Cpf;
using OMCS.Passive;
using Oraycn.ChatRendering;
using OVCS.ClientLinux.Controls.ChatBox;
using OVCS.ClientLinux.Tools;
using OVCS.LinuxCore;
using System;
using System.Text;
using System.Threading.Tasks;

namespace OVCS.ClientLinux
{
    [CPF.Design.DesignerLoadStyle("res://OVCS.Client.Linux/Resource/Stylesheet1.css")]//用于设计的时候加载样式

    //聊天面板控件
    public class TextChatContainer : Control
    {
        protected override void InitializeComponent()
        {
            CommandContext = this;
            DataContext = this;
            Background = CPF.Drawing.Color.White;
            Children.Add(new Grid
            {
                MarginTop = 0,
                MarginBottom = 0,
                MarginLeft = 0,
                MarginRight = 0,
                ClipToBounds = true,
                RowDefinitions =
                {
                    new RowDefinition
                    {
                        Height = GridLength.Auto,
                    },
                    new RowDefinition
                    {
                        Height = GridLength.Star,
                    },
                    new RowDefinition
                    {
                        Height = 180,
                    },
                },
                Children =
                {
                    new Grid()
                    {
                        //MarginTop = 0,
                        //MarginRight = 0,
                        //MarginBottom = 0,
                        //MarginLeft = 0,
                        Background = CPF.Drawing.Color.DeepSkyBlue,
                        PresenterFor=this,
                        Width="100%",
                        Height=56,
                        Children =
                        {
                            new Picture
                            {
                                MarginRight = 20,
                                ToolTip = "设备选择",
                                Source = CommonHelper.ResourcesCatalog+"setting.png",
                                Stretch = Stretch.Uniform,
                                Width= 35,
                                Height= 35,
                                Commands =
                                {
                                    {
                                        nameof(Button.MouseDown),

                                        (s,e) =>
                                        {
                                            this.settingdeviceClick();
                                        }
                                    }
                                },
                            }
                        },
                        Attacheds =
                        {
                            {
                               Grid.RowIndex,
                               0
                            }
                        }
                     },
                    new Grid()
                    {
                        MarginLeft = 0,
                        MarginRight = 0,
                        MarginTop = 0,
                        MarginBottom = 0,
                        PresenterFor=this,
                        Name = "GridChatBox",
                        Children =
                        {
                            //new ChatBox()
                            //{
                            //    MarginLeft = 0,
                            //    MarginRight = 0,
                            //    MarginTop = 0,
                            //    MarginBottom = 0,
                            //    Background = Color.White,
                            //    Name = "chatBox",
                            //    PresenterFor = this,
                            //},
                            new EmotionPanel
                            {
                                Name = "emotionPanel",
                                PresenterFor = this,
                                Visibility = Visibility.Collapsed,
                                MarginBottom = 10,
                                MarginLeft = 0,
                            }
                        },
                        Attacheds =
                        {
                            {
                               Grid.RowIndex,
                               1
                            }
                        }
                    },
                    new Grid()
                    {
                        PresenterFor=this,
                        RowDefinitions =
                        {
                            new RowDefinition()
                            {
                                Height = 36,
                            },
                            new RowDefinition()
                            {
                                Height = 108,
                            },
                            new RowDefinition()
                            {
                                Height = 36,
                            },
                        },
                        Children =
                        {
                            new StackPanel()
                            {
                                MarginLeft = 10,
                                MarginRight = 10,
                                Orientation= Orientation.Horizontal,
                                Children =
                                {
                                    new Picture
                                    {
                                        Name = "emotionButton",
                                        MarginLeft = 10,
                                        MarginRight = 10,
                                        PresenterFor = this,
                                        Width = 18,
                                        Height = 18,
                                        Classes = "WhiteBtnStyle",
                                        ToolTip = "表情",
                                        Stretch = CPF.Controls.Stretch.UniformToFill,
                                        Source = CommonHelper.ResourcesCatalog+"biaoqing.png",
                                        Commands =
                                        {
                                            {
                                                nameof(Button.MouseUp),
                                                (s,e)=>this.Click_EmojiPanel()
                                            },
                                            {
                                                nameof(Button.MouseMove),
                                                (s,e)=>
                                                {
                                                    this.BtnMove(s,(MouseEventArgs)e);
                                                }
                                            },
                                            {
                                                nameof(Button.MouseLeave),
                                                (s,e)=>
                                                {
                                                    this.BtnLeave(s,(MouseEventArgs)e);
                                                }
                                            },
                                        },
                                    },
                                },
                                Attacheds =
                                {
                                    {
                                        Grid.RowIndex,
                                        0
                                    }
                                }
                            },
                            new StackPanel()
                            {
                                Width = 300,
                                MarginLeft = 0,
                                MarginRight = 0,
                                MarginTop = 0,
                                MarginBottom = 0,
                                Children =
                                {
                                    new Inputbox()
                                    {
                                        MarginLeft = 0,
                                        MarginRight = 0,
                                        MarginBottom = 0,
                                        MarginTop = 0,
                                        ContextMenu = null,
                                        Name = "inputbox",
                                        PresenterFor = this,
                                        FontSize = 14,
                                    }
                                },
                                Attacheds =
                                {
                                    {
                                        Grid.RowIndex,
                                        1
                                    }
                                }
                            },
                            new Grid()
                            {
                                MarginRight = 10,
                                Children =
                                {
                                    new Grid()
                                    {
                                        Height = 26,
                                        Width = 150,
                                        MarginRight = 10,
                                        Children =
                                        {
                                            new Button()
                                            {
                                                Height = 26,
                                                Width = 68,
                                                Name = "sendMessage",
                                                PresenterFor= this,
                                                MarginRight = 10,
                                                MarginBottom = 10,
                                                Content = "发送",
                                                Commands =
                                                {
                                                    {
                                                        nameof(Button.MouseDown),
                                                        (s,e)=>this.sendMessage2_Click(s,(RoutedEventArgs)e)
                                                    }
                                                }
                                            },

                                        }
                                    }
                                },
                                Attacheds =
                                {
                                    {
                                        Grid.RowIndex,
                                        2
                                    }
                                }
                            }
                        },
                        Attacheds =
                        {
                            {
                               Grid.RowIndex,
                               2
                            }
                        }
                    },
                }
            });

            if (!DesignMode)//设计模式下不执行，也可以用#if !DesignMode
            {
                SetComponent();
            }
        }
        private ObjectManager<string, ChatMessageRecord> chatMessageManager = new ObjectManager<string, ChatMessageRecord>();
        private string roomId;
        private string chatID;
        private DateTime lastMessageTime = DateTime.MinValue; 
        private ObjectManager<string, int> unReadMsgCount = new ObjectManager<string, int>();
        private object locker = new object();
        private Grid GridChatBox = new Grid();
        private ChatBox chatBox = new ChatBox()
        {
            MarginLeft = 0,
            MarginRight = 0,
            MarginTop = 0,
            MarginBottom = 0,
            Background = Color.White,
        };
        private EmotionPanel emotionPanel;
        private Button emotionButton;
        private Picture emojiPicture;
        private Inputbox inputbox;
        private Button sendMessage;
        private IMultimediaManager multimediaManager;
        //new ChatBox()
        //{
        //    MarginLeft = 0,
        //    MarginRight = 0,
        //    MarginTop = 0,
        //    MarginBottom = 0,
        //    Background = Color.White,
        //    Name = "chatBox",
        //    PresenterFor = this,
        //},
        JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings();

        public IChatRender chatRender;
        protected override void OnInitialized()
        {
            base.OnInitialized();
        }
        public void SetComponent()
        {
            emotionPanel = this.FindPresenterByName<EmotionPanel>("emotionPanel");
            emotionButton = this.FindPresenterByName<Button>("emotionButton");
            emojiPicture = this.FindPresenterByName<Picture>("emojiPicture");
            inputbox = this.FindPresenterByName<Inputbox>("inputbox");
            sendMessage = this.FindPresenterByName<Button>("sendMessage");
            GridChatBox = this.FindPresenterByName<Grid>("GridChatBox");
            GridChatBox.Children.Insert(0, chatBox);
        }
#if !DesignMode //用户代码写到这里，设计器下不执行，防止设计器出错

        //用户代码
        public void Initialize(string _roomId, IMultimediaManager _multimediaManager)
        {
            try
            {
                this.roomId = _roomId; 
                this.multimediaManager = _multimediaManager;
                this.chatID = this.multimediaManager.CurrentUserID;
                jsonSerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
                this.inputbox.KeyDown += Inputbox_KeyDown;
                this.emotionPanel.EmotionClicked += EmotionPanel_EmotionClicked;
                CpfRender cpfRender = new CpfRender(GlobalResourceManager.EmotionDictionary);
                this.chatRender = ChatRenderFactory.CreateChatRender(cpfRender,new RenderDataProvider(), this.chatBox.ChatControl,Program.MultimediaManager.CurrentUserID, this.roomId, true);
                this.chatBox.Initialize(chatRender);
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.ToString() + "-" + ex.StackTrace);
            }
        }

        /// <summary>
        /// 单个表情点击事件
        /// </summary>
        public void EmotionPanel_EmotionClicked(int _emotionIndex, Image _image)
        {
            this.inputbox.AppentEmoji(_emotionIndex);
            this.inputbox.ScrollToEnd();
            this.Focus2InputBox();
        }

        /// <summary>
        /// 点击表情按钮
        /// </summary>
        public void Click_EmojiPanel()
        {
            if (this.emotionPanel.Visibility == Visibility.Visible)
            {
                this.emotionPanel.Visibility = Visibility.Collapsed;
            }
            else
            {
                this.emotionPanel.Visibility = Visibility.Visible;
                this.emotionPanel.Focus();
            }
        }

        /// <summary>
        /// 键盘按Enter发送
        /// </summary>
        public void Inputbox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Modifiers != CPF.Input.InputModifiers.Control && e.Key == CPF.Input.Keys.Enter)//按Enter键发送消息，Ctrl+ Enter 换行
            {
                this.sendMessage2_Click(null, null);
                e.Handled = true;
                return;
            }
        }

        public void BtnLeave(CpfObject s, MouseEventArgs e)
        {

        }

        public void BtnMove(CpfObject s, MouseEventArgs e)
        {

        }

        /// <summary>
        /// 插入一条文字消息
        /// </summary> 
        public 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.GetInputContent();
            ChatMessageRecord chatContact = this.GetChatContact(chatID);
            chatContact.ContentStr = content;
            return chatContact;
        }

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

        /// <summary>
        /// 输入框获得焦点
        /// </summary>
        public void Focus2InputBox()
        {
            UiSafeInvoker.ActionOnUI(delegate
            {
                inputbox.Focus();
            });
        }
        #endregion

        /// <summary>
        /// 发送给广播聊天消息
        /// </summary> 
        public 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(null, InformationTypes.BroadcastChat, recordInfo, this.roomId);
            }
            catch (System.Exception ee)
            {
                MessageBox.Show(ee.Message + " - " + ee.StackTrace);
            }
        }

        /// <summary>
        /// 渲染文本消息到页面
        /// </summary>
        public void RenderEmotionText(ChatMessageRecord contact)
        {
            if (contact == null)
            {
                return;
            }
            this.AppendSendTime(System.DateTime.Now);

            this.chatRender.AddChatItemText(contact.Guid, contact.SpeakerID, contact.ContentStr);
            Task.Factory.StartNew(() =>
            {
                Window_Changed();
                this.chatBox.ScrollToEnd();
            });
        }


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


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

        public void Window_Changed()
        {
            this.chatBox.Invalidate();
            this.chatBox.ChangeRenderSurfaceSize();
        }

        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)
        {
            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);
            }
        }

        /// <summary>
        /// 增加系统消息
        /// </summary>
        public void AddSystemMessage(string msg)
        {
            this.chatRender.AddChatItemSystemMessage(msg);
            Task.Factory.StartNew(() =>
            {
                Window_Changed();
            });
        }
        private SettingWindow settingWindow;
       private void settingdeviceClick()
       {
            if(settingWindow != null)
            {
                settingWindow.Close();
                settingWindow = null;
            }
            settingWindow = new SettingWindow(); 
            settingWindow.Show();
       }

#endif
    }
}
