using BPASmartClient.CustomResource.UserControls;
using BPASmartClient.CustomResource.UserControls.MessageShow;
using BPASmartClient.Helper;
using BPASmartClient.Model;
using Microsoft.Toolkit.Mvvm.ComponentModel;
using Microsoft.Toolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Media;

namespace BPASmartClient.ViewModel
{
    /// <summary>
    /// 告警/日志查询界面
    /// </summary>
    public class LogOrAlarmViewModel : ObservableObject
    {
        #region 单一变量
        private volatile static LogOrAlarmViewModel _Instance;
        public static LogOrAlarmViewModel GetInstance() => _Instance ?? (_Instance = new LogOrAlarmViewModel());
        private LogOrAlarmViewModel()
        {
            Init();
        }
        #endregion

        #region 变量
        string path = $"{System.AppDomain.CurrentDomain.BaseDirectory}LogDir\\HBL.LogDir2022_5_13.log";
        private string _SelectedText = "";
        public string SelectedText
        {
            get
            {
                return _SelectedText;
            }
            set
            {
                if (_SelectedText == value)
                    return;
                _SelectedText = value;
                OnPropertyChanged("SelectedText");
            }
        }
        /// <summary>
        /// 时间条件
        /// </summary>
        private DateTime _DateTime;
        public DateTime DateTimeStr
        {
            get
            {
                return _DateTime;
            }
            set
            {
                if (_DateTime == value)
                    return;
                _DateTime = value;
                OnPropertyChanged("DateTimeStr");
            }
        }
        public ObservableCollection<BookEx> SelectBookExs { set; get; }
        private ObservableCollection<BookEx> _books;
        public ObservableCollection<BookEx> BookExs
        {
            get
            {
                if (_books == null)
                {
                    _books = new ObservableCollection<BookEx>();

                    _books.CollectionChanged += (sender, e) =>
                    {
                        if (e.OldItems != null)
                        {
                            foreach (BookEx bookEx in e.OldItems)
                            {
                                bookEx.PropertyChanged -= ItemPropertyChanged;
                            }
                        }

                        if (e.NewItems != null)
                        {
                            foreach (BookEx bookEx in e.NewItems)
                            {
                                bookEx.PropertyChanged += ItemPropertyChanged;
                            }
                        }
                    };
                }

                return _books;
            }
        }

        private ObservableCollection<LogModel> _LogModels; public ObservableCollection<LogModel> LogDataGrid
        {
            get
            {
                return _LogModels;
            }
            set
            {
                if (_LogModels == value)
                    return;
                _LogModels = value;
                OnPropertyChanged("LogDataGrid");
            }
        }
        #endregion

        #region Command
        public RelayCommand QueryCommand { get; set; }
        public RelayCommand OpenCommand { get; set; }
        #endregion

        #region 函数
        public void Init()
        {
            LogDataGrid = new ObservableCollection<LogModel>();
            DateTimeStr = DateTime.Now;
            BookExs.Add(new BookEx(new Book() { Name = "一般日志条件", Tag = "Info" }) { IsChecked = true });
            BookExs.Add(new BookEx(new Book() { Name = "设备日志条件", Tag = "DeviceLog" }) { IsChecked = true });
            BookExs.Add(new BookEx(new Book() { Name = "错误日志条件", Tag = "Error" }) { IsChecked = true });
            BookExs.Add(new BookEx(new Book() { Name = "设备告警条件", Tag = "DeviceAlarm" }) { IsChecked = true });
            SelectBookExs = new ObservableCollection<BookEx>();
            ItemPropertyChanged(new BookEx(new Book()) { IsChecked = true },new PropertyChangedEventArgs("IsChecked"));
            //查询
            QueryCommand = new RelayCommand(() =>
            {
                string sql = string.Empty;
                if (SelectBookExs.Count <= 0)
                {
                    NoticeDemoViewModel.OpenMsg(EnumPromptType.Info, MainViewModel.GetInstance().window, "提示", $"至少选中一个条件!");
                    return;
                }
                SelectBookExs?.ToList().ForEach(par =>
                {
                    if (string.IsNullOrEmpty(sql))
                        sql += $"LOGGER='{par.BookN.Tag}'";
                    else
                        sql += $" OR LOGGER='{par.BookN.Tag}'";
                });
                //1.找到某天的文件
                string path = $"{System.AppDomain.CurrentDomain.BaseDirectory}LogDir\\HBL.LogDir{DateTimeStr.ToString("yyyy_M_d")}.log";
                if (File.Exists(path))
                {
                    LogDataGrid.Clear();
                    //2.根据选中查询日志
                    DataTable dataTable = ReadFile(path);
                    List<DataRow> datas = dataTable.Select($"({sql})").OrderByDescending(o => o["TIME"])?.ToList();
                    if (datas==null || datas.Count() <= 0)
                    {
                        NoticeDemoViewModel.OpenMsg(EnumPromptType.Info, MainViewModel.GetInstance().window, "提示", $"查询结果为空!");
                        return;
                    }
                    foreach (DataRow item in datas)
                    {
                        LogDataGrid.Add(new LogModel
                        {
                            time = item["TIME"].ToString(),
                            type = item["LOGGER"].ToString(),
                            message = item["MESSAGE"].ToString()
                           // foreground = (item["LOGGER"].ToString() == "ERROR" || item["LOGGER"].ToString() == "DEVICEALARM") ? new SolidColorBrush((System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#ed0032")) : new SolidColorBrush((System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#21bb2e"))
                        });
                    }
                }
                else
                {
                    NoticeDemoViewModel.OpenMsg(EnumPromptType.Info, MainViewModel.GetInstance().window, "提示", $"文件不存在，{path}!");
                }
            });
            //打开文件目录
            OpenCommand = new RelayCommand(() =>
            {
                System.Diagnostics.Process.Start("Explorer", "/select," + logHelper.GetLogConfigInstance().directRollfileAppender.File);
                logHelper.GetLogConfigInstance().OpenFile(logHelper.GetLogConfigInstance().directRollfileAppender.File);
            });
        }

        /// <summary>
        /// 读取文件
        /// </summary>
        /// <param name="path"></param>
        public DataTable ReadFile(string path)
        {
            DataTable dt = new DataTable();
            dt.Columns.AddRange(new[]
            {
                new DataColumn("TIME"),
                new DataColumn("LOGGER"),
                new DataColumn("NAME"),
                new DataColumn("PRIORITY"),
                new DataColumn("MESSAGE"),
            });
            //读取文件
            string s = "";
            using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (StreamReader sr = new StreamReader(fs, System.Text.Encoding.Default))
                {
                    s = sr.ReadToEnd();
                }
            }

            //正则表达式匹配，注意RegexOptions.RightToLeft
            var matches = Regex.Matches(s, @"(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) ([A-Z, ]{0,15}) ([A-Z,a-z]{0,20}) (\[\d{1}\]) (.*)", RegexOptions.RightToLeft);

            foreach (Match m in matches)
            {
                var time = m.Groups[1].Value;
                var logger = m.Groups[2].Value;
                var name = m.Groups[3].Value;
                var priority = m.Groups[4].Value;
                var msg = m.Groups[5].Value;
                var dr = dt.NewRow();
                dr.ItemArray = new[] { time, logger, name, priority, msg };
                dt.Rows.InsertAt(dr, 0);
            }
            return dt;
        }

        /// <summary>
        /// 选中改变
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ItemPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "IsChecked")
            {
                BookEx bookEx = sender as BookEx;

                if (bookEx != null)
                {
                    IEnumerable<BookEx> bookExs = BookExs.Where(b => b.IsChecked == true);

                    StringBuilder builder = new StringBuilder();
                    SelectBookExs.Clear();
                    foreach (BookEx item in bookExs)
                    {
                        builder.Append(item.BookN.Name + " ");
                        SelectBookExs.Add((BookEx)item);
                    }
                    SelectedText = builder == null ? string.Empty : builder.ToString();
                }
            }
        }
        #endregion


    }
}
