using EasyCaching.Core;
using IRaCIS.Core.Domain.Share;
using Microsoft.EntityFrameworkCore.SqlServer.Query.Internal;
using Microsoft.Extensions.Logging;
using System.IO.Compression;

namespace IRaCIS.Application.Services.BackGroundJob
{

    public interface IIRaCISCacheHangfireJob
    {

        Task ProjectStartCache();
        Task MemoryCacheTrialStatus();

        Task MemoryCacheAnonymizeData();

        Task CacheUserTypePermission(Guid? cacheUserTypeId);


        Task CreateImageZipTask(string folderPath, string zipPath, string relativePath, Guid visitTaskId);
    }
    public class IRaCISCacheHangfireJob: IIRaCISCacheHangfireJob
    {
        private readonly IRepository<Trial> _trialRepository;
        private readonly IRepository<VisitTask> _VisitTaskRepository;
        private readonly IEasyCachingProvider _provider;
        private readonly ILogger<IRaCISCacheHangfireJob> _logger;
        private readonly IRepository<SystemAnonymization> _systemAnonymizationRepository;

        private readonly IRepository<UserTypeMenu> _userTypeMenuRepository;

        public IRaCISCacheHangfireJob(IRepository<Trial> trialRepository,
            IRepository<SystemAnonymization> systemAnonymizationRepository, IRepository<UserTypeMenu> userTypeMenuRepository,
            IEasyCachingProvider provider,ILogger<IRaCISCacheHangfireJob> logger, IRepository<VisitTask> visitTaskRepository)
        {
            _trialRepository = trialRepository;
            _provider = provider;
            _logger = logger;
            _systemAnonymizationRepository = systemAnonymizationRepository;
            _userTypeMenuRepository = userTypeMenuRepository;
            _VisitTaskRepository = visitTaskRepository;
        }


        public async Task ProjectStartCache()
        {
            _logger.LogInformation("hangfire 定时缓存项目状态任务开始~");
            try
            {
                await MemoryCacheTrialStatus();

                await MemoryCacheAnonymizeData();

                await CacheUserTypePermission();
            }
            catch (Exception e)
            {
                _logger.LogError("hangfire 定时任务执行失败" + e.Message);

            }

            _logger.LogInformation("hangfire 定时任务执行结束");
        }

        public async Task MemoryCacheTrialStatus()
        {
            var list = await _trialRepository.Select(t => new { TrialId = t.Id, TrialStatusStr = t.TrialStatusStr })
                  .ToListAsync();

            list.ForEach(t => _provider.Set(t.TrialId.ToString(), t.TrialStatusStr, TimeSpan.FromDays(7)));

        }


        public async Task MemoryCacheAnonymizeData()
        {
            var systemAnonymizationList = await _systemAnonymizationRepository.Where(t => t.IsEnable).ToListAsync();

            _provider.Set(StaticData.Anonymize.Anonymize_AddFixedFiled, systemAnonymizationList.Where(t => t.IsAdd && t.IsFixed).ToList(), TimeSpan.FromDays(7));
            _provider.Set(StaticData.Anonymize.Anonymize_AddIRCInfoFiled, systemAnonymizationList.Where(t => t.IsAdd && t.IsFixed == false).ToList(), TimeSpan.FromDays(7));
            _provider.Set(StaticData.Anonymize.Anonymize_FixedField, systemAnonymizationList.Where(t => t.IsAdd == false && t.IsFixed).ToList(), TimeSpan.FromDays(7));
            _provider.Set(StaticData.Anonymize.Anonymize_IRCInfoField, systemAnonymizationList.Where(t => t.IsAdd == false && t.IsFixed == false).ToList(), TimeSpan.FromDays(7));
        }

        public async Task CacheUserTypePermission(Guid? cacheUserTypeId=null)
        {

            var permissionList = await _userTypeMenuRepository.Where(t => t.Menu.MenuType == "F")
                  .WhereIf(cacheUserTypeId != null, t => t.UserTypeId == cacheUserTypeId.Value).Select(t => new { t.UserTypeId, t.Menu.PermissionStr }).ToListAsync();

            foreach (var userTypeGroup in permissionList.GroupBy(t => t.UserTypeId))
            {
                _provider.Set($"{StaticData.CacheKey.UserTypeId}_{userTypeGroup.Key}", userTypeGroup.Select(t => t.PermissionStr).ToList(), TimeSpan.FromDays(7));
            }
        }

        public async Task CreateImageZipTask(string folderPath, string zipFilePath, string relativePath,Guid visitTaskId)
        {
            ZipFile.CreateFromDirectory(folderPath, zipFilePath);
            await _VisitTaskRepository.BatchUpdateNoTrackingAsync(t => t.Id == visitTaskId, u => new VisitTask() { PackState = PackState.Packed, PackRelativePath = relativePath });
        }
    }
}