using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Window;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using HighWayIot.Repository.domain;
using HighWayIot.Repository.service;
using Models;
using HighWayIot.Winform.Business;
using System.Reflection;

namespace HighWayIot.Winform.UserControlPages.LogPages
{
    public partial class ExportPreviewForm : Form
    {
        private string _savePath = string.Empty;

        private List<ZxDailyReportEntity> _zxDailyReportEntities;

        private List<ExportTableEntity> _exportTableEntities = new List<ExportTableEntity>();

        private List<ZxWeightEntity> _zxWeightEntities;

        private List<ZxRecipeEntity> _zxRecipeEntities;

        private ZxWeightService _zxWeightService = ZxWeightService.Instance;

        private ZxRecipeService _zxRecipeService = ZxRecipeService.Instance;

        private DataTable dataTable;

        public ExportPreviewForm(List<ZxDailyReportEntity> entity)
        {
            _zxDailyReportEntities = entity;

            InitializeComponent();

            Init();
        }

        private void Init()
        {
            dataGridView1.AutoGenerateColumns = false;

            //查询所有称重信息
            _zxWeightEntities = _zxWeightService.GetWeightInfos();

            //查询所有配方信息
            _zxRecipeEntities = _zxRecipeService.GetRecipeInfos();

            //开始关联 生成报表
            foreach(ZxDailyReportEntity rawEntity in _zxDailyReportEntities)
            {
                ExportTableEntity exportTableEntity = new ExportTableEntity();
                ZxRecipeEntity recipeEntity = _zxRecipeEntities.Where(x => x.RecipeCode == rawEntity.RecipeCode).FirstOrDefault();
                ZxWeightEntity baseWeight = _zxWeightEntities.Where(x => x.RecipeCode == rawEntity.RecipeCode && x.MaterialType == "基部胶").FirstOrDefault();
                ZxWeightEntity midWeight = _zxWeightEntities.Where(x => x.RecipeCode == rawEntity.RecipeCode && x.MaterialType == "缓冲胶").FirstOrDefault();
                ZxWeightEntity faceWeight = _zxWeightEntities.Where(x => x.RecipeCode == rawEntity.RecipeCode && x.MaterialType == "胎面胶").FirstOrDefault();
                if (recipeEntity == null)
                {
                    continue;
                }
                exportTableEntity.RecipeCode = rawEntity.RecipeCode;
                exportTableEntity.RecipeName = rawEntity.RecipeName;
                exportTableEntity.SpecCode = rawEntity.SpecCode;
                exportTableEntity.SpecName = recipeEntity.RecipeSpecName;
                exportTableEntity.StartTime = rawEntity.StartTime.ToString("yyyy-MM-dd hh:mm:ss");

                //基部胶
                if (baseWeight != null)
                {
                    exportTableEntity.BaseRubName = baseWeight.MaterialName;
                    exportTableEntity.BaseRubThickness = baseWeight.SetThickness.ToString();
                    //基部胶宽度和层数（可能有两层
                    if (baseWeight.SetLayer2 == 0 || baseWeight.SetLayer2 == null)
                    {
                        exportTableEntity.BaseRubWidth = baseWeight.SetWidth.ToString();
                        exportTableEntity.BaseRubLayer = baseWeight.SetLayer.ToString();
                    }
                    else
                    {
                        exportTableEntity.BaseRubWidth = $"{baseWeight.SetWidth}/{baseWeight.SetWidth2}";
                        exportTableEntity.BaseRubLayer = $"{baseWeight.SetLayer}/{baseWeight.SetLayer2}";
                    }
                    exportTableEntity.BaseRubFinishTime = GeneralUtils.DateTimeToString(rawEntity.StartTime, rawEntity.BaseEndTime);
                }

                //中层胶
                if (midWeight != null)
                {
                    exportTableEntity.MidRubName = midWeight.MaterialName;
                    exportTableEntity.MidRubThickness = midWeight.SetThickness.ToString();
                    exportTableEntity.MidRubWidth = midWeight.SetWidth.ToString();
                    exportTableEntity.MidRubLayer = midWeight.SetLayer.ToString();
                    exportTableEntity.MidRubFinishTime = GeneralUtils.DateTimeToString(rawEntity.StartTime, rawEntity.MidEndTime);
                }

                //胎面胶
                if (faceWeight != null)
                {
                    exportTableEntity.FaceRubName = faceWeight.MaterialName;
                    exportTableEntity.FaceRubThickness = faceWeight.SetThickness.ToString();
                    //胎面胶宽度和层数（可能有两层
                    if (faceWeight.SetLayer2 == 0 || faceWeight.SetLayer2 == null)
                    {
                        exportTableEntity.FaceRubWidth = faceWeight.SetWidth.ToString();
                        exportTableEntity.FaceRubLayer = faceWeight.SetLayer.ToString();
                    }
                    else
                    {
                        exportTableEntity.FaceRubWidth = $"{faceWeight.SetWidth}/{faceWeight.SetWidth2}";
                        exportTableEntity.FaceRubLayer = $"{faceWeight.SetLayer}/{faceWeight.SetLayer2}";
                    }
                    exportTableEntity.FaceRubFinishTime = GeneralUtils.DateTimeToString(rawEntity.StartTime, rawEntity.FaceEndTime);
                }

                exportTableEntity.RawTireWidth = (faceWeight.SetThickness * 2 + faceWeight.SetWidth).ToString();
                exportTableEntity.RawTireWeight = rawEntity.RawTireWeight.ToString();
                exportTableEntity.RepeatWeight = rawEntity.RepeatWeight.ToString();


                _exportTableEntities.Add(exportTableEntity);
            }

            dataGridView1.DataSource = null;
            dataGridView1.DataSource = _exportTableEntities;

            try
            {
                dataTable = ToDataTable(_exportTableEntities.ToArray());
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        /// <summary>
        /// 路径选择按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PathSelectButton_Click(object sender, EventArgs e)
        {
            folderBrowserDialog1.Description = "请选择文件路径";

            if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
            {
                _savePath = folderBrowserDialog1.SelectedPath;
                PathTextBox.Text = _savePath;
            }
        }

        private void ExportButton_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(PathTextBox.Text))
            {
                MessageBox.Show("请先选择导出路径！");
                return;
            }
            ExportExcel(dataTable, _savePath);
            this.Close();
        }

        /// <summary>
        /// 导出Excel
        /// </summary>
        /// <param name="dt"></param>
        public void ExportExcel(DataTable dt, string path)
        {
            try
            {
                //创建一个工作簿
                IWorkbook workbook = new HSSFWorkbook();

                //创建一个 sheet 表
                ISheet sheet = workbook.CreateSheet(dt.TableName);

                //创建一行
                IRow rowH = sheet.CreateRow(0);

                //创建一个单元格
                ICell cell = null;

                //创建单元格样式
                ICellStyle cellStyle = workbook.CreateCellStyle();

                //创建格式
                IDataFormat dataFormat = workbook.CreateDataFormat();

                //设置为文本格式，也可以为 text，即 dataFormat.GetFormat("text");
                cellStyle.DataFormat = dataFormat.GetFormat("@");

                //设置列名
                foreach (DataColumn col in dt.Columns)
                {
                    //创建单元格并设置单元格内容
                    rowH.CreateCell(col.Ordinal).SetCellValue(col.Caption);

                    //设置单元格格式
                    rowH.Cells[col.Ordinal].CellStyle = cellStyle;
                }

                //写入数据
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    //跳过第一行，第一行为列名
                    IRow row = sheet.CreateRow(i + 1);

                    for (int j = 0; j < dt.Columns.Count; j++)
                    {
                        cell = row.CreateCell(j);
                        cell.SetCellValue(dt.Rows[i][j].ToString());
                        cell.CellStyle = cellStyle;
                    }
                }

                //设置导出文件路径
                //string path = HttpContext.Current.Server.MapPath("Export/");

                //设置新建文件路径及名称
                string savePath = $"{path}/203报表{DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss")}.xls";

                //创建文件
                FileStream file = new FileStream(savePath, FileMode.CreateNew, FileAccess.Write);

                //创建一个 IO 流
                MemoryStream ms = new MemoryStream();

                //写入到流
                workbook.Write(ms);

                //转换为字节数组
                byte[] bytes = ms.ToArray();

                file.Write(bytes, 0, bytes.Length);
                file.Flush();

                //还可以调用下面的方法，把流输出到浏览器下载
                //OutputClient(bytes);

                //释放资源
                bytes = null;

                ms.Close();
                ms.Dispose();

                file.Close();
                file.Dispose();

                workbook.Close();
                sheet = null;
                workbook = null;
                MessageBox.Show("导出成功！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void ExportPreviewForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            this.DialogResult = DialogResult.OK;
        }


        /// <summary>
        /// 实体类转dt
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entities"></param>
        /// <returns></returns>
        public DataTable ToDataTable<T>(T[] entities)
        {
            DataTable dataTable = new DataTable(typeof(T).Name);

            PropertyInfo[] properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);

            foreach (PropertyInfo propInfo in properties)
            {
                // Get the Description attribute if it exists
                var descriptionAttribute = propInfo.GetCustomAttribute<DescriptionAttribute>();
                string columnName = descriptionAttribute != null ? descriptionAttribute.Description : propInfo.Name;

                dataTable.Columns.Add(columnName, propInfo.PropertyType);
            }

            foreach (T entity in entities)
            {
                object[] values = new object[properties.Length];
                for (int i = 0; i < properties.Length; i++)
                {
                    values[i] = properties[i].GetValue(entity);
                }

                dataTable.Rows.Add(values);
            }

            return dataTable;
        }
    }   
}
