package com.mosty.base.utils;

import com.alibaba.fastjson.JSON;
import com.mosty.base.feign.service.MostyBaseFeignService;
import com.mosty.common.base.constant.Constants;
import com.mosty.common.base.domain.ResponseResult;
import com.mosty.common.base.entity.log.SpringUtils;
import com.mosty.common.base.exception.BusinessException;
import com.mosty.common.base.util.StringUtils;
import com.mosty.common.config.entity.SysDictItem;
import com.mosty.common.config.entity.vo.SysDictItemVO;
import com.mosty.common.config.entity.vo.SysDictVO;
import com.mosty.common.redis.service.RedisService;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Objects;

/**
 * @author zhangzhao
 * @description 字典工具类
 * @modifier zhangzhao
 * @modifiedTime 2023/3/17 17:40
 * @since 2023/3/17 17:40
 */
public class DictUtils {

    /**
     * 字典编号-人员标签
     */
    public static final String DICT_ZDBH_D_BZ_RYBQ = "D_BZ_RYBQ";

    /**
     * 字典编号-车辆标签
     */
    public static final String DICT_ZDBH_D_BZ_CLBQ = "D_BZ_CLBQ";

    /**
     * 公共FeignService
     */
    private static MostyBaseFeignService mostyBaseFeignService;

    /**
     * 获取FeignService
     * @return 返回FeignService
     */
    private static MostyBaseFeignService getBaseFeignService(){
        if(mostyBaseFeignService == null){
            DictUtils.mostyBaseFeignService = SpringUtils.getBean(MostyBaseFeignService.class);
        }
        return DictUtils.mostyBaseFeignService;
    }

    /**
     * 设置字典缓存
     *
     * @param key 参数键
     * @param dictDatas 字典数据列表
     */
    public static void setDictCache(String key, List<SysDictItem> dictDatas)
    {
        SpringUtils.getBean(RedisService.class).setCacheObject(getCacheKey(key), dictDatas);
    }

    /**
     * 设置cache key
     *
     * @param configKey 参数键
     * @return 缓存键key
     */
    public static String getCacheKey(String configKey)
    {
        return Constants.SYS_DICT_KEY + configKey;
    }

    /**
     * 获取字典信息
     * @param zdbh 字典编号
     * @return 字典信息
     */
    public static SysDictVO getSysDict(String zdbh){
        ResponseResult<SysDictVO> responseResult = DictUtils.getBaseFeignService().getSysDictByCode(zdbh);
        if (responseResult == null || !responseResult.isSuccess()) {
            System.out.println("获取查询条件异常 responseResult = " + JSON.toJSONString(responseResult));
            throw new BusinessException("字典服务调用异常");
        }
        return responseResult.getData();
    }

    /**
     * 获取字典项列表
     * @param zdbh 字典编号
     * @return 字典项列表
     */
    public static List<SysDictItemVO> getDictItemList(String zdbh){
        SysDictVO sysDictVO = DictUtils.getSysDict(zdbh);
        if(sysDictVO == null || CollectionUtils.isEmpty(sysDictVO.getItemList())){
            return null;
        }
        return sysDictVO.getItemList();
    }

    /**
     * 判断该字典代码是否在字典项中
     * @param zdbh 字典编号
     * @param dm 字典代码
     * @return 是否在该字典项中
     */
    public static boolean isDictContainValue(String zdbh, String dm){
        //如果字典编号和字典代码有一项为空，则返回错误
        if(StringUtils.isBlank(zdbh) || StringUtils.isBlank(dm)){
            return false;
        }

        List<SysDictItemVO> sysDictItemList = DictUtils.getDictItemList(zdbh);

        //如果未查询到该字典，返回错误
        if(sysDictItemList == null || sysDictItemList.isEmpty()){
            return false;
        }

        //循环字典项数据，如果存在该数据，则返回正确
        for(SysDictItemVO sysDictItemVO : sysDictItemList){
            if (Objects.equals(dm, sysDictItemVO.getDm())) {
                return true;
            }
        }

        return false;
    }

    /**
     * 判断该字典代码是否在字典项中(多个代码判断，有一个不正确就返回错误)
     * @param zdbh 字典编号
     * @param dm 字典代码
     * @return 是否在该字典项中（有一个不在就返回错误）
     */
    public static boolean isDictContainValues(String zdbh, String dm){
        //如果字典编号和字典代码有一项为空，则返回错误
        if(StringUtils.isBlank(zdbh) || StringUtils.isBlank(dm)){
            return false;
        }

        List<SysDictItemVO> sysDictItemList = DictUtils.getDictItemList(zdbh);

        //如果未查询到该字典，返回错误
        if(sysDictItemList == null || sysDictItemList.isEmpty()){
            return false;
        }

        String[] dmArray = dm.split(",");
        for(String dmItem : dmArray){
            //如果有字典代码为空，直接返回错误
            if(StringUtils.isBlank(dmItem)){
                return false;
            }
            //此代码是否在字典之中
            boolean isThisDmInDict = false;
            //循环字典项列表判断代码是否在字典项中
            for(SysDictItemVO sysDictItemVO : sysDictItemList){
                if(Objects.equals(dmItem, sysDictItemVO.getDm())){
                    isThisDmInDict = true;
                }
            }
            //经过循环后，isDmInDict依然为false，表示代码不在字典项列表中，直接返回
            if(!isThisDmInDict){
                return false;
            }
        }

        //经过所有循环后，到这一步，表示传入的代码都在字典中，所以返回正确
        return true;
    }


    /**
     * 查询具体字典
     * @param zdbh 字典编号
     * @param dm 字典代码
     * @return 是否在该字典项中
     */
    public static SysDictItemVO getDictZdbhAndDm(String zdbh, String dm){
        //如果字典编号和字典代码有一项为空，则返回错误
        if(StringUtils.isBlank(zdbh) || StringUtils.isBlank(dm)){
            return null;
        }

        List<SysDictItemVO> sysDictItemList = DictUtils.getDictItemList(zdbh);

        //如果未查询到该字典，返回错误
        if(sysDictItemList == null || sysDictItemList.isEmpty()){
            return null;
        }

        //循环字典项数据，如果存在该数据，则返回正确
        for(SysDictItemVO sysDictItemVO : sysDictItemList){
            if (Objects.equals(dm, sysDictItemVO.getDm())) {
                return sysDictItemVO;
            }
        }

        return null;
    }

    /**
     * 查询字典名称
     * @param zdbh 字典编号
     * @param dm 字典代码
     * @return 字典名称
     */
    public static String getDictZdmcByZdbhAndDm(String zdbh, String dm){
        String zdmc = "";

        SysDictItemVO sysDictItemVO = DictUtils.getDictZdbhAndDm(zdbh, dm);
        if(ObjectUtils.isNotEmpty(sysDictItemVO)){
            zdmc = sysDictItemVO.getZdmc();
        }

        return zdmc;
    }

    /**
     * 查询字典名称（多个字典代码）
     * @param zdbh 字典编号
     * @param dms 字典代码（多个）
     * @return 字典名称
     */
    public static String getDictZdmcsByZdbhAndDms(String zdbh, String dms){
        if(StringUtils.isBlank(zdbh) || StringUtils.isBlank(dms)){
            return null;
        }
        StringBuilder zdmc = new StringBuilder();

        String[] dmArray = dms.split(Constant.SEPARATOR_ENGLISH_COMMA);
        for(String dm : dmArray){
            SysDictItemVO sysDictItemVO = DictUtils.getDictZdbhAndDm(zdbh, dm);
            if(ObjectUtils.isNotEmpty(sysDictItemVO)){
                zdmc.append(sysDictItemVO.getZdmc());
                zdmc.append(Constant.SEPARATOR_ENGLISH_COMMA);
            }
        }

        if(zdmc.length() > 0 ){
            zdmc.deleteCharAt(zdmc.length() - 1);
            return zdmc.toString();
        }
        return null;
    }

}
