package cn.estsh.i3plus.core.apiservice.serviceimpl.base;

import cn.estsh.i3plus.core.api.iservice.base.ISystemInitService;
import cn.estsh.i3plus.core.api.iservice.busi.ISystemResourceService;
import cn.estsh.i3plus.platform.common.util.CommonConstWords;
import cn.estsh.i3plus.pojo.base.enumutil.ImppEnumUtil;
import cn.estsh.i3plus.pojo.platform.bean.SysConfig;
import cn.estsh.i3plus.pojo.platform.bean.SysDictionary;
import cn.estsh.i3plus.pojo.platform.bean.SysLocaleLanguage;
import cn.estsh.i3plus.pojo.platform.bean.SysLocaleResource;
import cn.estsh.i3plus.pojo.platform.repository.SysConfigRepository;
import cn.estsh.i3plus.pojo.platform.repository.SysDictionaryRepository;
import cn.estsh.impp.framework.boot.util.ImppRedis;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description :
 * @Reference :
 * @Author : Adair Peng
 * @CreateDate : 2019-01-11 12:34
 * @Modify:
 **/
@Service
public class SystemInitService implements ISystemInitService {

    private static final Logger LOGGER = LoggerFactory.getLogger(SystemLoginService.class);

    @Autowired
    private SysConfigRepository configRDao;

    @Autowired
    private SysDictionaryRepository dictionaryRDao;

    @Autowired
    public ISystemResourceService systemResourceService;

    @Resource(name="redisRes")
    private ImppRedis redisRes;

    private int type = ImppEnumUtil.SYS_CACHE_TYPE.REDIS.getValue();

    @Override
    @ApiOperation(value = "初始化加载所有数据",notes = "初始化加载所有数据")
    public void loadAll() {
        type = ImppEnumUtil.SYS_CACHE_TYPE.REDIS.getValue();
        loadSysConfig();
        loadSysDictionary();
        loadSysLocaleLanguage();
    }

    @Override
    @ApiOperation(value = "加载系统配置",notes = "加载系统配置")
    public void loadSysConfig() {
        String redisKey = null;
        List<SysConfig> list = configRDao.findAll();
        for (SysConfig config : list) {
            redisKey = CommonConstWords.REDIS_PREFIX_CACHE_CONFIG + "_" + config.getConfigCode();

            //存放于缓存
            putDataToCache(redisKey, config,SysConfig.class);
        }
        LOGGER.info("加载系统配置数量：【{}】",list.size());
    }

    @Override
    @ApiOperation(value = "加载字典数据",notes = "加载字典数据")
    public void loadSysDictionary() {
        try {
            List<SysDictionary> list = dictionaryRDao.findAll();
            if(list != null && list.size() > 0){
                Map<String, List<SysDictionary>> parentCodeMap = list.stream().collect(Collectors.groupingBy(SysDictionary::getParentCodeRdd));
                Map<Long, List<SysDictionary>> parentIdMap = list.stream().collect(Collectors.groupingBy(SysDictionary::getParentId));

                for (String key : parentCodeMap.keySet()) {
                    //存放于缓存
                    putDataToCache(CommonConstWords.REDIS_PREFIX_CACHE_DICTIONARY + "_" + key,
                            parentCodeMap.get(key),List.class);
                }

                for (long key : parentIdMap.keySet()) {
                    putDataToCache(CommonConstWords.REDIS_PREFIX_CACHE_DICTIONARY + "_" + key,
                            parentIdMap.get(key),List.class);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    @Override
    @ApiOperation(value = "加载语言数据",notes = "加载语言数据")
    public void loadSysLocaleLanguage() {
        // Redis 缓存
        if(type == ImppEnumUtil.SYS_CACHE_TYPE.REDIS.getValue()){
            /**
             * 整体数据结构：
             * code <lang : value>
             *    先根据code查询，判断是否存在，然后通过语言获取对应的值
             */
            HashMap<String,HashMap<String,String>> resMap = new HashMap();
            HashMap<String,String> lanMap = null;
            HashMap<String,HashMap<String,String>> webLangMap = new HashMap<>();
            HashMap<String,String> webResMap;

            //语言数量
            List<SysLocaleLanguage> langList = systemResourceService.listSysLocaleLanguage(null);

            //查询所有资源
            List<SysLocaleResource> resourceList = systemResourceService.listSysLocaleResource(null);
            LOGGER.info("【加载平台资源】共有{}个资源，{}种语言。", resourceList.size(), langList.size());
            for (SysLocaleResource res : resourceList) {
                //遍历资源，放入map中
                lanMap = resMap.get(res.getResourceKey());
                //判断是否已存在资源信息
                if (lanMap == null){
                    lanMap = new HashMap();
                    //将key/代码放入
                    resMap.put(res.getResourceKey(), lanMap);
                }
                //根据语言放入
                lanMap.put(res.getLanguageCode(), res.getResourceValue());

                // web 资源
                if(!webLangMap.containsKey(res.getLanguageCode())){
                    webLangMap.put(res.getLanguageCode(), new HashMap<>());
                }
                // 放入资源信息
                webResMap = webLangMap.get(res.getLanguageCode());
                webResMap.put(res.getResourceKey(), res.getResourceValue());
            }

            for (String key : resMap.keySet()) {
                //放入缓存
                redisRes.putHashMap(CommonConstWords.REDIS_PREFIX_CACHE_LANGUAGE + key,resMap.get(key),0);
            }

            for(String key : webLangMap.keySet()){
                //放入缓存
                redisRes.putHashMap(CommonConstWords.REDIS_PREFIX_CACHE_LANGUAGE + key,webLangMap.get(key),0);
            }

        }
    }


    /**
     * 缓存存放数据统一管理
     * @param key
     * @param data
     * @param dataType
     */
    private void putDataToCache(String key,Object data,Class dataType){
        if(type == ImppEnumUtil.SYS_CACHE_TYPE.REDIS.getValue()){
            LOGGER.info(" Put Cache Redis Key:{},value:{},dataType:{}",key,data,dataType);
            // Redis 缓存
            if(dataType == List.class){
                redisRes.putList(key,data,-1);
            }else if(dataType == SysConfig.class){
                redisRes.putObject(key,data,-1);
            }else{
                LOGGER.error("不支持树形{}存放缓存！",dataType);
            }
        }
    }

    /**
     * 从缓存获取对象数据
     * @param key
     * @param dataType
     * @return
     */
    @Override
    @ApiOperation(value = "获取缓存中的数据",notes = "获取缓存中的数据")
    public Object getDataFromCache(String key,Class dataType){
        if(type == ImppEnumUtil.SYS_CACHE_TYPE.REDIS.getValue()){
            // Redis 缓存
            if(dataType == List.class){
                return redisRes.getList(key,0,-1);
            }else if(dataType == SysConfig.class){
                return redisRes.getObject(key);
            }else{
                LOGGER.error("不支持树形{}存放缓存！",dataType);
            }
        }
        return null;
    }
}
