using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using Foresight.Data;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IronIntel.Contractor.ExportExcel
{
    /// <summary>
    /// Excel 导入。提供对xlsx文件的解析
    /// </summary>
    public class ImportFromExcel
    {
        /// <summary>
        /// 解析excel数据
        /// </summary>
        /// <param name="excelBytes">Excel Data</param>
        /// <returns></returns>
        public DataTable LoadExcelData(byte[] excelBytes, int headerrowindex = 1)
        {
            return LoadExcelData(excelBytes, "", headerrowindex);
        }

        public DataTable[] LoadAllExcelData(byte[] excelBytes)
        {
            MemoryStream stream = null;
            List<DataTable> list = new List<DataTable>();
            try
            {
                stream = new MemoryStream(excelBytes);
                using (SpreadsheetDocument sdoc = SpreadsheetDocument.Open(stream, false))
                {
                    foreach (Sheet sheet in sdoc.WorkbookPart.Workbook.Descendants<Sheet>())
                    {
                        if (sheet != null)
                        {
                            WorksheetPart wsp = (WorksheetPart)sdoc.WorkbookPart.GetPartById(sheet.Id);
                            Worksheet ws = wsp.Worksheet;
                            //取Cell值的时候使用
                            SharedStringTablePart tablePart = sdoc.WorkbookPart.SharedStringTablePart;
                            //得到第一个工作表的所有行
                            IEnumerable<Row> rows = ws.Descendants<Row>();
                            //第一行是标题，标题作为表的列名
                            Row headerRow = rows.First();
                            DataTable excelData = new DataTable(sheet.Name);
                            string columnName = "";
                            foreach (Cell hc in headerRow)
                            {
                                columnName = GetCellValue(hc, tablePart);
                                excelData.Columns.Add(columnName, GetCellDataType(hc));
                            }
                            //装载数据到DataTable里面
                            foreach (Row row in rows)
                            {
                                if (row.RowIndex == 1) continue;
                                DataRow excelRow = excelData.NewRow();
                                int i = 0;
                                foreach (Cell cell in row)
                                {
                                    excelRow[i] = GetCellValue(cell, tablePart);
                                    i++;
                                }
                                excelData.Rows.Add(excelRow);
                            }
                            list.Add(excelData);
                        }
                    }
                }
            }
            catch
            {
                //解析过程中出错误了，TODO
            }
            finally
            {
                if (stream != null) stream.Close();
            }
            return list.ToArray();
        }

        public DataTable LoadExcelDataByClient(byte[] excelBytes)
        {
            DataTable[] dts = ExcelClient.GetTables(excelBytes, true, true);

            if(dts != null && dts.Length > 0)
            {
                return dts[0];
            }
            return null;
        }

        /// <summary>
        /// 解析excel数据
        /// </summary>
        /// <param name="excelBytes">Excel Data</param>
        /// <param name="sheetName">Sheet Name</param>
        /// <returns></returns>
        public DataTable LoadExcelData(byte[] excelBytes, string sheetName, int headerrowindex)
        {
            MemoryStream stream = null;
            try
            {
                stream = new MemoryStream(excelBytes);
                using (SpreadsheetDocument sdoc = SpreadsheetDocument.Open(stream, false))
                {
                    Sheet sheet = null;
                    if (string.IsNullOrEmpty(sheetName))//没有特定的sheetname的时候，取第一个sheet
                        sheet = sdoc.WorkbookPart.Workbook.Descendants<Sheet>().FirstOrDefault();
                    else//根据sheetname取特定sheet
                        sheet = sdoc.WorkbookPart.Workbook.Descendants<Sheet>().Where((s) => s.Name == sheetName).First();
                    if (sheet != null)
                    {
                        WorksheetPart wsp = (WorksheetPart)sdoc.WorkbookPart.GetPartById(sheet.Id);
                        WorkbookStylesPart stylepart = sdoc.WorkbookPart.GetPartsOfType<WorkbookStylesPart>().FirstOrDefault();
                        Worksheet ws = wsp.Worksheet;
                        //取Cell值的时候使用
                        SharedStringTablePart tablePart = sdoc.WorkbookPart.SharedStringTablePart;
                        //得到第一个工作表的所有行
                        IEnumerable<Row> rows = ws.Descendants<Row>();
                        //第一行是标题，标题作为表的列名
                        Row headerRow = rows.ElementAt(headerrowindex - 1);//.First();
                        DataTable excelData = new DataTable(sheet.Name);
                        string columnName = "";
                        foreach (Cell hc in headerRow)
                        {
                            columnName = GetCellValue(hc, tablePart);
                            excelData.Columns.Add(columnName, GetCellDataType(hc));
                            if (hc.CellReference != null)
                            {
                                var colref = System.Text.RegularExpressions.Regex.Replace(hc.CellReference.Value, @"\d", "");//C30->C
                                excelData.Columns[excelData.Columns.Count - 1].Caption = colref;
                            }
                        }
                        
                        //装载数据到DataTable里面
                        foreach (Row row in rows)
                        {
                            if (row.RowIndex <= headerrowindex) continue;
                            DataRow excelRow = excelData.NewRow();
                            int i = 0;
                            foreach (Cell cell in row)
                            {
                                if (cell.CellReference != null)//row不包含未输入的单元
                                {
                                    var colref = System.Text.RegularExpressions.Regex.Replace(cell.CellReference.Value, @"\d", "");//C30->C
                                    int j = i;
                                    while (j < excelData.Columns.Count && excelData.Columns[j].Caption != colref)
                                    {
                                        j++;
                                    }
                                    if (excelData.Columns[j].Caption == colref)
                                    {
                                        excelRow[j] = GetCellValue(cell, tablePart, stylepart);
                                    }
                                }
                                else
                                {
                                    excelRow[i] = GetCellValue(cell, tablePart, stylepart);
                                }
                                i++;
                            }
                            excelData.Rows.Add(excelRow);
                        }
                        return excelData;
                    }
                }
            }
            catch (Exception ex)
            {
                //解析过程中出错误了，TODO
            }
            finally
            {
                if (stream != null) stream.Close();
            }
            return null;
        }
        /// <summary>
        /// 得到Excel 中 Cell的值
        /// </summary>
        /// <param name="c">Cell</param>
        /// <param name="stp"></param>
        /// <returns></returns>
        private string GetCellValue(Cell cell, SharedStringTablePart stringTablePart, WorkbookStylesPart stylepart = null)
        {
            if (cell.ChildElements.Count == 0) return "";
            string value = cell.CellValue.InnerText;
            if (cell.DataType != null && cell.DataType == CellValues.SharedString)
            {
                value = stringTablePart.SharedStringTable.ChildElements[int.Parse(value)].InnerText;
            }
            else if (cell.StyleIndex != null && cell.StyleIndex > 0 && stylepart != null)
            {
                try
                {
                    //int formatStyleIndex = Convert.ToInt32(cell.StyleIndex.Value);
                    //CellFormat cf = (CellFormat)stylepart.Stylesheet.CellFormats.ElementAt(formatStyleIndex);

                    //if (cf.NumberFormatId != null)
                    //{
                    //    var numberFormatId = cf.NumberFormatId.Value;
                    //    if (stylepart.Stylesheet.NumberingFormats != null)
                    //    {
                    //        var numberingFormat = stylepart.Stylesheet.NumberingFormats.Cast<NumberingFormat>().Single(f => f.NumberFormatId.Value == numberFormatId);
                    //        if(numberingFormat != null)
                    //        {
                    //            double dd = 0;
                    //            if (double.TryParse(value, out dd))
                    //            {
                    //                return dd.ToString(numberingFormat.FormatCode.Value);
                    //            }
                    //        }
                    //    }
                    //}
                    //else
                    //{
                    //    value = cell.InnerText;
                    //}
                    double d = 0;
                    if (double.TryParse(value, out d))
                    {
                        value = d.ToString();
                        CellFormat cf = (CellFormat)stylepart.Stylesheet.CellFormats.ElementAt((int)cell.StyleIndex.Value);
                        if (cf.NumberFormatId >= 14 && cf.NumberFormatId <= 22)//Date
                        {
                            value = DateTime.FromOADate(d).ToString("M/d/yyyy");
                        }
                    }
                }
                catch { }
            }
            return value;
        }
        /// <summary>
        /// 得到单元格类型
        /// </summary>
        /// <param name="cell">Cell</param>
        /// <returns></returns>
        private Type GetCellDataType(Cell cell)
        {
            if (cell.DataType == null) return typeof(string);
            if (cell.DataType == CellValues.Date)
                return typeof(DateTime);
            if (cell.DataType == CellValues.Number)
                return typeof(decimal);
            return typeof(string);
        }
        public string[] LoadExcelColumnHead(byte[] excelBytes, int headerrowindex = 1)
        {
            return LoadExcelColumnHead(excelBytes, "", headerrowindex);
        }

        public string[] LoadExcelColumnHead(byte[] excelBytes, string sheetName, int headerrowindex)
        {
            MemoryStream stream = null;
            try
            {
                stream = new MemoryStream(excelBytes);
                using (SpreadsheetDocument sdoc = SpreadsheetDocument.Open(stream, false))
                {
                    Sheet sheet = null;
                    if (string.IsNullOrEmpty(sheetName))//没有特定的sheetname的时候，取第一个sheet
                        sheet = sdoc.WorkbookPart.Workbook.Descendants<Sheet>().FirstOrDefault();
                    else//根据sheetname取特定sheet
                        sheet = sdoc.WorkbookPart.Workbook.Descendants<Sheet>().Where((s) => s.Name == sheetName).First();
                    if (sheet != null)
                    {
                        WorksheetPart wsp = (WorksheetPart)sdoc.WorkbookPart.GetPartById(sheet.Id);
                        Worksheet ws = wsp.Worksheet;
                        //取Cell值的时候使用
                        SharedStringTablePart tablePart = sdoc.WorkbookPart.SharedStringTablePart;
                        //得到第一个工作表的所有行
                        IEnumerable<Row> rows = ws.Descendants<Row>();
                        //第一行是标题，标题作为表的列名
                        Row headerRow = rows.ElementAt(headerrowindex - 1);//.First();
                        List<string> ls = new List<string>();
                        foreach (Cell hc in headerRow)
                        {
                            string columnName = "";
                            columnName = GetCellValue(hc, tablePart);
                            ls.Add(columnName);
                        }

                        return ls.ToArray();
                    }
                }
            }
            catch (Exception ex)
            {
                //解析过程中出错误了，TODO
            }
            finally
            {
                if (stream != null) stream.Close();
            }
            return null;
        }
    }
}
