package com.gree.mall.manager.logic.common;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.gree.mall.manager.bean.common.SysDictAddParam;
import com.gree.mall.manager.bean.common.SysDictBean;
import com.gree.mall.manager.bean.common.SysDictVO;
import com.gree.mall.manager.commonmapper.AdminMapper;
import com.gree.mall.manager.exception.RemoteServiceException;
import com.gree.mall.manager.plus.entity.SysDict;
import com.gree.mall.manager.plus.entity.SysDictType;
import com.gree.mall.manager.plus.service.SysDictRefService;
import com.gree.mall.manager.plus.service.SysDictService;
import com.gree.mall.manager.plus.service.SysDictTypeService;
import com.gree.mall.manager.utils.RedisUtil;
import com.gree.mall.manager.zfire.bean.ZfireParamBean;
import com.gree.mall.manager.zfire.util.FieldUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;


@Service
public class SysDictLogic   {

    @Autowired
    CommonLogic commonLogic;


    @Autowired
    SysDictService sysDictService;
    @Autowired
    SysDictRefService sysDictRefService;

    @Autowired
    SysDictTypeService sysDictTypeService;
    @Autowired
    AdminMapper adminMapper;

    @Autowired
    RedisUtil redisUtil;


    /**
     * 字典类型
     * @param open 是否开放业务人配置 , 为空不限制
     * @return
     */
    public List<SysDictType> typeList(Boolean open){
        List<SysDictType> list = sysDictTypeService
                .lambdaQuery()
                .eq(Objects.nonNull(open), SysDictType::getOpen, open)
                .list();
        return list;
    }


    /**
     * 字典列表
     */
    public IPage<SysDictVO> sysDictIPage(ZfireParamBean zfireParamBean){
        ZfireParamBean zfireParam = FieldUtils.supplyParam(zfireParamBean);
        IPage<SysDictVO> sysDictIPage = adminMapper.sysDictList(new Page(zfireParamBean.getPageNum(), zfireParamBean.getPageSize()), zfireParam);
        return sysDictIPage;
    }



 /**
     * 删除字典
     * @param id
     * @param open 是否开放业务, 为空或者false不限制
     */
    public void delete(String id, Boolean open){
        if (BooleanUtils.isTrue(open)) {
            String dictType = sysDictService.lambdaQuery()
                    .select(SysDict::getDictType)
                    .eq(SysDict::getSysDictId, id)
                    .oneOpt()
                    .map(SysDict::getDictType)
                    .orElseThrow(() -> new RemoteServiceException("字典值不存在"));
            sysDictTypeService.lambdaQuery()
                    .select(SysDictType::getOpen)
                    .eq(SysDictType::getDictType, dictType)
                    .oneOpt()
                    .map(SysDictType::getOpen)
                    .filter(item -> item)
                    .orElseThrow(() -> new RemoteServiceException("该字典类型暂不开放配置"));
        }
        sysDictService.removeById(id);

    }

    /**
     * 字典详情
     */
    public SysDict detail(String id){
        return sysDictService.getById(id);
    }

    /**
     * 字典查询，key = dictCode  value = dictObject
     * @param type
     * @return
     */
    public Map<String, SysDict> dictByTypeOfCode(String type){
        List<SysDict> sysDicts = this.dictByType(type);
        Map<String, SysDict> sysDictMap = sysDicts.stream().collect(Collectors.toMap(v -> v.getDictCode(), Function.identity()));
        return sysDictMap;
    }
    public SysDict dictByTypeOfCode(String type,String dictCode){
        List<SysDict> sysDicts = this.dictByType(type);
        Map<String, SysDict> sysDictMap = sysDicts.stream().collect(Collectors.toMap(v -> v.getDictCode(), Function.identity()));
        return sysDictMap.get(dictCode);
    }

    /**
     * 字典查询，key = dictValue value = dictObject
     * @param type
     * @return
     */
    public Map<String, SysDict> dictByTypeOfValue(String type){
        List<SysDict> sysDicts = this.dictByType(type);
        Map<String, SysDict> sysDictMap = sysDicts.stream().collect(Collectors.toMap(v -> v.getDictValue(), Function.identity()));
        return sysDictMap;
    }
    public SysDict dictByTypeOfValue(String type,String dictValue){
        List<SysDict> sysDicts = this.dictByType(type);
        Map<String, SysDict> sysDictMap = sysDicts.stream().collect(Collectors.toMap(v -> v.getDictValue(), Function.identity()));
        return sysDictMap.get(dictValue);
    }


    /**
     * 字典查询
     * @param type
     * @return
     */
    public List<SysDict> dictByType(String type){
        return this.dictByType(type,null);
    }

    /**
     * 字典值查询
     * @param type
     * @param open 是否开放业务, 为空查询所有
     * @return
     */
    public List<SysDict> dictByType(String type, Boolean open) {
        SysDictType dictType = sysDictTypeService.lambdaQuery()
                .eq(SysDictType::getDictType, type)
                .eq(Objects.nonNull(open), SysDictType::getOpen, open)
                .one();
        if (dictType == null) {
            return Collections.emptyList();
        }
        List<SysDict> dictList = sysDictService.lambdaQuery()
                .eq(SysDict::getDictType, type)
                .orderByDesc(SysDict::getSortNum)
                .list();

        return dictList;
    }

    public void saveOpenDict(SysDict param) {
        sysDictTypeService.lambdaQuery()
                .select(SysDictType::getDictType)
                .eq(SysDictType::getDictType, param.getDictType())
                .eq(SysDictType::getOpen, true)
                .oneOpt()
                .orElseThrow(() -> new RemoteServiceException("暂不开放该字典类型配置"));
        checkRepeatDictCode(param.getDictType(), param.getDictCode());

        sysDictService.save(param);
    }

    public void updateOpenDict(SysDict param) {
        String dictType = sysDictService.lambdaQuery()
                .select(SysDict::getDictType)
                .eq(SysDict::getSysDictId, param.getSysDictId())
                .oneOpt()
                .map(SysDict::getDictType)
                .orElseThrow(() -> new RemoteServiceException("字典类型错误,修改失败"));
        sysDictTypeService.lambdaQuery()
                .select(SysDictType::getDictType)
                .eq(SysDictType::getDictType, dictType)
                .eq(SysDictType::getOpen, true)
                .oneOpt()
                .orElseThrow(() -> new RemoteServiceException("暂不开放该字典类型配置"));
        sysDictService.updateById(param);
    }

    private void checkRepeatDictCode(String dictType, String code) {
        Integer count = sysDictService.lambdaQuery()
                .eq(SysDict::getDictType, dictType)
                .eq(SysDict::getDictCode, code)
                .count();
        if (count > 0) {
            throw new RemoteServiceException(code + "重复存在");
        }
    }


    public void addType(SysDictType param) {
        param.insert();
    }

    public void updateType(SysDictType param) {
        param.updateById();
    }

    public void delType(String id, boolean b) {
        sysDictTypeService.removeById(id);
    }

    public SysDictType detailType(String id) {
        return sysDictTypeService.getById(id);
    }

    public List<SysDict> getSysDictList(String dictType) {
        List<SysDict> list = sysDictService.lambdaQuery().eq(SysDict::getDictType, dictType).list();
        return list;
    }
}
