using System;
using System.Collections.Generic;
using System.Formats.Asn1;
using System.Linq;
using System.Threading.Tasks;
using Furion;
using Furion.DependencyInjection;
using Furion.JsonSerialization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Waste.Application;
using Waste.Domain;
using static Google.Protobuf.WellKnownTypes.Field.Types;

namespace Waste.Web.Entry.Pages.Result
{
    public class ResultColumnConfigService : ITransient
    {
        public const string AccountSettingDefinitionName = "AccountResultColumnConfig";
        public const string GlobalSettingDefinitionName = "GlobalResultColumnConfig";
        private readonly ILogger<ResultColumnConfigService> logger;
        private readonly SettingProvider settingProvider;
        private readonly UserSettingValueProvider userSettingValueProvider;
        private readonly GlobalSettingValueProvider globalSettingValueProvider;

        public static readonly Dictionary<string, string> SystemColumn = new Dictionary<string, string>()
        {
            {nameof(ResultList.DeviceFacEcode).ToLower(),"设备编号"},
            {nameof(ResultList.DeviceEcode).ToLower(),"机器码"},
            {nameof(ResultList.DeviceName).ToLower(),"设备名称"},
            {nameof(ResultList.BusinessName).ToLower(),"所属商户"},
            {nameof(ResultList.PostStatus).ToLower(),"状态"},
            {nameof(ResultList.CreateTime).ToLower(),"回收时间"},
            {nameof(ResultList.WasteType).ToLower(),"物品编码"},
            {nameof(ResultList.Registration).ToLower(),"垃圾桶"},
            {nameof(ResultList.GrossWeight).ToLower(),"毛重(KG)"},
            {nameof(ResultList.Tare).ToLower(),"皮重(KG)"},
            {nameof(ResultList.NetWeight).ToLower(),"净重(KG)"},
            {nameof(ResultList.DeviceAddress).ToLower(),"地址"},
            {nameof(ResultList.Measure_Price).ToLower(),"单价"},
            {nameof(ResultList.Measure_Amount).ToLower(),"金额"},
            {nameof(ResultList.Measure_OpUser).ToLower(),"操作员"},
            {nameof(ResultList.Measure_UUID).ToLower(),"消息ID"},
            {nameof(ResultList.Measure_WasteSType).ToLower(),"物品小类"},

            {nameof(ResultList.ID1).ToLower(),"ID1"},
            {nameof(ResultList.ID2).ToLower(),"ID2"},
            {nameof(ResultList.ID3).ToLower(),"ID3"},
            {nameof(ResultList.ID4).ToLower(),"ID4"},
            {nameof(ResultList.ID5).ToLower(),"ID5"},
            {nameof(ResultList.ID6).ToLower(),"ID6"},
            {nameof(ResultList.ID7).ToLower(),"ID7"},
            {nameof(ResultList.ID8).ToLower(),"ID8"},

        };

        public ResultColumnConfigService(ILogger<ResultColumnConfigService> logger, SettingProvider settingProvider, UserSettingValueProvider userSettingValueProvider, GlobalSettingValueProvider globalSettingValueProvider)
        {
            this.logger = logger;
            this.settingProvider = settingProvider;
            this.userSettingValueProvider = userSettingValueProvider;
            this.globalSettingValueProvider = globalSettingValueProvider;
        }

        private Task<Dictionary<string, string>> GetDefaultColumn()
        {
            return Task.FromResult(SystemColumn);
        }
        public async Task<Dictionary<string, string>> GetAccountDefaultColumn()
        {
            return (await GetGlobalColumn()).Where(x => x.IsShow).ToDictionary(x => x.Name, x => x.Title);
        }
        public async Task<List<GlobalColumnConfig>> GetGlobalColumn()
        {
            var def = await GetDefaultColumn();
            var value = await settingProvider.GetOrNullAsync(GlobalSettingDefinitionName);
            if (string.IsNullOrWhiteSpace(value)) return DefaultList();

            try
            {
                var config = JSON.Deserialize<GlobalConfig>(value);
                if (config.ResultColumn != null && config.ResultColumn.Any())
                {
                    #region 以系统顺序为准
                    var dic = config.ResultColumn.GroupBy(x => x.Name).ToDictionary(x => x.Key, x => x.First());
                    return def
                        .Select(x =>
                        {
                            if (dic.TryGetValue(x.Key, out var find))
                            {
                                return new GlobalColumnConfig
                                { Name = x.Key, Title = find.Title, IsShow = find.IsShow };
                            }
                            return new GlobalColumnConfig { Name = x.Key, Title = string.Empty, IsShow = false };
                        }).ToList();

                    #endregion


                    #region 自定义顺序

                    /*                    return config.ResultColumn.GroupBy(x => x.Name)
                        .Where(x => def.ContainsKey(x.Key))
                        .Select(x =>
                            new GlobalColumnConfig { Name = x.Key, Title = x.First().Title, IsShow = x.First().IsShow }).ToList();                 
*/
                    #endregion


                }
            }
            catch (Exception e)
            {
                logger.LogError(e, "反序列化失败:{value}", value);

            }
            return DefaultList();

            List<GlobalColumnConfig> DefaultList()
            {
                return def.Select(x =>
                    new GlobalColumnConfig { Name = x.Key, Title = x.Value, IsShow = true }).ToList();
            }
        }


        public async Task<Dictionary<string, string>> GetAccountColumn()
        {
            var _GlobalColumn = (await GetGlobalColumn()).Where(x => SystemColumn.ContainsKey(x.Name) && x.IsShow).ToDictionary(x => x.Name, x => string.IsNullOrWhiteSpace(x.Title) ? SystemColumn[x.Name] : x.Title);
            var value = await settingProvider.GetOrNullAsync(AccountSettingDefinitionName);
            if (string.IsNullOrWhiteSpace(value)) return _GlobalColumn;

            try
            {
                var config = JSON.Deserialize<AccountConfig>(value);
                if (config.ResultColumn != null && config.ResultColumn.Any())
                {
                    return config.ResultColumn.GroupBy(x => x.Name)
                        .Where(x => _GlobalColumn.ContainsKey(x.Key))
                        .ToDictionary(x => x.Key,
                            //x => x.First().Title
                            x => _GlobalColumn[x.Key]
                        );
                }
            }
            catch (Exception e)
            {
                logger.LogError(e, "反序列化失败:{value}", value);
            }

            return _GlobalColumn;


        }

        public async Task WriteAccountConfig(List<ColumnConfig> ResultColumn)
        {
            var value = SerializeConfig(ResultColumn, SystemColumn);
            await userSettingValueProvider.SetAsync(AccountSettingDefinitionName, value);
        }

        public static string SerializeConfig(List<ColumnConfig> ResultColumn, Dictionary<string, string> DefaultColumn)
        {
            if (ResultColumn != null && ResultColumn.Any())
            {
                return JSON.Serialize(new AccountConfig
                { ResultColumn = ResultColumn.GroupBy(x => x.Name).Where(x => DefaultColumn.ContainsKey(x.Key) && x.Any()).Select(x => new ColumnConfig { Name = x.Key/*, Title = x.First().Title*/ }).ToList() });
            }

            return null;
        }

        public async Task WriteGlobalConfig(List<GlobalColumnConfig> ResultColumn)
        {
            var value = SerializeConfig(ResultColumn, SystemColumn);
            await globalSettingValueProvider.SetAsync(GlobalSettingDefinitionName, value);
        }

        public static string SerializeConfig(List<GlobalColumnConfig> ResultColumn, Dictionary<string, string> DefaultColumn)
        {
            if (ResultColumn != null && ResultColumn.Any())
            {
                return JSON.Serialize(new GlobalConfig
                { ResultColumn = ResultColumn.Where(x => DefaultColumn.ContainsKey(x.Name)).ToList() });
            }

            return null;
        }
    }

    public sealed class ResultColumnConfigStartup : AppStartup
    {
        public void ConfigureServices(IServiceCollection services)
        {

        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.ApplicationServices.GetRequiredService<SettingDefinitionManager>()
                .AddSettingDefinition(new SettingDefinition()
                {
                    Name = ResultColumnConfigService.GlobalSettingDefinitionName,
                    Providers = { GlobalSettingValueProvider.ProviderName }
                })
                .AddSettingDefinition(new SettingDefinition()
                {
                    Name = ResultColumnConfigService.AccountSettingDefinitionName,
                    Providers = { UserSettingValueProvider.ProviderName }
                });
        }
    }

    public class AccountConfig
    {
        public List<ColumnConfig> ResultColumn { get; set; }
    }
    public class GlobalConfig
    {
        public List<GlobalColumnConfig> ResultColumn { get; set; }
    }

    public class ColumnConfig
    {
        public string Name { get; set; }
    }

    public class GlobalColumnConfig : ColumnConfig
    {
        //public string SystemTitle { get; set; }
        public string Title { get; set; }
        public bool IsShow { get; set; }
    }


}