using Newtonsoft.Json;
using OfficeOpenXml;
using Performance.DtoModels;
using Performance.EntityModels;
using Performance.Infrastructure;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace Performance.Services.OnlineExcel
{
    public partial class OnlineExcelService
    {
        public static Dictionary<Operation, Action<ExcelWorksheet, int, int>> OperationMapps = new Dictionary<Operation, Action<ExcelWorksheet, int, int>>
        {
            { Operation.InsertRow, (sheet,from,count) => sheet.InsertRow(from, count, from + 1) },
            { Operation.DeleteRow, (sheet,from,count) => sheet.DeleteRow(from, count) },
            { Operation.InsertColumn, (sheet,from,count) => sheet.InsertColumn(from, count, from + 1) },
            { Operation.DeleteColumn, (sheet,from,count) => sheet.DeleteColumn(from, count) },
        };
        private List<string> GetColumns()
        {
            var columns = new List<string> { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" };
            List<string> newColumns = new List<string>(columns);
            foreach (var column in columns)
            {
                foreach (var item in columns)
                {
                    newColumns.Add($"{column}{item}");
                }
            }
            return newColumns;
        }

        public void WriteSheet(per_allot allot, EpChanage chanage)
        {
            FileInfo file = new FileInfo(allot.Path);

            if (file.LastWriteTimeUtc.ToTimeStamp().ToString() != chanage.Version)
                throw new PerformanceException("您读取的文件已被其他人更改");

            using (ExcelPackage package = new ExcelPackage(file))
            {
                foreach (var sheet in package.Workbook.Worksheets)
                {
                    if (sheet.Name != chanage.SheetName) continue;
                    // 新增删除 行 列 信息
                    if (chanage.OperationRecord != null && chanage.OperationRecord.Length > 0)
                    {
                        foreach (var item in chanage.OperationRecord.Where(w => w.Count > 0).OrderBy(w => w.DateTime))
                        {
                            OperationMapps[item.Operation].Invoke(sheet, item.From, item.Count);
                        }
                    }
                    // 写入数据
                    var columns = GetColumns();
                    for (int row = 0; row < chanage.Data.Count; row++)
                    {
                        var tempData = JsonConvert.DeserializeObject<Dictionary<string, object>>(JsonConvert.SerializeObject(chanage.Data[row]));
                        foreach (var key in tempData.Keys)
                        {
                            var col = columns.IndexOf(key);
                            var cell = sheet.Cells[row + 1, col + 1];
                            if (!(cell.Value is ExcelErrorValue) && string.IsNullOrEmpty(cell.Formula))
                                cell.Value = tempData[key];
                        }
                    }

                    _cache.Remove($"SheetData-{chanage.SheetName}:{allot.Path}");
                }
                package.Save();
            }
        }
    }
}