using Performance.EntityModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Performance.DtoModels
{
    public class HandsonTableBase
    {
        public HandsonTableBase()
        {
            ColHeaders = new List<string>();
            Columns = new List<HandsonColumn>();
            Data = new List<Dictionary<string, object>>();
            NestedHeadersArray = new object[] { };
        }

        public List<string> ColHeaders { get; set; }
        public List<Dictionary<string, object>> Data { get; set; }
        public List<HandsonColumn> Columns { get; set; }
        public object[] NestedHeadersArray { get; set; }
    }

    public class HandsonTable : HandsonTableBase
    {
        private IEnumerable<collect_permission> _permissions;

        public bool ReadOnly { get; set; } = false;

        public HandsonTable(int sheetType, string[] cols, List<collect_permission> permissions)
            : base()
        {
            _permissions = permissions;

            InitColHeaders(sheetType, cols);
            InitColumns(permissions);
        }

        public void SetRowData(IEnumerable<HandsonRowData> datas, bool isTypein)
        {
            foreach (var dt in datas)
            {
                var dic = CreateDataRow("编号", dt.Row.ToString());
                foreach (var item in dt.CellData)
                {
                    //if (dic.ContainsKey(item.Name.ToLower()) && isTypein && _permissions.Any(w => w.HeadName.ToLower() == item.Name.ToLower()))
                    //    dic[item.Name.ToLower()] = item.Value?.ToString() ?? "";
                    //else if (dic.ContainsKey(item.Name.ToLower()) && _permissions.Any(w => w.HeadName.ToLower() == item.Name.ToLower() && w.AttachLast > 0))
                    //    dic[item.Name.ToLower()] = item.Value?.ToString() ?? "";
                    //else if (dic.ContainsKey(item.Name.ToLower()) && _permissions.Any(w => w.HeadName.ToLower() == item.Name.ToLower()))
                    dic[item.Name.ToLower()] = item.Value?.ToString() ?? "";
                }
                Data.Add(dic);
            }
        }

        private void InitColHeaders(int sheetType, string[] cols)
        {
            var defaluts = new DefalutHandsonHeader[]
              {
                new DefalutHandsonHeader{ SheetType = SheetType.OtherIncome, Necessity = new[] { "核算单元（医技组）","核算单元（医生组）","核算单元（护理组）","科室名称" } },
                new DefalutHandsonHeader{ SheetType = SheetType.Expend, Necessity = new[] { "核算单元（医技组）","核算单元（医生组）","核算单元（护理组）","科室名称" } },
                new DefalutHandsonHeader{ SheetType = SheetType.Workload, Necessity = new[] { "核算单元","科室名称" } },
                new DefalutHandsonHeader{ SheetType = SheetType.SpecialUnit, Necessity = new[] { "科室名称" } },
                //new DefalutHandsonHeader{ SheetType = SheetType.AccountExtra, Necessity = new[] { "核算单元","科室名称" } },
                //new DefalutHandsonHeader{ SheetType = SheetType.PersonExtra, Necessity = new[] { "核算单元","科室名称" } },
              };
            var necessitys = defaluts.FirstOrDefault(w => sheetType == (int)w.SheetType)?.Necessity.ToList();
            necessitys = necessitys ?? new List<string>();

            foreach (var col in cols)
            {
                var item = col.ToLower();
                if (!necessitys.Contains(item))
                    necessitys.Add(item);
                if (!_permissions.Any(w => w.HeadName.ToLower() == item && w.Visible == 1))
                    necessitys.Remove(item);
            }
            ColHeaders = necessitys;
        }

        private void InitColumns(List<collect_permission> permissions)
        {
            var defaults = new List<string> { "核算单元（医技组）", "核算单元（医生组）", "核算单元（护理组）", "核算单元", "科室名称" };

            List<HandsonColumn> columns = new List<HandsonColumn>();
            foreach (var col in ColHeaders)
            {
                var item = col.ToLower();
                var readnoly = _permissions.FirstOrDefault(f => f.HeadName == item)?.Readnoly == 1;

                DataFormat format = defaults.Contains(col) ? DataFormat.普通格式 : DataFormat.小数;
                columns.Add(new HandsonColumn(item.ToLower(), readnoly, format));
            }
            Columns = columns;
        }

        private Dictionary<string, object> CreateDataRow(string key, string value)
        {
            var temp = new Dictionary<string, object>() { { key, value } };
            foreach (var item in ColHeaders)
            {
                if (!temp.ContainsKey(item))
                    temp.Add(item.ToLower(), "");
            }
            return temp;
        }
    }

    public class HandsonColumn
    {
        public HandsonColumn(string data, bool readOnly = false, DataFormat format = DataFormat.普通格式)
        {
            Data = data;
            ReadOnly = readOnly;

            switch (format)
            {
                case DataFormat.普通格式:
                    Type = "text";
                    break;

                case DataFormat.日期YYYYMMDD:
                    Type = "DateFormat";
                    DateFormat = "YYYY/MM/DD";
                    break;

                case DataFormat.小数:
                    Type = "numeric";
                    NumericFormat = new NumericFormat { Pattern = "0,00.00" };
                    break;

                case DataFormat.小数1:
                    Type = "numeric";
                    NumericFormat = new NumericFormat { Pattern = "0,00.0" };
                    break;

                case DataFormat.整数:
                    Type = "numeric";
                    NumericFormat = new NumericFormat { Pattern = "0,00" };
                    break;

                case DataFormat.百分比:
                    Type = "numeric";
                    NumericFormat = new NumericFormat { Pattern = "0,00.00%" };
                    break;
            }
        }

        public string Data { get; set; }
        public bool ReadOnly { get; set; }
        public string Type { get; set; }
        public string DateFormat { get; set; }
        public string[] Source { get; set; }

        public bool Strict { get; set; } = false;
        public NumericFormat NumericFormat { get; set; }
    }

    public class NumericFormat
    {
        public string Pattern { get; set; }
    }

    public class DefalutHandsonHeader
    {
        public SheetType SheetType { get; set; }
        public string[] Necessity { get; set; }
    }

    public class HandsonRowData
    {
        public HandsonRowData(int row, IEnumerable<HandsonCellData> cellData)
        {
            Row = row;
            CellData = cellData;
        }

        public int Row { get; set; }
        public IEnumerable<HandsonCellData> CellData { get; set; }
    }

    public class HandsonCellData
    {
        public HandsonCellData(string name, object value)
        {
            Name = name;
            Value = value;
        }

        public string Name { get; set; }
        public object Value { get; set; }
    }

    public class NestedHeader
    {
        public NestedHeader(string label, int colspan)
        {
            Label = label;
            Colspan = colspan;
        }

        public string Label { get; set; }

        public int Colspan { get; set; }
    }
}
