using System;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
using VCommon.Logging.Viewer.Utility;

namespace VCommon.Logging.Viewer
{
    public partial class DetailForm : Form
    {
        private static readonly string WebBrowserHtml;
        private LogEntity LogEntity { get; }
        private readonly Action<DetailForm> _closingRemove;

        static DetailForm()
        {
            WebBrowserHtml = WebBrowserUtility.LoadWebBrowserResource();
        }

        public DetailForm()
        {
            InitializeComponent();
            WbJson.DocumentText = WebBrowserHtml;
        }

        internal DetailForm(LogEntity logEntity, Action<DetailForm> closingRemove) : this()
        {
            LogEntity = logEntity;
            _closingRemove = closingRemove;
            StringBuilder sbSummary = new StringBuilder();
            PropertyInfo[] propertyInfos = LogEntity.GetType()
                .GetProperties(BindingFlags.Instance | BindingFlags.Public);
            var descriptFileNameLength = 0;
            var fieldCount = 0;
            foreach (var propertyInfo in propertyInfos.Where(c => c.Name != nameof(LogEntity.Detail)))
            {
                var desc = propertyInfo.GetCustomAttributes<DescriptionAttribute>().FirstOrDefault()?.Description ?? propertyInfo.Name;
                //TODO: 精简详情头部文本格式化逻辑
                sbSummary.Append(
                    $"{desc}:" +
                    $"{propertyInfo.GetValue(LogEntity, null)}\t");

                if (++fieldCount == 3)
                {
                    sbSummary.Append(Environment.NewLine);
                }
                if (fieldCount == 4)
                {
                    var padLeftLength = logEntity.FileName.Length + descriptFileNameLength + 1 - (logEntity.ThreadName.Length + desc.Length) - 8;
                    if (padLeftLength > 0)
                    {
                        sbSummary.Append(new string(' ', padLeftLength) + "\t");
                    }
                }
                if (propertyInfo.Name == nameof(logEntity.FileName))
                {
                    descriptFileNameLength = desc.Length;
                }
            }
            txtDetail.Text = sbSummary.ToString();
            txtDetail.Select(logEntity.FileName.Length + 1 + descriptFileNameLength, 0);
            Application.DoEvents();
        }

        private void DetailForm_Shown(object sender, EventArgs e)
        {
            Application.DoEvents();
            BackgroundWorker bgw = new BackgroundWorker();
            bgw.RunWorkerCompleted += Bgw_RunWorkerCompleted;
            TaskExtend.Delay(50).ContinueWith(t =>
            {
                bgw.RunWorkerAsync();
            });
        }

        private void Bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Application.DoEvents();
            Invoke(new Action(() =>
            {
                // ReSharper disable once PossibleNullReferenceException
                WbJson.Document.InvokeScript("GetOutputResult", new object[] { LogEntity.Detail });
            }));
        }

        public void PreFilterMessage(ref Message m)
        {
            WebBrowserUtility.SendMouseWheel(m, WbJson);
        }

        private void DetailForm_FormClosing(object sender, FormClosingEventArgs e) => _closingRemove?.Invoke(this);

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            int WM_KEYDOWN = 256;
            int WM_SYSKEYDOWN = 260;
            if (msg.Msg == WM_KEYDOWN | msg.Msg == WM_SYSKEYDOWN)
            {
                switch (keyData)
                {
                    //esc关闭窗体
                    case Keys.Escape:
                        Close();
                        break;
                }
            }
            return false;
        }
    }
}