using IRaCIS.Application.Interfaces;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using MiniExcelLibs;
using MiniExcelLibs.OpenXml;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NPOI.HSSF.UserModel;

namespace IRaCIS.Core.Application.Service;

public static class ExcelExportHelper
{
    //MiniExcel_Export
    public static async Task<IActionResult> DataExportAsync(string code, object data, string exportFileNamePrefix, IRepository<CommonDocument> _commonDocumentRepository, IWebHostEnvironment _hostEnvironment, IDictionaryService? _dictionaryService = null, Type? translateType = null, CriterionType? criterionType = null)
    {

        //判断是否有字典翻译

        if (_dictionaryService != null && translateType != null)
        {

            ////只标注单个的时候
            //var needTranslatePropertyList = translateType.GetProperties().Where(t => t.IsDefined(typeof(DictionaryTranslateAttribute), true))
            //    .Select(c => new { c.Name, DicParentCode = ((DictionaryTranslateAttribute?)c.GetCustomAttributes(typeof(DictionaryTranslateAttribute), false)[0])?.DicParentCode }).ToList();


            //一个值 对应不同的字典翻译
            var needTranslatePropertyList = translateType.GetProperties().Where(t => t.IsDefined(typeof(DictionaryTranslateAttribute), true))
                .SelectMany(c =>
                c.GetCustomAttributes(typeof(DictionaryTranslateAttribute), false).Select(f => (DictionaryTranslateAttribute?)f).Where(t => t.CriterionType == criterionType || t.CriterionType == null).Select(k => new { c.Name, k.DicParentCode })
                ).ToList();



            //字典表查询出所有需要翻译的数据

            var translateDataList = await _dictionaryService.GetBasicDataSelect(needTranslatePropertyList.Select(t => t.DicParentCode).Distinct().ToArray());


            var dic = JsonConvert.DeserializeObject<IDictionary<string, object>>(data.ToJsonNotIgnoreNull());

            foreach (var key in dic.Keys)
            {
                //是数组 那么找到对应的属性 进行翻译
                if (dic[key].GetType().IsAssignableFrom(typeof(JArray)))
                {

                    var newObjList = new List<object>();
                    var no = 1;

                    foreach (var item in dic[key] as JArray)
                    {
                        var itemDic = JsonConvert.DeserializeObject<IDictionary<string, object>>(item.ToJsonNotIgnoreNull());


                        foreach (var needTranslateProperty in needTranslatePropertyList)
                        {
                            var beforeValue = itemDic[needTranslateProperty.Name]?.ToString();


                            itemDic[needTranslateProperty.Name] = translateDataList[needTranslateProperty.DicParentCode].Where(t => t.Code.ToLower() == beforeValue?.ToLower()).FirstOrDefault()?.ValueCN ?? String.Empty;


                        }

                        itemDic.Add("No", no++);
                        newObjList.Add(itemDic);
                    }

                    dic[key] = newObjList;

                }
            }


            data = dic;


        }





        var (physicalPath, fileNmae) = await FileStoreHelper.GetCommonDocPhysicalFilePathAsync(_hostEnvironment, _commonDocumentRepository, code);


        //模板路径
        var tplPath = physicalPath;

        #region MiniExcel

        var memoryStream = new MemoryStream();

        var config = new OpenXmlConfiguration()
        {
            IgnoreTemplateParameterMissing = true,
        };

        await MiniExcel.SaveAsByTemplateAsync(memoryStream, tplPath, data, config);

        memoryStream.Seek(0, SeekOrigin.Begin);

        return new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
        {
            FileDownloadName = $"{exportFileNamePrefix}_{fileNmae.Substring(0, fileNmae.LastIndexOf('.'))}_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx"
        };

        #endregion

        #region Magicodes  模板规则不一样

        ////创建Excel导出对象
        //IExportFileByTemplate exporter = new ExcelExporter();

        ////根据模板导出
        //var result = await exporter.ExportBytesByTemplate(exportInfo, tplPath);


        //return new XlsxFileResult(bytes: result, fileDownloadName: $"{doc.Name}_{DateTime.Now.ToString("yyyy-MM-dd:hh:mm:ss")}.xlsx");
        #endregion

    }



    public static async Task<MemoryStream> DataExport_NpoiTestAsync(string code, object data, IRepository<CommonDocument> _commonDocumentRepository, IWebHostEnvironment _hostEnvironment, IDictionaryService? _dictionaryService = null, Type? translateType = null, CriterionType? criterionType = null)
    {
        //判断是否有字典翻译

        if (_dictionaryService != null && translateType != null)
        {
            //一个值 对应不同的字典翻译
            var needTranslatePropertyList = translateType.GetProperties().Where(t => t.IsDefined(typeof(DictionaryTranslateAttribute), true))
                .SelectMany(c =>
                c.GetCustomAttributes(typeof(DictionaryTranslateAttribute), false).Select(f => (DictionaryTranslateAttribute?)f).Where(t => t.CriterionType == criterionType || t.CriterionType == null).Select(k => new { c.Name, k.DicParentCode })
                ).ToList();

            //字典表查询出所有需要翻译的数据

            var translateDataList = await _dictionaryService.GetBasicDataSelect(needTranslatePropertyList.Select(t => t.DicParentCode).Distinct().ToArray());

            var dic = JsonConvert.DeserializeObject<IDictionary<string, object>>(data.ToJsonNotIgnoreNull());

            foreach (var key in dic.Keys)
            {
                //是数组 那么找到对应的属性 进行翻译
                if (dic[key].GetType().IsAssignableFrom(typeof(JArray)))
                {

                    var newObjList = new List<object>();
                    var no = 1;

                    foreach (var item in dic[key] as JArray)
                    {
                        var itemDic = JsonConvert.DeserializeObject<IDictionary<string, object>>(item.ToJsonNotIgnoreNull());

                        foreach (var needTranslateProperty in needTranslatePropertyList)
                        {
                            var beforeValue = itemDic[needTranslateProperty.Name]?.ToString();

                            itemDic[needTranslateProperty.Name] = translateDataList[needTranslateProperty.DicParentCode].Where(t => t.Code.ToLower() == beforeValue?.ToLower()).FirstOrDefault()?.ValueCN ?? String.Empty;
                        }

                        itemDic.Add("No", no++);
                        newObjList.Add(itemDic);
                    }

                    dic[key] = newObjList;

                }
            }


            data = dic;


        }





        var (physicalPath, fileNmae) = await FileStoreHelper.GetCommonDocPhysicalFilePathAsync(_hostEnvironment, _commonDocumentRepository, code);


        //模板路径
        var tplPath = physicalPath;

        #region MiniExcel

        var memoryStream = new MemoryStream();

        var config = new OpenXmlConfiguration()
        {
            IgnoreTemplateParameterMissing = true,
        };

        await MiniExcel.SaveAsByTemplateAsync(memoryStream, tplPath, data, config);

        memoryStream.Seek(0, SeekOrigin.Begin);


        return memoryStream;

       //var wb = new HSSFWorkbook(memoryStream);

        //var  sheet = wb.GetSheetAt(0);


        #endregion
    }

}