using DeviceRepairAndOptimization.Models;
using DeviceRepairAndOptimization.Models.DeviceRepair;
using DeviceRepairAndOptimization.Utils;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace DeviceRepairAndOptimization.Pages.RepairView
{
    public partial class page_RepairRecordView : FormBase
    {
        private KeyOfValuesV1 Template = new KeyOfValuesV1();

        /// <summary>
        /// 查询字符串
        /// </summary>
        private string FilterString
        {
            get
            {
                return txt_Filter.Text.Trim();
            }
        }

        /// <summary>
        /// 查询开始时间
        /// </summary>
        private DateTime FilterStartTime
        {
            get
            {
                if (de_Start.EditValue == null)
                    de_Start.EditValue = DateTime.Today.AddMonths(-1);
                return (DateTime)de_Start.EditValue;
            }
        }

        /// <summary>
        /// 查询结束时间
        /// </summary>
        private DateTime FilterEndTime
        {
            get
            {
                if (de_End.EditValue == null)
                    de_End.EditValue = DateTime.Today.AddHours(23).AddMinutes(59).AddSeconds(59);
                return (DateTime)de_End.EditValue;
            }
        }

        private Dictionary<string, string> ExportHeaderInfos = null;

        /// <summary>
        /// 当前选中行下标
        /// </summary>
        private int CurrentRowIndex;

        /// <summary>
        /// 当前选中对象
        /// </summary>
        private view_DeviceRepairRecord CurrentDataObject;

        public page_RepairRecordView()
        {
            InitializeComponent();

            this.Load += Page_RepairRecordView_Load;
            gridView1.CustomDrawRowIndicator += (s, e) =>
            {
                if (e.Info.IsRowIndicator && e.RowHandle >= 0)
                {
                    e.Info.DisplayText = (e.RowHandle + 1).ToString();
                    e.Appearance.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center;
                    e.Appearance.TextOptions.VAlignment = DevExpress.Utils.VertAlignment.Center;
                }
            };
        }

        private void Page_RepairRecordView_Load(object sender, EventArgs e)
        {
            InitializeGridData();
            de_Start.EditValue = DateTime.Today.AddMonths(-1);
            de_End.EditValue = DateTime.Today.AddHours(23).AddMinutes(59).AddSeconds(59);
            layoutControlGroup1.ViewInfo.OwnerILayoutControl.AllowCustomizationMenu = false;
        }

        /// <summary>
        /// 数据加载
        /// </summary>
        void InitializeGridData()
        {
            try
            {
                splashScreenManager1.ShowWaitForm();
                APIResponseData apiResponseData = Business.DeviceRepairManager.Instance.Filter(FilterString, FilterStartTime, FilterEndTime);

                List<view_DeviceRepairRecord> lst = new List<view_DeviceRepairRecord>();
                if (apiResponseData.Code == 1)
                    lst = apiResponseData.ToDeserializeObject<List<view_DeviceRepairRecord>>();

                dgvDatas.DataSource = lst;
                gridView1.BestFitColumns();
                splashScreenManager1.TryCloseWait();
            }
            catch (Exception ex)
            {
                splashScreenManager1.TryCloseWait();
                XtraMessageBoxHelper.Error(ex.Message);
            }
        }

        /// <summary>
        /// 导入
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Import_Click(object sender, EventArgs e)
        {
            try
            {
                if (!ApiHelper.Instance.RoleExistsAuth("BIZ_REPAIRRECORD_IMPORT").ToBool())
                {
                    XtraMessageBoxHelper.Error($"当前账号缺少此操作的权限");
                    return;
                }

                //扩展 - 自定义待选择文件类型
                OpenFileDialog ofd = new OpenFileDialog();
                //自定义待选择文件类型
                ofd.Filter = "Excel文件|*.xls;*.xlsx;*.xlsm;";
                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    string loadFilePath = ofd.FileName;
                    if (XtraMessageBoxHelper.Ask("确定现在导入吗？") == DialogResult.OK)
                    {
                        string fileExtension = Path.GetExtension(loadFilePath);


                        using (FileStream fs = new FileStream(loadFilePath, FileMode.Open, FileAccess.Read))
                        {
                            IWorkbook workbook;
                            if (fileExtension.Equals(".xls", StringComparison.CurrentCultureIgnoreCase))
                                workbook = new HSSFWorkbook(fs); // 处理.xls文件
                            else if (fileExtension.Equals(".xlsx", StringComparison.CurrentCultureIgnoreCase))
                                workbook = new XSSFWorkbook(fs); // 处理.xlsx文件
                            else
                            {
                                throw new Exception("不支持的文件格式");
                            }

                            // 获取第一个工作表
                            ISheet sheet = workbook.GetSheetAt(0);

                            // 读取表头
                            IRow headerRow = sheet.GetRow(0);

                            // 判断字段数量是否匹配模板
                            if (headerRow.LastCellNum != Template.KeyValuePairs.Count)
                            {
                                throw new Exception("数据模板列数不符合！");
                            }


                            DataTable ImportDatas = new DataTable();

                            #region 列头导入

                            List<string> NotFoundCell = new List<string>();
                            for (int colIndex = 0; colIndex < Template.KeyValuePairs.Count; colIndex++)
                            {
                                ICell cell = headerRow.GetCell(colIndex);
                                string CellValue = string.Empty;
                                if (cell != null)
                                    CellValue = cell.StringCellValue;

                                // 列名为空 或 非模板内列
                                CellTypeOfValue cellTemplate = Template.KeyValuePairs.FirstOrDefault(x => x.Caption.Equals(CellValue, StringComparison.CurrentCultureIgnoreCase));
                                if (string.IsNullOrWhiteSpace(CellValue) || cellTemplate == null)
                                {
                                    NotFoundCell.Add($"位置:【{ConvertColumnIndexToColumnName(colIndex)}】的值:{CellValue}不在模板中！");
                                    continue;
                                }

                                ImportDatas.Columns.Add(cellTemplate.FieldName, cellTemplate.FieldType);
                            }

                            #endregion


                            #region 读取数据行

                            // 读取数据行并将其添加到 DataTable 中
                            for (int rowIndex = 1; rowIndex <= sheet.LastRowNum; rowIndex++)
                            {
                                try
                                {
                                    IRow dataRow = sheet.GetRow(rowIndex);
                                    if (dataRow != null)
                                    {
                                        DataRow newRow = ImportDatas.NewRow();
                                        for (int colIndex = 0; colIndex < dataRow.LastCellNum; colIndex++)
                                        {
                                            ICell cell = dataRow.GetCell(colIndex);
                                            if (cell != null)
                                            {
                                                if (cell.CellType == CellType.Numeric)
                                                {
                                                    if (DateUtil.IsCellDateFormatted(cell))
                                                    {
                                                        // 日期类型
                                                        DateTime dateValue = cell.DateCellValue;
                                                        if (dateValue.Year == 1899)
                                                        {
                                                            DateTime nDateValue = new DateTime();
                                                            if (DateTime.TryParse(newRow[colIndex - 1] + "", out nDateValue))
                                                            {
                                                                nDateValue = new DateTime(nDateValue.Year, nDateValue.Month, nDateValue.Day, dateValue.Hour, dateValue.Minute, dateValue.Second);
                                                                newRow[colIndex] = nDateValue;
                                                                continue;
                                                            }
                                                            else
                                                            {
                                                                dateValue = dateValue.AddDays(1);
                                                            }
                                                        }

                                                        newRow[colIndex] = dateValue;
                                                    }
                                                    else
                                                    {
                                                        //其他数字类型
                                                        newRow[colIndex] = cell.NumericCellValue;
                                                    }
                                                }
                                                else if (cell.CellType == CellType.Blank)
                                                {
                                                    // 空白
                                                    newRow[colIndex] = DBNull.Value;
                                                }
                                                else if (cell.CellType == CellType.Formula)
                                                {
                                                    // 公式
                                                    if (fileExtension.Equals(".xls", StringComparison.CurrentCultureIgnoreCase))
                                                    {
                                                        XSSFFormulaEvaluator eva = new XSSFFormulaEvaluator(workbook);
                                                        if (eva.Evaluate(cell).CellType == CellType.Numeric)
                                                        {
                                                            newRow[colIndex] = eva.Evaluate(cell).NumberValue;
                                                        }
                                                        else
                                                        {
                                                            newRow[colIndex] = eva.Evaluate(cell).StringValue;
                                                        }
                                                    }
                                                    else
                                                    {
                                                        HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(workbook);
                                                        if (eva.Evaluate(cell).CellType == CellType.Numeric)
                                                        {
                                                            newRow[colIndex] = eva.Evaluate(cell).NumberValue;
                                                        }
                                                        else
                                                        {
                                                            newRow[colIndex] = eva.Evaluate(cell).StringValue;
                                                        }
                                                    }
                                                }
                                                else
                                                {
                                                    newRow[colIndex] = cell.ToString();
                                                }
                                            }
                                        }

                                        ImportDatas.Rows.Add(newRow);


                                    }
                                }
                                catch (Exception ex)
                                {
                                    throw ex;
                                }
                            }

                            #endregion

                            // 模板中不存在的列
                            if (NotFoundCell.Count > 0)
                                throw new Exception(string.Join("<br>", NotFoundCell));

                            List<DeviceRepairRecordModel> lst = ImportDatas.ToList<DeviceRepairRecordModel>();
                            APIResponseData apiResponseData = Business.DeviceRepairManager.Instance.Insertable(lst);
                            if (apiResponseData.Code == 1)
                                XtraMessageBoxHelper.Info(apiResponseData.Message);
                            else
                                XtraMessageBoxHelper.Error(apiResponseData.Message);
                            InitializeGridData();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Invoke(new Action(() => { InitializeGridData(); }));
                XtraMessageBoxHelper.Error(ex.Message);
            }
        }


        string ConvertColumnIndexToColumnName(int index)
        {
            index = index + 1;
            int system = 26;
            char[] digArray = new char[100];

            int i = 0;
            while (index > 0)
            {
                int mod = index % system;
                if (mod == 0)
                    mod = system;

                digArray[i++] = (char)(mod - 1 + 'A');
                index = (index - 1) / 26;
            }

            StringBuilder sb = new StringBuilder(i);
            for (int j = i - 1; j >= 0; j--)
            {
                sb.Append(digArray[j]);
            }
            return sb.ToString();
        }

        /// <summary>
        /// 搜索
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Search_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.FilterStartTime > DateTime.Today)
                    throw new Exception("开始时间不允许大于当前时间！");

                if (this.FilterStartTime >= this.FilterEndTime)
                    throw new Exception("开始时间不允许大于结束时间！");

                InitializeGridData();
            }
            catch (Exception ex)
            {
                XtraMessageBoxHelper.Error(ex.Message);
            }
        }

        /// <summary>
        /// 编辑
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Edit_Click(object sender, EventArgs e)
        {
            try
            {
                if (!ApiHelper.Instance.RoleExistsAuth("BIZ_REPAIRRECORD_EDIT").ToBool())
                {
                    XtraMessageBoxHelper.Error($"当前账号缺少此操作的权限");
                    return;
                }

                CurrentRowIndex = gridView1.FocusedRowHandle;
                if (!gridView1.IsValidRowHandle(CurrentRowIndex))
                {
                    throw new Exception("请先选择记录所在行！");
                }

                CurrentDataObject = gridView1.GetRow(CurrentRowIndex) as view_DeviceRepairRecord;
                if (CurrentDataObject == null)
                {
                    throw new Exception("请先选择记录所在行！");
                }

                using (page_RepairRecordEdit view = new page_RepairRecordEdit(CurrentDataObject.ToDeviceRepairRecord()))
                {
                    if (view.ShowDialog() == DialogResult.OK)
                    {
                        Invoke(new Action(() => { InitializeGridData(); }));
                        XtraMessageBoxHelper.Info("操作成功！");
                    }
                }
            }
            catch (Exception ex)
            {
                XtraMessageBoxHelper.Error(ex.Message);
            }
        }

        /// <summary>
        /// 表格选择行改变事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void gridView1_FocusedRowChanged(object sender, DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e)
        {
            try
            {
                if (e.FocusedRowHandle >= 0)
                {
                    CurrentRowIndex = e.FocusedRowHandle;
                    CurrentDataObject = gridView1.GetRow(e.FocusedRowHandle) as view_DeviceRepairRecord;
                }
            }
            catch (Exception ex)
            {
                XtraMessageBoxHelper.Error(ex.Message);
            }
        }

        /// <summary>
        /// 当前数据导出
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Export_Click(object sender, EventArgs e)
        {
            try
            {
                if (!ApiHelper.Instance.RoleExistsAuth("BIZ_REPAIRRECORD_EXPORT").ToBool())
                {
                    XtraMessageBoxHelper.Error($"当前账号缺少此操作的权限");
                    return;
                }

                List<view_DeviceRepairRecord> lst = new List<view_DeviceRepairRecord>();
                if (XtraMessageBoxHelper.AskYesNo("是否导出当前查询条件下的数据？（否为导出全部数据）") == DialogResult.No)
                {
                    splashScreenManager1.ShowWaitForm();
                    APIResponseData apiResponseData = Business.DeviceRepairManager.Instance.Filter("", DateTime.MinValue, DateTime.Today.AddDays(1));

                    if (apiResponseData.Code == 1)
                        lst = apiResponseData.ToDeserializeObject<List<view_DeviceRepairRecord>>();
                }
                else
                {
                    splashScreenManager1.ShowWaitForm();
                    lst = dgvDatas.DataSource as List<view_DeviceRepairRecord>;
                }

                SaveFileDialog sfd = new SaveFileDialog();
                sfd.Filter = "Excel文件|*.xlsx;*.xls;";
                string filePath = string.Empty;

                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    filePath = sfd.FileName;

                    if (lst != null && lst.Count > 0)
                    {
                        InitializeExportHeaderInfos();

                        DataTable tbDatas = lst.toDataTable();
                        DataTable tbContent = new DataTable();

                        // 添加行信息
                        foreach (var item in ExportHeaderInfos)
                        {
                            tbContent.Columns.Add(item.Value);
                        }

                        // 添加内容
                        foreach (DataRow row in tbDatas.Rows)
                        {
                            DataRow r = tbContent.NewRow();
                            foreach (DataColumn col in tbContent.Columns)
                            {
                                string ColumnName = ExportHeaderInfos.FirstOrDefault(x => x.Value == col.ColumnName).Key;

                                if (!string.IsNullOrWhiteSpace(ColumnName))
                                {
                                    if (timeColumns.Contains(ColumnName))
                                    {
                                        DateTime time = default(DateTime);
                                        if (DateTime.TryParse(row[ColumnName] + "", out time))
                                        {
                                            if (ColumnName.Equals("ActualDateOfIssuance", StringComparison.CurrentCultureIgnoreCase)
                                               || ColumnName.Equals("ReferenceDate", StringComparison.CurrentCultureIgnoreCase)
                                               )
                                            {
                                                r[col.ColumnName] = time.ToString("d");
                                            }
                                            else if (ColumnName.Equals("BasicStartTime", StringComparison.CurrentCultureIgnoreCase)
                                                || ColumnName.Equals("ReferenceTime", StringComparison.CurrentCultureIgnoreCase)
                                                )
                                            {
                                                r[col.ColumnName] = time.ToString("T");
                                            }
                                            else if (ColumnName.Equals("StartOfMaintenance", StringComparison.CurrentCultureIgnoreCase)
                                                || ColumnName.Equals("MaintenanceCompletionTime", StringComparison.CurrentCultureIgnoreCase)
                                                )
                                            {
                                                r[col.ColumnName] = time.ToString("g"); 
                                            }
                                        }
                                        else
                                        {
                                            r[col.ColumnName] = row[ColumnName];
                                        }
                                    }
                                    else
                                    {
                                        r[col.ColumnName] = row[ColumnName];
                                    }
                                }
                            }
                            tbContent.Rows.Add(r);
                        }

                        byte[] bt = ExcelExport.Export(tbContent);
                        File.WriteAllBytes(filePath, bt);
                    }
                }

                splashScreenManager1.TryCloseWait();
            }
            catch (Exception ex)
            {
                splashScreenManager1.TryCloseWait();
                XtraMessageBoxHelper.Error(ex.Message);
            }
        }


        string[] timeColumns = new string[] { "ActualDateOfIssuance", "ReferenceDate", "BasicStartTime", "ReferenceTime", "StartOfMaintenance", "MaintenanceCompletionTime" };
        void InitializeExportHeaderInfos()
        {
            if (ExportHeaderInfos == null)
            {
                ExportHeaderInfos = new Dictionary<string, string>();
                ExportHeaderInfos.Add("Plant", "工厂");
                ExportHeaderInfos.Add("Installations", "设备");
                ExportHeaderInfos.Add("PurchaseOrder", "订单");
                ExportHeaderInfos.Add("OrderType", "订单类型");
                ExportHeaderInfos.Add("TypesOfMaintenanceOperations", "维护作业类型");
                ExportHeaderInfos.Add("FullProgramCosts", "全部计划成本");
                ExportHeaderInfos.Add("Acttotcost", "ActTotCost");
                ExportHeaderInfos.Add("SystemStatus", "系统状态");
                ExportHeaderInfos.Add("TestLot", "检验批");
                ExportHeaderInfos.Add("Tin", "技术标识号");
                ExportHeaderInfos.Add("DescriptionOfTechnicalObjects", "技术对象描述");
                ExportHeaderInfos.Add("Descriptive", "描述");
                ExportHeaderInfos.Add("Importer", "输入者");
                ExportHeaderInfos.Add("ActualDateOfIssuance", "实际下达日期");
                ExportHeaderInfos.Add("BasicStartTime", "基本的开始时间");
                ExportHeaderInfos.Add("ReferenceDate", "参考日期");
                ExportHeaderInfos.Add("ReferenceTime", "参考时间");
                ExportHeaderInfos.Add("FinalModifier", "最后修改者");
                ExportHeaderInfos.Add("ReasonForDowntime", "停机原因");
                ExportHeaderInfos.Add("MaintenancePersonnel", "维修人员");
                ExportHeaderInfos.Add("StartOfMaintenance", "开始维修时间");
                ExportHeaderInfos.Add("MaintenanceCompletionTime", "维修完成时间");
                ExportHeaderInfos.Add("CauseOfFailure", "故障原因");
                ExportHeaderInfos.Add("MaintenanceContent", "维修内容");
                ExportHeaderInfos.Add("ReplacementParts", "配件");
                ExportHeaderInfos.Add("Downtime", "停机时长");
                ExportHeaderInfos.Add("MaintenancePeriod", "维修工时");
                ExportHeaderInfos.Add("RepairMethods", "维修方式");
                ExportHeaderInfos.Add("PhenomenologicalDistinction", "现象区分");
                ExportHeaderInfos.Add("VerificationNumber", "验证编号");
                ExportHeaderInfos.Add("OtherThan", "其它");
                ExportHeaderInfos.Add("DeviceStatus", "设备状态");
                ExportHeaderInfos.Add("Tier", "Tier");
                ExportHeaderInfos.Add("DidTheFaultCauseAShutdown", "故障是否导致停机");
                ExportHeaderInfos.Add("TierTrackers", "Tier跟踪人员");
                ExportHeaderInfos.Add("StatusFeedbackAndTime", "状态反馈/及时间");
                ExportHeaderInfos.Add("PartsAndServiceRequisitionTime", "配件/服务申购时间");
                ExportHeaderInfos.Add("PartsAndServiceArrivalTime", "配件/服务到货时间");
                ExportHeaderInfos.Add("PmAndAmAssociatedProjectLocation", "PM/AM关联项目位置");
            }
        }
    }
}
