using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using Aitex.Core.RT.Event;
using Aitex.Core.Util;
using Caliburn.Micro;
using DocumentFormat.OpenXml.Drawing;
using MECF.Framework.Common.Aitex.Core.RT.EMS;
using MECF.Framework.Common.DataCenter;
using MECF.Framework.Common.OperationCenter;
using MECF.Framework.UI.Client.CenterViews.DataLogs.Event;
using MECF.Framework.UI.Client.ClientBase;
using OpenSEMI.ClientBase;
using OpenSEMI.ClientBase.Command;
using SciChart.Core.Extensions;
using Sicentury.Core.Collections;

namespace MECF.Framework.UI.Client.CenterViews.Maintain.ViewModels
{
    public class MaintainEventViewModel : UiViewModelBase, ISupportMultipleSystem
    {
        #region Properties

        MaintainEventView view;

        public ICommand NavigateCommand { get; set; }

        /// <summary>
        /// 搜索条件:开始时间
        /// </summary>
        public DateTime SearchBeginTime
        {
            get => view.wfTimeFrom.Value;
            set
            {
                view.wfTimeFrom.Value = value;
                NotifyOfPropertyChange(nameof(SearchBeginTime));
            }
        }

        /// <summary>
        /// 搜索条件:结束时间
        /// </summary>
        public DateTime SearchEndTime
        {
            get => view.wfTimeTo.Value;
            set
            {
                view.wfTimeTo.Value = value;
                NotifyOfPropertyChange(nameof(SearchEndTime));
            }
        }

        private List<string> _plannames = new();

        /// <summary>
        /// 复选框选项:PlanNames（List不会更新）
        /// </summary>
        public List<string> PlanNames
        {
            get { return _plannames; }
            set
            {
                _plannames = value;
                NotifyOfPropertyChange(nameof(PlanNames));
            }
        }

        private ObservableCollection<string> _planmodules = new();

        /// <summary>
        /// 复选框选项:PlanModules（随着planname更新）
        /// </summary>
        public ObservableCollection<string> PlanModules
        {
            get { return _planmodules; }
            set
            {
                _planmodules = value;
                NotifyOfPropertyChange(nameof(PlanModules));
            }
        }

        private Dictionary<string,List<string>> planmoduledic = new Dictionary<string,List<string>>();

        private string _searchplanname = "";

        /// <summary>
        /// 搜索条件:Plan
        /// </summary>
        public string SearchPlanName
        {
            get { return _searchplanname; }
            set
            {
                if (_searchplanname != value)
                {
                    _searchplanname = value;
                    NotifyOfPropertyChange(nameof(SearchPlanName));

                    SearchPlanModule = "";
                    PlanModules.Clear();

                    if (planmoduledic.Keys.Contains(value))
                    {
                        planmoduledic[value].ForEach(PlanModules.Add);
                    }
                }
               
            }
        }

        private string _searchplanmodule = "";

        /// <summary>
        /// 搜索条件:Module
        /// </summary>
        public string SearchPlanModule
        {
            get { return _searchplanmodule; }
            set
            {
                _searchplanmodule = value;
                NotifyOfPropertyChange(nameof(SearchPlanModule));
            }
        }

        private List<MaintainerItemConfigInfo> items = new();

        private List<string> _parentitemnames = new();
        /// <summary>
        /// 复选框选项:ParentItemNames（List不会更新）
        /// </summary>
        public List<string> ParentItemNames
        {
            get { return _parentitemnames; }
            set
            {
                _parentitemnames = value;
                NotifyOfPropertyChange(nameof(ParentItemNames));
            }
        }

        private ObservableCollection<string> _itemnames = new();
        /// <summary>
        /// 复选框选项:ParentItemNames（随着ParentItemName更新）
        /// </summary>
        public ObservableCollection<string> ItemNames
        {
            get { return _itemnames; }
            set
            {
                _itemnames = value;
                NotifyOfPropertyChange(nameof(ItemNames));
            }
        }

        private ObservableCollection<string> _itemindexs = new() {"" };
        /// <summary>
        /// 复选框选项:ParentItemNames（随着ParentItemName更新）
        /// </summary>
        public ObservableCollection<string> ItemIndexs
        {
            get { return _itemindexs; }
            set
            {
                _itemindexs = value;
                NotifyOfPropertyChange(nameof(ItemIndexs));
            }
        }

        private string _searchparentitemname="";
        /// <summary>
        /// 搜索条件:ParentItem
        /// </summary>
        public string SearchParentItemName
        {
            get { return _searchparentitemname; }
            set
            {
                if (_searchparentitemname != value)
                {
                    _searchparentitemname = value;
                    NotifyOfPropertyChange(nameof(SearchParentItemName));

                    ItemNames.Clear();
                    ItemIndexs.Clear();

                    ItemNames.Add("");
                    ItemIndexs.Add("");

                    items.ForEach(i =>
                    {
                        if (i.ParentName == _searchparentitemname)
                        {
                            if (!ItemNames.Contains(i.Name))
                            {
                                ItemNames.Add(i.Name);
                            }
                        }
                    });

                    SearchItemName = "";
                    SearchIndex = "";
                }
            }
        }

        private string _searchitemname = "";

        /// <summary>
        /// 搜索条件:Item
        /// </summary>
        public string SearchItemName
        {
            get { return _searchitemname; }
            set
            {
                if (_searchitemname != value)
                {
                    _searchitemname = value;
                    NotifyOfPropertyChange(nameof(SearchItemName));

                    ItemIndexs.Clear();

                    ItemIndexs.Add("");
                    ItemIndexs.Add("0");

                    items.ForEach(i =>
                    {
                        if (i.ParentName == _searchparentitemname && i.Name == _searchitemname)
                        {
                            if (!ItemIndexs.Contains(i.Index.ToString()))
                            {
                                ItemIndexs.Add(i.Index.ToString());
                            }
                        }
                    });

                    SearchIndex = "";
                }
            }
        }

        private string _searchindex = "0";

        /// <summary>
        /// 搜索条件:Index
        /// </summary>
        public string SearchIndex
        {
            get { return _searchindex; }
            set
            {
                _searchindex = value;
                NotifyOfPropertyChange(nameof(SearchIndex));
            }
        }

        private string _searchkeywords = "";

        /// <summary>
        /// 搜索条件:Index
        /// </summary>
        public string SearchKeyWords
        {
            get { return _searchkeywords; }
            set
            {
                _searchkeywords = value;
                NotifyOfPropertyChange(nameof(SearchKeyWords));
            }
        }

        List<MaintainEventInfo> queryresult = new();
        /// <summary>
        /// 返回受支持的分页每页容量。
        /// </summary>
        public List<int> PaginationCapacity { get; }

        private int _selectedPaginationCapacity;
        /// <summary>
        /// 返回选择的分页每页容量。
        /// </summary>
        public int SelectedPaginationCapacity
        {
            get => _selectedPaginationCapacity;
            set
            {
                _selectedPaginationCapacity = value;
                Query();
            }
        }

        /// <summary>
        /// 更新分页信息。
        /// <para>Tuple.Item1: 当前页号</para>
        /// <para>Tuple.Item2: 总页号；设置为-1时表示忽略更新总页号。</para>
        /// </summary>
        private readonly IProgress<Tuple<int, int>> _progUpdatePaginationInfo;

        /// <summary>
        /// 更新查询状态。
        /// </summary>
        private readonly IProgress<bool> _progUpdateQueryStatus;

        public ObservableRangeCollection<MaintainEventInfo> SearchedResult { get; private set; }

        /// <summary>
        /// 显示查询到的事件日志列表。
        /// </summary>
        private readonly IProgress<List<MaintainEventInfo>> _progShowSearchingResult;

        private List<MaintainEventInfo> _alleventinfos = new();
        public List<MaintainEventInfo> AllEvenInfos
        {
            get { return _alleventinfos; }
            set
            {
                _alleventinfos = value;
                NotifyOfPropertyChange(nameof(AllEvenInfos));
            }
        }

        private bool _isLoading;
        /// <summary>
        /// 返回是否正在加载数据。
        /// </summary>
        public bool IsLoading
        {
            get => _isLoading;
            set
            {
                _isLoading = value;
                NotifyOfPropertyChange(nameof(IsLoading));
            }
        }

        /// <summary>
        /// 页码列表，用于快速跳转页面下拉框数据源。
        /// </summary>
        public ObservableRangeCollection<int> PaginationSource { get; }

        /// <summary>
        /// 页码信息。
        /// </summary>
        public string PageInfo => $"{_currentPage}/{_totalPage}";

        private int _currentPage;
        private int _totalPage;
        private int _selectedPage;
        
        public int SelectedPage
        {
            get => _selectedPage;
            set
            {
                _selectedPage = value;
                Query(_selectedPage);
            }
        }
        #endregion

        #region Constructors
        public MaintainEventViewModel()
        {
            DisplayName = "MaintainEvent";

            SearchedResult = new ObservableRangeCollection<MaintainEventInfo>();

            PaginationSource = new ObservableRangeCollection<int>();

            NavigateCommand = new BaseCommand<string>(Navigate, (o) => true);

            // 分页支持的每页Log数量
            //! 最小每页条目数使用30，以保证正好显示一页而不出现纵向滚动条。
            PaginationCapacity = new List<int>
            {
                30,
                300,
                3000
            };

            _selectedPaginationCapacity = PaginationCapacity.Last();
            _totalPage = 1;
            _currentPage = 1;

            #region 获取plan搜索条件信息

            List<MaintainerInfo> maintainerlist = (List<MaintainerInfo>)QueryDataClient.Instance.Service.GetData("MaintainManager.MaintainerInfos");

            PlanNames.Add("");
            planmoduledic.Add("", new List<string>() { "" });
            foreach (MaintainerInfo item in maintainerlist)
            {
                PlanNames.AddIfNotContains(item.Name);
                if (!planmoduledic.ContainsKey(item.Name))
                {
                    planmoduledic.Add(item.Name, new List<string>() { "" });
                }

                planmoduledic[item.Name].AddIfNotContains(item.Module);
               
            }

            #endregion

            #region 获取item搜索条件信息

            items = (List<MaintainerItemConfigInfo>)QueryDataClient.Instance.Service.GetData("MaintainManager.MaintainerConfigItems");

            ParentItemNames = new List<string>() { "" };
            ItemNames = new ObservableCollection<string>() { "" };
            ItemIndexs = new ObservableCollection<string> { "0" };
            items.ForEach(i =>
            {
                ParentItemNames.AddIfNotContains(i.ParentName);
            });
            #endregion

            #region 显示查询到的列表

            _progShowSearchingResult = new Progress<List<MaintainEventInfo>>((queryRet =>
            {
                if (SearchedResult == null)
                    SearchedResult = new ObservableRangeCollection<MaintainEventInfo>();
                else
                    SearchedResult.Clear();

                queryRet.ForEach(i =>
                {
                    foreach (var item in items)
                    {
                        if (item.ParentName == i.ParentItemName && item.Name == i.ItemName && item.Index == i.Index)
                        {
                            i.Description = item.Description;
                            break;
                        }
                    }
                });

                queryresult = queryRet;
                SearchedResult.AddRange(queryRet);
            }));

            #endregion

            #region 更新分页信息

            _progUpdatePaginationInfo = new Progress<Tuple<int, int>>(pageInfo =>
            {
                _currentPage = pageInfo.Item1;

                if (pageInfo.Item2 > 0)
                {
                    _totalPage = pageInfo.Item2;
                    PaginationSource.Clear();
                    PaginationSource.AddRange(Enumerable.Range(1, _totalPage));
                    NotifyOfPropertyChange(nameof(PaginationSource));
                }

                NotifyOfPropertyChange(nameof(PageInfo));

                _selectedPage = _currentPage;
                NotifyOfPropertyChange(nameof(SelectedPage));
            });

            #endregion

            #region 更新查询状态

            _progUpdateQueryStatus = new Progress<bool>(isBusy =>
            {
                IsLoading = isBusy;
            });

            #endregion
        }

        #endregion

        #region Functions

        public void Navigate(string args)
        {
            switch (args)
            {
                case "first":
                    if (_currentPage == 1)
                        return;
                    _currentPage = 1;
                    break;

                case "previous":
                    if (_currentPage > 1)
                        _currentPage--;
                    break;

                case "next":
                    if (_currentPage < _totalPage)
                        _currentPage++;
                    break;

                case "last":
                    if (_currentPage == _totalPage)
                        return;
                    _currentPage = _totalPage;
                    break;

                default:
                    return;
            }

            Query(_currentPage);
        }

        protected override void OnInitialize()
        {
            ActiveUpdateData = false;   //关闭界面后不开启后台线程，减少开销
        }

        protected override void OnViewLoaded(object view)
        {
            base.OnViewLoaded(view);

            // 默认的查询时间设置为当天
            this.view = (MaintainEventView)view;
            SearchBeginTime = DateTime.Today.AddDays(-30);
            SearchEndTime = DateTime.Today.AddDays(1).AddTicks(-1);
            Preload();
        }

        private void Preload()
        {
            Query();
        }

        public void Filter()
        {
            SearchedResult.Clear();
            var keywords = SearchKeyWords.ToLower();
            queryresult.ForEach(i =>
            {

                if (i.PlanName.ToLower().Contains(keywords) ||
                i.PlanModule.ToLower().Contains(keywords) ||
                i.ParentItemName.ToLower().Contains(keywords) ||
                i.ItemName.ToLower().Contains(keywords) ||
                i.Description.ToLower().Contains(keywords) ||
                i.Record.ToLower().Contains(keywords))
                {
                    SearchedResult.Add(i);
                }
            });
        }

        /// <summary>
        /// 查询数据。
        /// </summary>
        /// <param name="page">待查询的页号</param>
        /// <param name="isIncludeFilter">是否包含过滤条件。</param>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        public void Query(int page = -1)
        {

            if (SearchBeginTime > SearchEndTime)
            {
                DialogBox.ShowError("Time range invalid, start time should be early than end time");
                return;
            }

            Task.Run(() =>
            {
                var searchingResult = new List<MaintainEventInfo>();

                // 查询开始
                _progUpdateQueryStatus.Report(true);

                if (page <= -1) // Query按钮按下，或首次加载界面
                {
                    // 统计总页数
                    var rowCount = QueryRowAmount(
                        SearchBeginTime, 
                        SearchEndTime, 
                        SearchPlanName,
                        SearchPlanModule,
                        SearchParentItemName, 
                        SearchItemName,
                        SearchIndex == "" ? -1 : int.Parse(SearchIndex));

                    var totalPage = (int)Math.Ceiling(rowCount / (double)SelectedPaginationCapacity);

                    // 首次查询第一页
                    searchingResult = QueryEventLogs(
                        1,
                        SelectedPaginationCapacity,
                        SearchBeginTime,
                        SearchEndTime,
                        SearchPlanName,
                        SearchPlanModule,
                        SearchParentItemName,
                        SearchItemName,
                        SearchIndex == "" ? -1 : int.Parse(SearchIndex));

                    // 更新页面信息
                    _progUpdatePaginationInfo.Report(new Tuple<int, int>(1, totalPage));


                }
                else if (page >= 1)
                {
                    // 翻页按钮按下
                    searchingResult = QueryEventLogs(
                        page,
                        SelectedPaginationCapacity,
                        SearchBeginTime,
                        SearchEndTime,
                        SearchPlanName,
                        SearchPlanModule,
                        SearchParentItemName,
                        SearchItemName,
                        SearchIndex == "" ? -1 : int.Parse(SearchIndex));

                    // 更新页面信息
                    _progUpdatePaginationInfo.Report(new Tuple<int, int>(page, -1));

                }
                else
                {
                    throw new ArgumentOutOfRangeException(nameof(page), "invalid page number.");
                }

                // 显示结果
                _progShowSearchingResult.Report(searchingResult);

                // 查询完毕
                _progUpdateQueryStatus.Report(false);

            });
        }

        #endregion

        #region 数据库查询
        /// <summary>
        /// 获取查询语句中select部分表达式。
        /// </summary>
        private string GetEventLogQuerySql(DateTime begintime, DateTime endtime)
        {
            return
                "SELECT \"planname\", \"planmodule\", \"itemparentname\", \"itemname\", \"uid\",\"createtime\" , \"role\", \"detial\" FROM \"maintenance_event_data\"" +
                GetWhereTimeRangeExpression(begintime, endtime);
        }

        /// <summary>
        /// 获取EventLog行数查询语句中select部分表达式。
        /// </summary>
        private string GetEventCountSql(DateTime begintime, DateTime endtime)
        {
            return
                "SELECT COUNT(1) FROM \"maintenance_event_data\"" + GetWhereTimeRangeExpression(begintime, endtime);
        }

        /// <summary>
        /// 获取WHERE条件中的“时间范围”子句。
        /// <para>注意：所有Select语句构造时必须包含TimeRange条件。</para>
        /// </summary>
        /// <returns></returns>
        private string GetWhereTimeRangeExpression(DateTime begintime, DateTime endtime)
        {

            var sql = new StringBuilder(
                $" WHERE \"createtime\" BETWEEN '{begintime:yyyy/MM/dd HH:mm:ss}' AND '{endtime:yyyy/MM/dd HH:mm:ss}'");

            return sql.ToString();
        }

        /// <summary>
        /// 获取WHERE条件中的plan条件子句。
        /// </summary>
        /// <returns></returns>
        private string GetWherePlanExpression(string planname = "", string module = "")
        {
            return ((planname == "") ? "" : $" AND \"planname\" = '{planname}'")
                + ((module == "") ? "" : $" AND \"planmodule\" = '{module}'");
        }

        /// <summary>
        /// 获取WHERE条件中的item条件子句。
        /// </summary>
        /// <returns></returns>
        private string GetWhereItemExpression(string itemparentname = "", string itemname = "", int index = -1)
        {
            return ((itemparentname == "") ? "" : $" AND \"itemparentname\" = '{itemparentname}'")
                + ((itemname == "") ? "" : $" AND \"itemname\" = '{itemname}'")
                + ((index == -1) ? "" : $"AND \"index\" = '{index}'");
        }

        /// <summary>
        /// 获取WHERE条件中的“关键字”子句。
        /// </summary>
        /// <returns></returns>
        private string GetWhereQueryKeyWordsExpression(string keywords)
        {
            return string.IsNullOrEmpty(keywords)
                ? ""
                : $" AND (lower(\"description\") like lower('%{keywords}%'))" + $" AND (lower(\"detial\") like lower('%{keywords}%'))";
        }

        /// <summary>
        /// 获取SQL查询语句中的分页表达式。
        /// </summary>
        /// <param name="countPerPage"></param>
        /// <param name="currentPage"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        private string GetPaginationExpression(int countPerPage, int currentPage)
        {
            if (countPerPage <= 0)
                throw new ArgumentOutOfRangeException(nameof(countPerPage),
                    "the amount items per page can not be less than 1.");

            if (currentPage <= 0)
                throw new ArgumentOutOfRangeException(nameof(currentPage),
                    "the current page required can not be less than 1.");



            return $" ORDER BY \"createtime\" LIMIT {countPerPage} OFFSET {countPerPage * (currentPage - 1)}";
        }

        /// <summary>
        /// 查询当前条件下共有多少行数据。
        /// <param name="isIncludeFilter">是否包含过滤条件。</param>
        /// </summary>
        public int QueryRowAmount(
            DateTime begintime,
            DateTime endtime,
            string planname,
            string module,
            string itemparentname,
            string itemname,
            int index)
        {
            string s1 = GetEventCountSql(begintime, endtime);
            string s2 = planname == "" ? "" : GetWherePlanExpression(planname, module);
            string s3 = itemparentname == "" ? "" : GetWhereItemExpression(itemparentname, itemname, index);
            //string s4 = keywords == "" ? "" : GetWhereQueryKeyWordsExpression(keywords);
            var sql = s1 + s2 + s3;

            var dt = QueryDataClient.Instance.Service.QueryData(sql);

            // 未查询到任何数据。
            if (dt == null || dt.Rows.Count <= 0 || dt.Columns.Count <= 0)
                return 0;

            // 返回满足当前条件的行数。
            return int.Parse(dt.Rows[0][0].ToString());
        }

        /// <summary>
        /// 查询符合条件的事件日志。
        /// </summary>
        /// <param name="page">待查询页码。0:查询所有数据而不分页；其它：查询指定的页码。</param>
        /// <param name="isIncludeFilter">是否包含过滤条件。</param>
        /// <exception cref="ArgumentOutOfRangeException">页码错误，页码必须为大于等于0的整数。</exception>
        /// <returns></returns>
        public List<MaintainEventInfo> QueryEventLogs(
            int page,
            int pageSize,
            DateTime begintime,
            DateTime endtime,
            string planname,
            string module,
            string itemparentname,
            string itemname,
            int index)
        {
            if (page < 0)
                throw new ArgumentOutOfRangeException(nameof(page), "the page number must be greater than 0.");

            string s1 = GetEventLogQuerySql(begintime, endtime);
            string s2 = planname == "" ? "" : GetWherePlanExpression(planname, module);
            string s3 = itemparentname == "" ? "" : GetWhereItemExpression(itemparentname, itemname, index);
            //string s4 = keywords == "" ? "" : GetWhereQueryKeyWordsExpression(keywords);

            var sql = s1 + s2 + s3;

            // page == 0 表示查询所有数据，仅导出Excel时使用。
            if (page > 0)
                sql += GetPaginationExpression(pageSize, page);

            var dt = QueryDataClient.Instance.Service.QueryData(sql);

            // 未查询到任何数据。
            if (dt == null || dt.Rows.Count <= 0 || dt.Columns.Count <= 0)
                return new List<MaintainEventInfo>();

            var list = new List<MaintainEventInfo>();

            foreach (var row in dt.Rows)
            {
                DataRow dr = row as DataRow;
                try
                {
                    MaintainEventInfo me = new MaintainEventInfo()
                    {
                        PlanName = dr[0].ToString(),
                        PlanModule = dr[1].ToString(),
                        ParentItemName = dr[2].ToString(),
                        ItemName = dr[3].ToString(),
                        Index = int.Parse(dr[4].ToString()),
                        MaintainTime = DateTime.Parse(dr[5].ToString()),
                        Recorder = dr[6].ToString(),
                        Record = dr[7].ToString()
                    };
                    list.Add(me);
                }
                catch (Exception ex)
                {

                    continue;
                }
            }

            return list;
        }

        #endregion
    }
}
