using Aitex.Common.Util;
using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using Caliburn.Micro;
using DocumentFormat.OpenXml.Bibliography;
using DocumentFormat.OpenXml.Drawing.Charts;
using DocumentFormat.OpenXml.InkML;
using DocumentFormat.OpenXml.Office2016.Drawing.ChartDrawing;
using DocumentFormat.OpenXml.Spreadsheet;
using MECF.Framework.Common.Aitex.Core.Common.DeviceData;
using MECF.Framework.Common.DataCenter;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.PMs;
using MECF.Framework.UI.Client.CenterViews.Core;
using MECF.Framework.UI.Client.ClientBase;
using Microsoft.VisualBasic;
using OfficeOpenXml;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;
using OfficeOpenXml.FormulaParsing.Excel.Functions.RefAndLookup;
using OfficeOpenXml.Style;
using SciChart.Charting.Model.DataSeries;
using SciChart.Charting.Visuals.Axes;
using SciChart.Charting.Visuals.RenderableSeries;
using SciChart.Data.Model;
using Sicentury.Core;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Dynamic;
using System.IO;
using System.IO.Packaging;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

namespace MECF.Framework.UI.Client.CenterViews.DataLogs.ProcessHistory
{
    public class ProcessHistoryTestViewModel : UiViewModelBase
    {
        #region Variables

        private IRange _timeRange;
        private IRange _visibleRangeValue;
        private AutoRange _autoRange;
        private List<ProcessDeviceItem> PMItemList { get; set; }

        private string _path = PathManager.GetAppDir() + "\\Export";

        /// <summary>
        /// 返回ViewModel绑定的视图对象。
        /// </summary>
        public UserControl View { get; private set; }

        public DateTime StartDateTime
        {
            get => ((ProcessHistoryTestView)View).wfTimeFrom.Value;
            set
            {
                ((ProcessHistoryTestView)View).wfTimeFrom.Value = value;
                NotifyOfPropertyChange(nameof(StartDateTime));
            }
        }

        public DateTime EndDateTime
        {
            get => ((ProcessHistoryTestView)View).wfTimeTo.Value;
            set
            {
                ((ProcessHistoryTestView)View).wfTimeTo.Value = value;
                NotifyOfPropertyChange(nameof(EndDateTime));
            }
        }

        public List<string> PmList { get; set; }

        private string cbSelectPM;

        public string CbSelectPM
        {
            get => cbSelectPM;
            set
            {
                cbSelectPM = value;
                PMItemList = (List<ProcessDeviceItem>)QueryDataClient.Instance.Service.GetData($"{cbSelectPM}.ProcessHistoryItemsDefault");//选择的PM变化时，重新加载模板
            }
        }

        private string _exportText;

        public string ExportText
        {
            get => _exportText;
            set
            {
                if (ProcessHistoryDataList == null)
                {
                    _exportText = "Export";
                }
                else
                {
                    int count = ProcessHistoryDataList.Count(item => item.IsExport);
                    _exportText = $"Export{count}";
                }
                NotifyOfPropertyChange(nameof(ExportText));
            }
        }

        private bool _selectRecipeIsNull;

        public bool SelectRecipeIsNull
        {
            get => _selectRecipeIsNull;
            set
            {
                _selectRecipeIsNull = value;
                NotifyOfPropertyChange(nameof(SelectRecipeIsNull));
            }
        }

        /// <summary>
        /// 选择的Recipe
        /// </summary>
        public RecipeProcessHistoryData RecipeProcessHistoryData { get; set; }

        private ObservableCollection<ProcessHistoryData> processHistoryDataList;

        /// <summary>
        /// 单个Recipe对应的Step数据集合
        /// </summary>
        public ObservableCollection<ProcessHistoryData> ProcessHistoryDataList
        {
            get => processHistoryDataList;
            set
            {
                processHistoryDataList = value;
                NotifyOfPropertyChange(nameof(ProcessHistoryDataList));
            }
        }

        /// <summary>
        /// 选中Step
        /// </summary>
        public ProcessHistoryData SelectProcessHistoryData { get; set; }

        private ObservableCollection<ProcessHistoryDeviceData> stepDeviceDataList;

        /// <summary>
        /// Step单步时对应的硬件数据集合
        /// </summary>
        public ObservableCollection<ProcessHistoryDeviceData> StepDeviceDataList
        {
            get => stepDeviceDataList;
            set
            {
                stepDeviceDataList = value;
                NotifyOfPropertyChange(nameof(StepDeviceDataList));
            }
        }

        /// <summary>
        /// Step中选中硬件的数据
        /// </summary>
        public ProcessHistoryDeviceData StepSelectDeviceData { get; set; }

        private ObservableCollection<IRenderableSeries> appendedSeries;

        public ObservableCollection<IRenderableSeries> AppendedSeries
        {
            get => appendedSeries;
            set
            {
                appendedSeries = value;
                NotifyOfPropertyChange(nameof(AppendedSeries));
            }
        }

        public IRange VisibleRangeTime
        {
            get => _timeRange;
            set
            {
                _timeRange = value;
                NotifyOfPropertyChange(nameof(VisibleRangeTime));
            }
        }

        public IRange VisibleRangeValue
        {
            get => _visibleRangeValue;
            set
            {
                _visibleRangeValue = value;
                NotifyOfPropertyChange(nameof(VisibleRangeValue));
            }
        }

        public AutoRange ChartAutoRange
        {
            get => _autoRange;
            set
            {
                _autoRange = value;
                NotifyOfPropertyChange(nameof(ChartAutoRange));
            }
        }

        private bool _isExportNotBusy = true;

        public bool IsExportNotBusy
        {
            get => _isExportNotBusy;
            set
            {
                _isExportNotBusy = value;
                NotifyOfPropertyChange();
            }
        }

        private string _exportTXt = "Export";

        public string ExportTXt
        {
            get => _exportTXt;
            set
            {
                _exportTXt = value;
                NotifyOfPropertyChange();
            }
        }

        #endregion Variables

        protected override void OnViewLoaded(object _view)
        {
            base.OnViewLoaded(_view);
            View = (ProcessHistoryTestView)_view;
            IniUIData();
        }

        private void IniUIData()
        {
            PmList = new List<string>();
            for (int i = 1; i <= 2; i++)
            {
                if ((bool)QueryDataClient.Instance.Service.GetConfig($"System.SetUp.IsPM{i}Installed"))
                    PmList.Add($"PM{i}");
            }
            if (PmList.Count > 0)
                CbSelectPM = PmList[0];
            StartDateTime = DateTime.Now.Date;
            EndDateTime = DateTime.Now.Date.AddDays(1).AddTicks(-1);

            VisibleRangeTime = new DateRange(DateTime.Now.AddMinutes(-60), DateTime.Now.AddMinutes(60));
            VisibleRangeValue = new DoubleRange(0, 10);

            Refresh();
        }

        protected override void OnDeactivate(bool close)
        {
            ActiveUpdateData = true;
            base.OnDeactivate(close);
        }

        protected override void OnActivate()
        {
            base.OnActivate();

            EnableTimer(true);
        }

        public void SetExportAll(bool b)
        {
            if (ProcessHistoryDataList == null)
                return;

            foreach (var item in ProcessHistoryDataList)
                item.IsExport = b;
        }

        /// <summary>
        /// 根据选择的Recipe导出数据
        /// </summary>
        public void ExportRecipeProcessHistory()
        {
            if (ProcessHistoryDataList == null)
            {
                MessageBox.Show("没有选择的Recipe", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            SetBtn(false);
            MessageBoxResult result = MessageBox.Show("你确定要导出数据吗?", "提示", MessageBoxButton.YesNo, MessageBoxImage.Question);

            Task.Run(() =>
            {
                if (result == MessageBoxResult.Yes)
                {
                    try
                    {
                        List<ObservableCollection<ProcessHistoryDeviceData>> exportRecipeProcessHistoryData = new();

                        for (int i = 0; i < ProcessHistoryDataList.Count; i++)
                        {
                            if (ProcessHistoryDataList[i].IsExport)
                            {
                                var qeph = QueryExportProcessHistory(ProcessHistoryDataList[i]);
                                if (qeph == null)
                                    continue;
                                foreach (var data in qeph)
                                {
                                    data.StepNumber = ProcessHistoryDataList[i].StepNumber;
                                    data.StepName = ProcessHistoryDataList[i].StepName;
                                }

                                exportRecipeProcessHistoryData.Add(qeph);
                            }
                        }

                        if (exportRecipeProcessHistoryData.Count > 0)
                        {
                            SaveCsv(exportRecipeProcessHistoryData);
                            //SaveExcel(exportRecipeProcessHistoryData);
                            MessageBox.Show("数据导出完成", "成功", MessageBoxButton.OK, MessageBoxImage.Information);
                        }
                        else
                            MessageBox.Show("未选择导出的Step", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                    }
                    catch (Exception e)
                    {
                        MessageBox.Show(e.ToString(), "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                    }
                }
                SetBtn(true);
            });
        }

        private void SetBtn(bool b)
        {
            ExportTXt = b ? "Export" : "AwaitExport";
            IsExportNotBusy = b;
        }

        private void SaveCsv(List<ObservableCollection<ProcessHistoryDeviceData>> phdd)
        {
            StringBuilder csvContent = new StringBuilder();

            csvContent.Append("Date,Time,Wafer,Step,StepName,");
            for (int i = 0; i < phdd[0].Count; i++)
            {
                // 设置单元格的值为表头名
                csvContent.Append($"{phdd[0][i].DeviceName}[{phdd[0][i].Unit}],");
            }

            csvContent.AppendLine(); // 换行

            foreach (var processDataList in phdd)//所有Step循环
            {
                var stepDeviceData = processDataList
                    .Where(item => item.DeviceValue != null && item.DeviceValue.Count > 0)
                    .Select(item => item)
                    .FirstOrDefault(); // 如果没有找到，返回0

                if (stepDeviceData == null)
                    continue;

                // 遍历数组并写入 CSV 文件
                for (int i = 0; i < stepDeviceData.DeviceValue.Count; i++)
                {
                    var dateTime = new DateTime(long.Parse(stepDeviceData.TimeStamp[i]));
                    csvContent.Append(dateTime.ToString("yyyy-MM-dd") + ",");
                    csvContent.Append(dateTime.ToString("HH:mm:ss") + ",");
                    csvContent.Append(RecipeProcessHistoryData.WaferInf + ",");
                    csvContent.Append(processDataList[0].StepNumber + ",");
                    csvContent.Append(processDataList[0].StepName + ",");

                    for (int j = 0; j < processDataList.Count; j++)
                    {
                        if (i < processDataList[j].DeviceValue.Count)

                            csvContent.Append(processDataList[j].DeviceValue[i].ToString("F3") + ",");
                        else
                            csvContent.Append("0,");
                    }
                    csvContent.AppendLine(); // 换行
                }
            }

            // 保存Excel文件

            if (!Directory.Exists(_path))
                Directory.CreateDirectory(_path);

            var filePath = $"{_path}\\{DateTime.Now:yyyy-MM-dd HH-mm-ss} - {RecipeProcessHistoryData.Name}.csv";

            File.WriteAllText(filePath, csvContent.ToString());
        }

        private void SaveExcel(List<ObservableCollection<ProcessHistoryDeviceData>> phdd)
        {
            // 创建一个新的ExcelPackage实例
            using (ExcelPackage excelPackage = new ExcelPackage())
            {
                // 添加一个工作表
                ExcelWorksheet worksheet = excelPackage.Workbook.Worksheets.Add(RecipeProcessHistoryData.Name);

                // 将数据写入Excel工作表
                worksheet.Cells[1, 1].Value = "Date";
                worksheet.Cells[1, 2].Value = "Time";
                worksheet.Cells[1, 3].Value = "Wafer";
                //worksheet.Cells[1, 4].Value = "Tray";
                worksheet.Cells[1, 4].Value = "Step";
                worksheet.Cells[1, 5].Value = "StepName";

                for (int i = 0; i < phdd[0].Count; i++)
                {
                    // 设置单元格的值为表头名
                    worksheet.Cells[1, i + 6].Value = $"{phdd[0][i].DeviceName}[{phdd[0][i].Unit}]";
                }

                int k = 1;//拼接Step换行用
                foreach (var processDataList in phdd)//所有Step循环
                {
                    for (int i = 0; i < processDataList.Count; i++)//单步Step循环
                    {
                        for (int j = 0; j < processDataList[i].DeviceValue.Count; j++)//当前Step，一个硬件产生的所有数据循环
                        {
                            if (i == 0)//i==0意味着数据属于同一个Step
                            {
                                //单步数据的共同数据，采集时间、Step序号和Step名称
                                var dateTime = new DateTime(long.Parse(processDataList[i].TimeStamp[j]));
                                worksheet.Cells[k + j + 1, 1].Value = dateTime.ToString("yyyy-MM-dd");
                                worksheet.Cells[k + j + 1, 2].Value = dateTime.ToString("HH:mm:ss");
                                worksheet.Cells[k + j + 1, 3].Value = RecipeProcessHistoryData.WaferInf;
                                worksheet.Cells[k + j + 1, 4].Value = processDataList[i].StepNumber;
                                worksheet.Cells[k + j + 1, 5].Value = processDataList[i].StepName;
                            }

                            //获取数据值
                            worksheet.Cells[k + j + 1, i + 6].Value = processDataList[i].DeviceValue[j];
                            worksheet.Cells[k + j + 1, i + 6].Style.Numberformat.Format = "0.000";
                        }
                    }

                    k += processDataList[0].DeviceValue.Count;
                }

                // 保存Excel文件

                if (!Directory.Exists(_path))
                    Directory.CreateDirectory(_path);

                string xlsxFilePath = $"{_path}\\{DateTime.Now:yyyy-MM-dd HH-mm-ss} - {RecipeProcessHistoryData.Name}.xlsx";
                FileInfo fileInfo = new FileInfo(xlsxFilePath);

                // 设置所有单元格的水平和垂直对齐方式为居中
                worksheet.Cells.Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
                worksheet.Cells.Style.VerticalAlignment = ExcelVerticalAlignment.Center;

                // 自适应所有列的宽度
                worksheet.Cells.AutoFitColumns();
                excelPackage.SaveAs(fileInfo);
            }
        }

        private ObservableCollection<ProcessHistoryDeviceData> QueryExportProcessHistory(ProcessHistoryData processHistoryData)
        {
            if (string.IsNullOrEmpty(processHistoryData.StepBeginTime) || string.IsNullOrEmpty(processHistoryData.StepEndTime))
            {
                MessageBox.Show("Not complete time", "Error",
                    MessageBoxButton.OK,
                    MessageBoxImage.Error);
                return null;
            }
            var daySlices = DateRangeHelper.SplitInToHours(new DateRangeHelper(Convert.ToDateTime(processHistoryData.StepBeginTime), Convert.ToDateTime(processHistoryData.StepEndTime)), 12);
            return ProcessHistorySqlHelp.GetProcessHistoryDeviceData(daySlices, CbSelectPM, PMItemList);
        }

        public void HandExport()
        {
            if (!Directory.Exists(_path))
                Directory.CreateDirectory(_path);
            Process.Start("explorer.exe", _path);
        }

        public void AutoExport()
        {
            string path = (string)QueryDataClient.Instance.Service.GetData($"RT.AutoExpProcessHistory.Path");
            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);
            Process.Start("explorer.exe", path);
        }

        /// <summary>
        /// 根据时间段查询Recipe生产的历史记录
        /// </summary>
        public void QueryRecipeProcessHistory()
        {
            if (StartDateTime > EndDateTime)
            {
                MessageBox.Show("time range invalid, start time should be early than end time.", "Error",
                    MessageBoxButton.OK,
                    MessageBoxImage.Error);
                return;
            }

            var dialog = new ProcessHistoryInfMessageBoxViewModel(StartDateTime.ToString("yyyy-MM-dd HH:mm:ss"), EndDateTime.ToString("yyyy-MM-dd HH:mm:ss"), CbSelectPM);
            var wm = new WindowManager();

            dynamic settings = new ExpandoObject();
            settings.WindowStartupLocation = WindowStartupLocation.CenterOwner;
            settings.Title = "Recipe历史生产数据选择";
            settings.ResizeMode = ResizeMode.NoResize;
            settings.ShowInTaskbar = false;

            var bret = wm.ShowDialog(dialog, null, settings);
            if ((bool)bret)
            {
                if (dialog.RecipeProcessHistoryData == null)
                    return;

                RecipeProcessHistoryData = dialog.RecipeProcessHistoryData;
                SelectRecipeIsNull = true;
                ProcessHistoryDataList = ProcessHistorySqlHelp.QueryProcessHistoryData(dialog.RecipeProcessHistoryData.ProcessGuid, dialog.RecipeProcessHistoryData.Name, dialog.StepModel);
                StepDeviceDataList?.Clear();
                AppendedSeries?.Clear();
                Refresh();
            }
        }

        /// <summary>
        /// 选择Recipe后，自动查询当时记录的Step详情
        /// </summary>
        public void GetProcessHistory()
        {
            if (SelectProcessHistoryData == null)
                return;
            QueryProcessHistory(SelectProcessHistoryData);

            Refresh();
        }

        public void QueryProcessHistory(ProcessHistoryData processHistoryData)
        {
            if (string.IsNullOrEmpty(processHistoryData.StepBeginTime) || string.IsNullOrEmpty(processHistoryData.StepEndTime))
            {
                MessageBox.Show("Not complete time", "Error",
                    MessageBoxButton.OK,
                    MessageBoxImage.Error);
                return;
            }
            var daySlices = DateRangeHelper.SplitInToHours(new DateRangeHelper(Convert.ToDateTime(processHistoryData.StepBeginTime), Convert.ToDateTime(processHistoryData.StepEndTime)), 12);
            List<List<GasFlowSum>> gasFlowRunVent = new List<List<GasFlowSum>>();

            StepDeviceDataList = ProcessHistorySqlHelp.GetProcessHistoryDeviceData(daySlices, CbSelectPM, PMItemList);
        }

        /// <summary>
        /// 显示Charting历史数据记录
        /// </summary>
        public void DeviceCharting()
        {
            if (StepSelectDeviceData == null)
                return;
            GetDeviceCharting();
        }

        private void GetDeviceCharting()
        {
            RenderableSeriesProvide renderableSeries = new RenderableSeriesProvide();
            AppendedSeries = new ObservableCollection<IRenderableSeries> { renderableSeries.GetLineSeries(StepSelectDeviceData.DeviceName) };

            var dataSeries = AppendedSeries[0].DataSeries as XyDataSeries<DateTime, double>;
            var dateList = new List<DateTime>();
            var valueList = new List<double>();
            var metaList = new List<ParameterNodePoint>();

            // 数据记录点
            for (int i = 0; i < StepSelectDeviceData.DeviceValue.Count; i++)
            {
                var date = new DateTime(long.Parse(StepSelectDeviceData.TimeStamp[i]));
                var cellValue = StepSelectDeviceData.DeviceValue[i];

                dateList.Add(date);
                valueList.Add(cellValue);
                metaList.Add(new ParameterNodePoint(date, cellValue));
            }
            dataSeries.Append(dateList, valueList, metaList);

            Thread.Sleep(10);
            ChartAutoRange = AutoRange.Never;
            ((ProcessHistoryTestView)View).chart.ZoomExtents();
        }
    }
}