#nullable enable
using OfficeOpenXml;
using OfficeOpenXml.Style;
using RestSharp;
using StackExchange.Profiling.Internal;
namespace Admin.NET.Core
{
    public static class ExcelUtil
    {
        /// 
        /// 在response中导出标准格式的数据
        /// 
        /// 
        /// 
        /// 
        public static void ToExcel(List headers, List> data, string sheetName, Stream newStream)
        {
            using var package = new ExcelPackage(newStream);
            var worksheet = package.Workbook.Worksheets.Add(sheetName);
            for (int j = 0; j < headers.Count; j++)
            {
                worksheet.Cells[1, j + 1].Value = headers[j];
                worksheet.Cells[1, j + 1].Style.Font.Bold = true;//加粗
                worksheet.Cells[1, j + 1].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;//水平居中 
                worksheet.Cells[1, j + 1].Style.VerticalAlignment = ExcelVerticalAlignment.Center;//垂直居中 
                worksheet.Cells[1, j + 1].Style.Border.Bottom.Style = ExcelBorderStyle.Thin;//边框常规粗细
                worksheet.Cells[1, j + 1].Style.Border.Left.Style = ExcelBorderStyle.Thin;//边框常规粗细
                worksheet.Cells[1, j + 1].Style.Border.Right.Style = ExcelBorderStyle.Thin;//边框常规粗细
                worksheet.Cells[1, j + 1].Style.Border.Top.Style = ExcelBorderStyle.Thin;//边框常规粗细
            }
            for (int i = 0; i < data.Count; i++)
            {
                for (int j = 0; j < data[i].Count; j++)
                {
                    worksheet.Cells[2 + i, j + 1].Value = data[i][j];
                }
            }
            package.Save();
        }
        /// 
        /// 在response中导出标准格式的多表数据
        /// 
        /// 
        /// 
        /// 
        /// 
        public static void ToExcel(List> headersList, List>> dataList, List sheetNameList, Stream newStream)
        {
            using var package = new ExcelPackage(newStream);
            for (var k = 0; k < sheetNameList.Count; k++)
            {
                var worksheet = package.Workbook.Worksheets.Add(sheetNameList[k]);
                for (int j = 0; j < headersList[k].Count; j++)
                {
                    worksheet.Cells[1, j + 1].Value = headersList[k][j];
                    worksheet.Cells[1, j + 1].Style.Font.Bold = true;//加粗
                    worksheet.Cells[1, j + 1].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;//水平居中 
                    worksheet.Cells[1, j + 1].Style.VerticalAlignment = ExcelVerticalAlignment.Center;//垂直居中 
                    worksheet.Cells[1, j + 1].Style.Border.Bottom.Style = ExcelBorderStyle.Thin;//边框常规粗细
                    worksheet.Cells[1, j + 1].Style.Border.Left.Style = ExcelBorderStyle.Thin;//边框常规粗细
                    worksheet.Cells[1, j + 1].Style.Border.Right.Style = ExcelBorderStyle.Thin;//边框常规粗细
                    worksheet.Cells[1, j + 1].Style.Border.Top.Style = ExcelBorderStyle.Thin;//边框常规粗细
                }
                for (int i = 0; i < dataList[k].Count; i++)
                {
                    for (int j = 0; j < dataList[k][i].Count; j++)
                    {
                        worksheet.Cells[2 + i, j + 1].Value = dataList[k][i][j];
                    }
                }
            }
            package.Save();
        }
        /// 
        /// 在response中根据模板导出单表数据
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        public static void ToExcel(string templatePath, List headers, List> data, string sheetName, int headStartLine, int dataStartLine, Stream newStream)
        {
            var options = new RestClientOptions(App.Configuration["FileUrl"])
            {
                ThrowOnAnyError = true,
                //MaxTimeout = 2000
            };
            var client = new RestClient(options);
            var request = new RestRequest($"/file/download", Method.Get);
            request?.AddParameter(Parameter.CreateParameter("path", templatePath, ParameterType.QueryString))
                ?.AddParameter(Parameter.CreateParameter("fileName", "template.xlsx", ParameterType.QueryString));
            var response = client.DownloadData(request ?? null!);
            MemoryStream ms = new(response ?? null!);
            using var package = new ExcelPackage(newStream, ms);
            var worksheet = package.Workbook.Worksheets[0];
            worksheet.Name = sheetName;
            for (int j = 0; j < headers.Count; j++)
            {
                worksheet.Cells[headStartLine, j + 1].Value = headers[j];
            }
            for (int i = 0; i < data.Count; i++)
            {
                for (int j = 0; j < data[i].Count; j++)
                {
                    worksheet.Cells[dataStartLine + i, j + 1].Value = data[i][j];
                }
            }
            package.Save();
        }
        /// 
        /// 在response中根据模板导出多表数据
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        public static void ToExcel(string templatePath, List> headersList, List>> dataList, List sheetNameList, List headStartLineList, List dataStartLineList, Stream newStream)
        {
            var options = new RestClientOptions(App.Configuration["FileUrl"])
            {
                ThrowOnAnyError = true,
            };
            var client = new RestClient(options);
            var request = new RestRequest($"/file/download", Method.Get);
            request?.AddParameter(Parameter.CreateParameter("path", templatePath, ParameterType.QueryString))
                ?.AddParameter(Parameter.CreateParameter("fileName", "template.xlsx", ParameterType.QueryString));
            var response = client.DownloadData(request ?? null!);
            MemoryStream ms = new(response ?? null!);
            using var package = new ExcelPackage(newStream, ms);
            for (var k = 0; k < sheetNameList.Count; k++)
            {
                var worksheet = package.Workbook.Worksheets.FirstOrDefault(x => x.Name == sheetNameList[k]) ?? null!;
                for (int j = 0; j < headersList[k].Count; j++)
                {
                    worksheet.Cells[headStartLineList[k], j + 1].Value = headersList[k][j];
                }
                for (int i = 0; i < dataList[k].Count; i++)
                {
                    for (int j = 0; j < dataList[k][i].Count; j++)
                    {
                        worksheet.Cells[dataStartLineList[k] + i, j + 1].Value = dataList[k][i][j];
                    }
                }
            }
            package.Save();
        }
        /// 
        /// 导入标准格式的数据文件
        /// 
        /// 上传的文件
        /// 
        public static void FromExcel(IFormFile file, int headStartLine, int dataStartLine, out List headers, out List> data, out string sheetName)
        {
            if (file == null) throw Oops.Oh(ErrorCodeEnum.D8000);
            //暂时注释,以后再放开 【Editby shaocx,2024-04-15】
            /*
            string key = "UploadFile:Excel";
            var allowContentTypes = App.Configuration.GetSection($"{key}:contentType").Get>();
            if (!allowContentTypes.Contains(file.ContentType)) throw Oops.Oh(ErrorCode.D8001);
            //*/
            sheetName = "";
            headers = new();
            data = new();
            using var package = new ExcelPackage(file.OpenReadStream());
            var worksheet = package.Workbook.Worksheets.Count > 0 ? package.Workbook.Worksheets[0] : null;
            sheetName = package.Workbook.Worksheets.Count > 0 ? package.Workbook.Worksheets[0].Name : "";
            var cellsCount = worksheet?.Cells?.Count() ?? 0;
            int col = 1;
            string? header = worksheet?.Cells[headStartLine, col++].Value?.ToString();
            while (!string.IsNullOrWhiteSpace(header))
            {
                headers.Add(header);
                header = worksheet?.Cells[headStartLine, col++]?.Value?.ToString();
            }
            var headersCount = headers.Count;
            if (headersCount == 0) throw Oops.Oh("表头数量不能为0");
            var rowsCount = (int)Math.Ceiling(((double)cellsCount) / headersCount) - dataStartLine + 1;
            for (var i = 0; i < rowsCount; i++)
            {
                List