using Hotline.Caching.Interfaces;
using Hotline.SeedData;
using Hotline.Settings;
using Hotline.Share.Dtos.Settings;
using Hotline.Share.Tools;
using Mapster;
using XF.Domain.Cache;
using XF.Domain.Dependency;
using XF.Domain.Repository;

namespace Hotline.Caching.Services
{
    public class SysDicDataCacheManager : ISystemDicDataCacheManager, IScopeDependency
    {
        private readonly IRepository<SystemDicData> _sysDicDataRepository;
        private readonly IRepository<SystemDicType> _systemDicTypeRepository;
        private readonly ITypedCache<IReadOnlyList<SystemDicData>> _cacheSysDicData;

        public SysDicDataCacheManager(IRepository<SystemDicData> sysDicDataRepository, ITypedCache<IReadOnlyList<SystemDicData>> cacheSysDicData, IRepository<SystemDicType> systemDicTypeRepository)
        {
            _sysDicDataRepository = sysDicDataRepository;
            _cacheSysDicData = cacheSysDicData;
            _systemDicTypeRepository = systemDicTypeRepository;
        }


        public IReadOnlyList<SystemDicData> GetSysDicDataCache(string code)
        {
            var sysDicDataList = _cacheSysDicData.GetOrSet(code, k =>
            {
                return _sysDicDataRepository.Queryable().Where(x => x.DicTypeCode == code && x.IsShow == true).OrderBy(x => x.Sort).ToTreeAsync(x => x.Children, it => it.ParentId, "").GetAwaiter().GetResult();
            });
            return sysDicDataList;
        }

        public IReadOnlyList<SystemDicDataOutDto> GetOrAdd(string code)
        {
            return GetOrAddDic(code).Adapt<IReadOnlyList<SystemDicDataOutDto>>();
        }

        public IReadOnlyList<SystemDicData> GetOrAddDic(string code)
        {
            var items = GetSysDicDataCache(code);
            if (items.NotNullOrEmpty()) return items;

            var any = _sysDicDataRepository.Queryable().Where(m => m.DicTypeCode == code).Any();
            if (any) return [];

            var sysDicType = _systemDicTypeRepository.Get(x => x.DicTypeCode == code);
            var seedData = new SystemDicDataSeedData();
            if (sysDicType == null)
            {
                sysDicType = seedData.GetType(code);
                sysDicType.Id = _systemDicTypeRepository.AddAsync(sysDicType).GetAwaiter().GetResult();
            }
            var sysDicDatas = seedData.GetData(code);
            AssignChilderDicType(sysDicDatas.ToList(), code, sysDicType.Id);

            RemoveSysDicDataCache(code);
            return GetSysDicDataCache(code);
        }

        private void AssignChilderDicType(IList<SystemDicData> sysDicDatas, string code, string dicTypeId, string parentId = "")
        {
            foreach (var item in sysDicDatas)
            {
                item.DicTypeCode = code;
                item.DicTypeId = dicTypeId;
                item.ParentId = parentId;
                item.IsShow = true;
                _sysDicDataRepository.AddAsync(item).GetAwaiter().GetResult();
                if (item.Children.NotNullOrEmpty()) AssignChilderDicType(item.Children, code, dicTypeId, item.Id);
            }
        }

        public IReadOnlyList<SystemDicData> GetVisitSatisfaction()
            => GetSysDicDataCache(SysDicTypeConsts.VisitSatisfaction);

        public IReadOnlyList<SystemDicData> AcceptType => GetSysDicDataCache(SysDicTypeConsts.AcceptType);

        public IReadOnlyList<SystemDicData> LeaderSMS => GetSysDicDataCache(SysDicTypeConsts.LeaderSMS);

        public IReadOnlyList<SystemDicData> CallForwardingSource => GetSysDicDataCache(SysDicTypeConsts.CallForwardingSource);

        /// <summary>
        /// 工作场所
        /// </summary>
        public IReadOnlyList<SystemDicDataOutDto> Workplace => GetOrAdd(SysDicTypeConsts.Workplace);

        /// <summary>
        /// 作业区域
        /// </summary>
        public IReadOnlyList<SystemDicDataOutDto> WorkplaceName => GetOrAdd(SysDicTypeConsts.WorkplaceName);

        /// <summary>
        /// 作业类型
        /// </summary>
        public IReadOnlyList<SystemDicDataOutDto> JobType => GetOrAdd(SysDicTypeConsts.JobType);

        /// <summary>
        /// 经营单位类别
        /// </summary>
        public IReadOnlyList<SystemDicDataOutDto> BusinessUnitType => GetOrAdd(SysDicTypeConsts.BusinessUnitType);

        public IReadOnlyList<SystemDicData> BulletinType => GetSysDicDataCache(SysDicTypeConsts.AcceptType);

        /// <summary>
        /// 随手拍公告类型
        /// </summary>
        public IReadOnlyList<SystemDicDataOutDto> SnapshotBulletinType => GetOrAdd(SysDicTypeConsts.SnapshotBulletinType);
        public SystemDicDataOutDto GetSnapshotBulletinType(string dicDataValue)
            => this.SnapshotBulletinType.FirstOrDefault(x => x.DicDataValue == dicDataValue) ?? new SystemDicDataOutDto();


        /// <summary>
        /// 作业区域
        /// </summary>
        public IReadOnlyList<SystemDicDataOutDto> WorkArea => GetOrAdd(SysDicTypeConsts.WorkArea);

        public IReadOnlyList<SystemDicData> VisitMananer => GetSysDicDataCache(SysDicTypeConsts.VisitManner);
        public IReadOnlyList<SystemDicData> SourceChannel => GetSysDicDataCache(SysDicTypeConsts.SourceChannel);

        /// <summary>
        /// 随手拍公告来源
        /// </summary>
        public IReadOnlyCollection<SystemDicDataOutDto> SnapshotBulletinSource => GetOrAdd(SysDicTypeConsts.SnapshotBulletinSource);

        /// <summary>
        /// 红包补充发放类型
        /// </summary>
        public IReadOnlyCollection<SystemDicDataOutDto> SnapshotReplenishType => GetOrAdd(SysDicTypeConsts.SnapshotReplenishType);

        /// <summary>
        /// 随手拍工单标签
        /// </summary>
        public IReadOnlyCollection<SystemDicDataOutDto> SnapshotOrderLabel => GetOrAdd(SysDicTypeConsts.SnapshotOrderLabel);

        /// <summary>
        /// 工单标签
        /// </summary>
        public IReadOnlyCollection<SystemDicDataOutDto> OrderTag => GetOrAdd(SysDicTypeConsts.OrderTag);

        /// <summary>
        /// 回访满意度
        /// </summary>
        public IReadOnlyCollection<SystemDicDataOutDto> VisitSatisfaction => GetOrAdd(SysDicTypeConsts.VisitSatisfaction);

        /// <summary>
        /// 随手拍特殊红包审核类型
        /// </summary>
        public IReadOnlyCollection<SystemDicDataOutDto> SnapshotRedPackSpecialType => GetOrAdd(SysDicTypeConsts.SnapshotRedPackSpecialType);

        /// <summary>
        /// 额外扣除积分类型
        /// </summary>
        public IReadOnlyCollection<SystemDicDataOutDto> ExtraDeductionPointsType => GetOrAdd(SysDicTypeConsts.ExtraDeductionPointsType);

        /// <summary>
        /// 兴唐动作状态映射
        /// </summary>
        public IReadOnlyCollection<SystemDicDataOutDto> XingTangOperationMap => GetOrAdd(SysDicTypeConsts.XingTangOperationMap);

        public IReadOnlyList<SystemDicData> InstaShotSpecialReason => GetOrAddDic(SysDicTypeConsts.InstaShotSpecialReason);

        /// <summary>
        /// 随手拍安全员类型
        /// </summary>
        public IReadOnlyList<SystemDicData> SafetyType => GetOrAddDic(SysDicTypeConsts.SafetyType);

        public void RemoveSysDicDataCache(string code)
        {
            _cacheSysDicData.Remove(code);
        }

        /// <summary>
        /// 获取用户头像图片
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public string HeaderImages(string value)
        {
            var dto = GetOrAdd(SysDicTypeConsts.HeaderImages).Where(m => m.DicDataValue == value).FirstOrDefault() ?? new SystemDicDataOutDto();
            if (dto.DicDataName == "LocalHeadImageDefault")
            {
                return SystemDicDataSeedData.LocalHeadImageDefault;
            }
            if (dto.DicDataName == "LocalHeadImageAQWS")
            {
                return SystemDicDataSeedData.LocalHeadImageAQWS;
            }
            return dto.DicDataName;
        }
    }
}
