package com.hdkj.lt.core.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.hdkj.lt.base.constants.RedisKeyConstants;
import com.hdkj.lt.base.enums.OrganTypeEnum;
import com.hdkj.lt.core.sys.dao.SysOrganMapper;
import com.hdkj.lt.core.sys.model.po.SysOrgan;
import com.hdkj.lt.core.sys.service.ISysOrganService;
import com.hdkj.lt.utils.cache.RedisRepository;
import lombok.AllArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Nonnull;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description:
 * @Author: wenhao
 * @Create: 2024/03/28 13:54
 * @Version: 1.0
 */
@Service
@AllArgsConstructor
public class SysOrganServiceImpl extends ServiceImpl<SysOrganMapper, SysOrgan> implements ISysOrganService {

    private final RedisRepository redisRepository;

    @Override
    public void putAllToCache() {
        redisRepository.del(RedisKeyConstants.CACHE_KEY_ORGAN_HASH);
        Map<String, Object> dbMap = super.list(new LambdaQueryWrapper<SysOrgan>().ne(SysOrgan::getOrganType, OrganTypeEnum.USER.getCode()))
                .stream().collect(Collectors.toMap(e -> String.valueOf(e.getOrganId()), e -> e));
        redisRepository.putHashValues(RedisKeyConstants.CACHE_KEY_ORGAN_HASH, dbMap);
    }

    @Override
    public SysOrgan getCacheById(@Nonnull Long organId) {
        Map<String, Object> cacheMap = redisRepository.getHashValue(RedisKeyConstants.CACHE_KEY_ORGAN_HASH);
        SysOrgan sysOrgan = (SysOrgan) cacheMap.get(String.valueOf(organId));
        if (Objects.isNull(sysOrgan)) {
            sysOrgan = super.getById(organId);
            cacheMap.put(String.valueOf(organId), sysOrgan);
            redisRepository.putHashValues(RedisKeyConstants.CACHE_KEY_ORGAN_HASH, cacheMap);
        }
        return sysOrgan;
    }

    @Override
    public Map<Long, SysOrgan> getCacheMapByIds(Collection<Long> organIds) {
        Map<Long, SysOrgan> resultMap = Maps.newHashMap();
        if (CollectionUtils.isEmpty(organIds)) {
            return resultMap;
        }
        Map<String, Object> cacheMap = redisRepository.getHashValue(RedisKeyConstants.CACHE_KEY_ORGAN_HASH);
        organIds = organIds.stream().distinct().collect(Collectors.toList());
        organIds.forEach(i -> Optional.ofNullable(cacheMap.get(String.valueOf(i))).ifPresent(e -> resultMap.put(i, (SysOrgan) e)));
        Set<Long> queriedIds = resultMap.keySet();
        if (CollectionUtils.size(organIds) != CollectionUtils.size(queriedIds)) {
            List<Long> notFoundIds = (List<Long>) CollectionUtils.removeAll(organIds, queriedIds);
            Map<Long, SysOrgan> dbMap = super.listByIds(notFoundIds).stream().collect(Collectors.toMap(SysOrgan::getOrganId, e -> e));
            resultMap.putAll(dbMap);
            cacheMap.putAll(dbMap.entrySet().stream().collect(Collectors.toMap(e -> String.valueOf(e.getKey()), Map.Entry::getValue)));
            redisRepository.putHashValues(RedisKeyConstants.CACHE_KEY_ORGAN_HASH, cacheMap);
        }
        return resultMap;
    }

    @Override
    public Set<SysOrgan> getCacheSetByIds(Collection<Long> organIds) {
        Set<SysOrgan> resultSet = Sets.newHashSet();
        if (CollectionUtils.isEmpty(organIds)) {
            return resultSet;
        }
        Map<String, Object> cacheMap = redisRepository.getHashValue(RedisKeyConstants.CACHE_KEY_ORGAN_HASH);
        organIds = organIds.stream().distinct().collect(Collectors.toList());
        organIds.forEach(i -> Optional.ofNullable(cacheMap.get(String.valueOf(i))).ifPresent(e -> resultSet.add((SysOrgan) e)));
        List<Long> queriedIds = resultSet.stream().map(SysOrgan::getOrganId).collect(Collectors.toList());
        if (CollectionUtils.size(organIds) != CollectionUtils.size(queriedIds)) {
            List<Long> notFoundIds = (List<Long>) CollectionUtils.removeAll(organIds, queriedIds);
            List<SysOrgan> dbList = super.listByIds(notFoundIds);
            resultSet.addAll(dbList);
            Map<Long, SysOrgan> dbMap = dbList.stream().collect(Collectors.toMap(SysOrgan::getOrganId, e -> e));
            cacheMap.putAll(dbMap.entrySet().stream().collect(Collectors.toMap(e -> String.valueOf(e.getKey()), Map.Entry::getValue)));
            redisRepository.putHashValues(RedisKeyConstants.CACHE_KEY_ORGAN_HASH, cacheMap);
        }
        return resultSet;
    }

}
