using BPASmartClient.Helper;
using BPASmartClient.IoT;
using BPASmartClient.Message;
using BPASmartClient.Model;
using Microsoft.Toolkit.Mvvm.ComponentModel;
using Microsoft.Toolkit.Mvvm.Input;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using System.Windows.Threading;

namespace BPASmartClient.ViewModel
{
    /// <summary>
    /// 日志界面
    /// </summary>
    public class LogViewModel : ObservableObject
    {
        #region 变量
        //定时上报文件到阿里云
        public DispatcherTimer UpDataFileTimer;
        //定时清除界面日志
        public DispatcherTimer dispatcherTimer;
        public string ClientId = System.Configuration.ConfigurationManager.AppSettings["ClientId"].ToString();
        public ObservableCollection<LogModel> LogDataGridData { get; set; }
        private ObservableCollection<LogModel> _LogModels;public ObservableCollection<LogModel> LogDataGrid
        {
            get
            {
                return _LogModels;
            }
            set
            {
                if (_LogModels == value)
                    return;
                _LogModels = value;
                OnPropertyChanged("LogDataGrid");
            }
        }
        private bool _RealTimeModel = true;public bool RealTimeModel
        {
            get
            {
                return _RealTimeModel;
            }
            set
            {
                if (_RealTimeModel == value)
                    return;
                _RealTimeModel = value;
                OnPropertyChanged("RealTimeModel");
            }
        }
        private bool _TimedClear = true;public bool TimedClear
        {
            get
            {
                return _TimedClear;
            }
            set
            {
                if (_TimedClear == value)
                    return;
                _TimedClear = value;
                OnPropertyChanged("TimedClear");
            }
        }
        private string _SelectedText = "";
        public string SelectedText
        {
            get
            {
                return _SelectedText;
            }
            set
            {
                if (_SelectedText == value)
                    return;
                _SelectedText = value;
                OnPropertyChanged("SelectedText");
            }
        }
        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;
            }
        }
        #endregion

        #region 单一
        private volatile static LogViewModel _Instance;
        public static LogViewModel GetInstance() => _Instance ?? (_Instance = new LogViewModel());
        private LogViewModel()
        {
            Init();
        }
        #endregion

        #region 函数
        /// <summary>
        /// 初始化
        /// </summary>
        public void Init()
        {
            logHelper.Fun_InitLog(System.AppDomain.CurrentDomain.BaseDirectory);
            if (LogDataGrid == null) LogDataGrid = new ObservableCollection<LogModel>();
            if (LogDataGridData == null) LogDataGridData = new ObservableCollection<LogModel>();
            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"));
            //一般日志
            MessageLog.GetInstance.InfoNotify = new Action<string>((s) =>
            {
                System.Windows.Application.Current?.Dispatcher.Invoke((Action)(() =>
                {
                    LogModel logModel = new LogModel { message = s, type = "Info" };
                    LogDataGridData.Insert(0, logModel);
                    AddLog(logModel);
                    logHelper.GetLogConfigInstance().WriteLog(LogLevel.INFO, s);
                }));
            });
            //设备日志
            MessageLog.GetInstance.DeviceProcessLogNotify = new Action<string, string>((id, s) =>
            {
                System.Windows.Application.Current?.Dispatcher.Invoke((Action)(() =>
                {
                    LogModel logModel = new LogModel { message = s, type = "DeviceLog" };
                    LogDataGridData.Insert(0, logModel);
                    AddLog(logModel);
                    logHelper.GetLogConfigInstance().WriteLog(LogLevel.DEBUG, s);
                }));
            });
            //设备告警日志
            MessageLog.GetInstance.DeviceAlarmLogNotify = new Action<string, string>((id, s) =>
            {
                System.Windows.Application.Current?.Dispatcher.Invoke((Action)(() =>
                {
                    LogModel logModel = new LogModel { message = id, type = "DeviceAlarm" };
                    LogDataGridData.Insert(0, logModel);
                    AddLog(logModel);
                    logHelper.GetLogConfigInstance().WriteLog(LogLevel.WARN, id);
                }));
            });
            //错误日志
            MessageLog.GetInstance.ExInfoNotify = new Action<string>((s) =>
            {
                System.Windows.Application.Current?.Dispatcher.Invoke((Action)(() =>
                {
                    LogModel logModel = new LogModel { message = s, type = "Error" };
                    LogDataGridData.Insert(0, logModel);
                    AddLog(logModel);
                    logHelper.GetLogConfigInstance().WriteLog(LogLevel.ERROR, s);
                    DataVClient.GetInstance().HttpAddLog(new LogTable
                    {
                        ClientId = ClientId,
                        LogTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                        LogType = "严重",
                        LogMessage = s,
                        LogVla = "错误日志"
                    });
                }));
            });

            ExcelCommand = new RelayCommand(() =>
            {
                ExcellOrder();
            });

            OpenCommand = new RelayCommand(() =>
            {
                string msg = string.Format("已找到日志文件,是否打开！      \n      1.如选中不打开，则弹出日志文件夹目录。\n      2.打开，则弹出日志文件夹目录，并打开文件。");
                if (System.Windows.MessageBox.Show(msg, "提示", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                {
                    System.Diagnostics.Process.Start("Explorer", "/select," + logHelper.GetLogConfigInstance().directRollfileAppender.File);
                    logHelper.GetLogConfigInstance().OpenFile(logHelper.GetLogConfigInstance().directRollfileAppender.File);
                }
                else
                    System.Diagnostics.Process.Start("Explorer", "/select," + logHelper.GetLogConfigInstance().directRollfileAppender.File);
            });

            dispatcherTimer = new DispatcherTimer();
            dispatcherTimer.Tick += delegate
            {
                System.Windows.Application.Current?.Dispatcher.Invoke((Action)(() =>
                {
                    if (LogDataGridData.Count > 200)
                    {
                        LogModel logModel= LogDataGridData.Last();
                        DeleteLog(logModel);
                        LogDataGridData.Remove(logModel);
                    }
                }));

            };
            dispatcherTimer.Interval = TimeSpan.FromSeconds(10);
            dispatcherTimer.Start();
            UpDataFileTimer = new DispatcherTimer();
            UpDataFileTimer.Tick += delegate
            {
                DataVClient.GetInstance().UpDataFile();
            };
            UpDataFileTimer.Interval = TimeSpan.FromHours(0.5);
            UpDataFileTimer.Start();
        }
        /// <summary>
        /// 增加日志
        /// </summary>
        public void AddLog(LogModel logModel)
        {
            BookEx book= SelectBookExs?.ToList().Find(par => par.IsChecked && par.BookN.Tag == logModel.type);
            if (book != null)
            {
                LogDataGrid.Insert(0, logModel);
            }
        }
        /// <summary>
        /// 刷新日志
        /// </summary>
        /// <param name="logModel"></param>
        public void RefreshLog()
        {
            LogDataGrid.Clear();
            LogDataGridData?.ToList().ForEach(b => {

                BookEx book = SelectBookExs?.ToList().Find(par => par.IsChecked && par.BookN.Tag == b.type);
                if (book != null)
                {
                    LogDataGrid.Add(b);
                }
            });
            
        }
        /// <summary>
        /// 删除日志
        /// </summary>
        public void DeleteLog(LogModel logModel)
        {
            LogModel log= LogDataGrid?.ToList().Find(par => par == logModel);
            if(log!=null) LogDataGrid.Remove(log);
        }

        /// <summary>
        /// 导出数据
        /// </summary>
        public void ExcellOrder()
        {
            if (LogDataGrid.Count > 0)
            {
                string text = "时间    类型    日志内容\n";
                LogDataGrid?.ToList().ForEach(temp =>
                {
                    text = text + temp.time + "    " + temp.type + "    " + temp.message + "\n";
                });
                SaveFileDialog openfile = new SaveFileDialog();
                openfile.Filter = "Txt文件(*.txt)|*.txt";
                if (openfile.ShowDialog() == false)
                {
                    return;
                }
                string path = openfile.FileName;
                if (!System.IO.File.Exists(path))
                {
                    //没有则创建这个文件
                    FileStream fs1 = new FileStream(path, FileMode.Create, FileAccess.Write);//创建写入文件   
                    StreamWriter sw = new StreamWriter(fs1);
                    sw.WriteLine(text);//开始写入值
                    sw.Close();
                    fs1.Close();
                }
                else
                {
                    FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Write);
                    StreamWriter sr = new StreamWriter(fs);
                    sr.WriteLine(text);//开始写入值
                    sr.Close();
                    fs.Close();
                }
                string msg = string.Format("记录导出完成,共导出记录{0}条,是否打开！", LogDataGrid.Count);
                if (System.Windows.MessageBox.Show(msg, "提示", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                {
                    logHelper.GetLogConfigInstance().OpenFile(openfile.FileName);
                }
            }
            else
                System.Windows.MessageBox.Show("无数据!");

        }
        /// <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.Replace("日志","") + ",");
                        SelectBookExs.Add((BookEx)item);
                    }
                    SelectedText = builder == null ? string.Empty : builder.ToString();
                    RefreshLog();
                }
            }
        }
        #endregion

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

    public class LogModel : ObservableObject
    {
        public string time { get; set; }
        private string _type;
        public string type
        {
            get
            {
                return _type;
            }
            set
            {
                if (_type == value)
                    return;
                _type = value;
                if (_type == "Error" || _type == "Error".ToUpper() || _type == "DeviceAlarm".ToUpper() || _type == "DeviceAlarm") foreground = new SolidColorBrush((System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#ed0032"));

                OnPropertyChanged("type");
                OnPropertyChanged("foreground");
            }
        }
        public string message { get; set; }
        private Brush _foreground;
        public Brush foreground
        {
            get
            {
                return _foreground;
            }
            set
            {
                if (_foreground == value)
                    return;
                _foreground = value;
                OnPropertyChanged("foreground");
            }
        }
        public LogModel()
        {
            foreground = new SolidColorBrush((System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#21bb2e"));
            time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        }
    }
}
