package com.blueland.service.impl;


import java.util.*;

/**
 * @author 代码自动生成工具
 * @version 1.0
 * @since
 */

import java.util.stream.Collectors;

import javax.annotation.PostConstruct;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.blueland.constant.RedisConstant;
import com.blueland.core.util.RemoteDictUtils;
import com.blueland.core.util.UserUtils;
import com.blueland.model.TPfDict;
import com.blueland.service.IDictService;
import com.blueland.service.SysRedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import com.blueland.core.util.IdentifierGenerator;
import com.blueland.core.util.StringUtil;
import com.blueland.bo.DictEntity;
import com.blueland.dao.DictDao;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class DictServiceImpl extends ServiceImpl<DictDao, TPfDict> implements IDictService {
    @Autowired
    //Dict对应的DAO类,主要用于数据库的增删改查等操作
    private DictDao dictDao;

    //key为 租户ID-父编码
//    private Map<String, List<DictEntity>> dictMap = new HashMap<String, List<DictEntity>>();

//    @Autowired
//    private RemoteDictUtils remoteDictUtils;

    @Autowired
    SysRedisService sysRedisService;

    /**
     * 根据条件查询dict列表(分页)
     */
    @Override
    public Page<DictEntity> findDictPageListByParams(Map<String, Object> dict, int curPage, int pageSize) {
        Page<DictEntity> page = new Page<>(curPage, pageSize);
        Page<DictEntity> list = dictDao.findDictPagePageByParams(page, dict);
        return list;
    }

    /**
     * 根据条件查询dict列表(不分页)
     */
    @Override
    public List<DictEntity> findDictList(Map<String, Object> maps) {
        return dictDao.findDictPageListByParams(maps);
    }

    /**
     * 新增或修改Dict
     *
     * @param dict
     * @return
     */
    @Override
    public int saveDict(DictEntity dict) {
        int result = 0;
        String id = dict.getId();
        if (id != null && !"".equals(id)) {
            dict.setUpdateDate(new Date());
            result = dictDao.updateDict(dict);
        } else {
            dict.setId(null);
            dict.setCreateDate(new Date());
            dict.setUpdateDate(new Date());
            dict.setAppId(UserUtils.getTenantId());
            TPfDict tPfDict = BeanUtil.copyProperties(dict, TPfDict.class);
            result = dictDao.insert(tPfDict);
        }
        return result;
    }

    /**
     * 根据ID删除对象（物理删除）
     */
    @Override
    public int deleteDictById(String id) {
        //先获取
        int count = dictDao.deleteDictById(id);
        return count;
    }

    /**
     * 根据编码删除对象（逻辑删除：修改状态）
     */
    @Override
    public int deleteDicts(String dictCode) {
        int count = dictDao.deleteDicts(dictCode);
        return count;
    }


    /**
     * 20200428 add 优先查询缓存，没有再查询数据库
     */
    @Override
    public List<DictEntity> findDictListByCache(String appId) {
        // 从redis中获取数据
        List<DictEntity> dictList = sysRedisService.getDictList();
        //没有数据再查数据库
        if (dictList.size() == 0) {
            dictList = dictDao.findDictPageListByAppId(appId);
        }
        return dictList;
    }

    /**
     * 20200428 add 优先查询缓存，没有再查询数据库
     *
     * @return
     */
    @Override
    public List<DictEntity> findchildListByCache(String appId, String dictParentId) {
        // 从redis中获取数据
        List<DictEntity> dictList = sysRedisService.getDictListByParentCode(dictParentId);
        if (ObjectUtil.isEmpty(dictList)) {
            DictEntity dictEntity = new DictEntity();
            dictEntity.setAppId(appId);
            dictEntity.setDictParentId(dictParentId);
            dictEntity.setStatus("Y");
            dictList = this.baseMapper.findList(dictEntity);
        }
        dictList = dictList.stream().sorted(Comparator.comparing(DictEntity:: getSort)).collect(Collectors.toList());
        return dictList;
    }

    /**
     * 20200428 add 优先查询缓存，没有再查询数据库
     *
     * @return
     */
    @Override
    public DictEntity findByCache(DictEntity param) {
        //20190808 modify 如果没传dictCode 也能返回结果，是有问题的，这里加上判断
        DictEntity dictEntity = null;
        if (StringUtil.notEmpty(param.getDictCode())) {
            String appId = param.getAppId();
            String dictParentId = param.getDictParentId();
            dictEntity = sysRedisService.getDict(param.getDictCode(), param.getDictParentId());
            if (ObjectUtil.isEmpty(dictEntity)) {
                QueryWrapper<TPfDict> queryWrapper = new QueryWrapper<>();
                queryWrapper.lambda().eq(TPfDict::getAppId, appId);
                queryWrapper.lambda().eq(TPfDict::getDictParentId, dictParentId);
                queryWrapper.lambda().eq(TPfDict::getDictCode, param.getDictCode());
                TPfDict dict = dictDao.selectOne(queryWrapper);
                dictEntity = BeanUtil.toBean(dict, DictEntity.class);
            }
        }
        return dictEntity;
    }

    /**
     * 20200908 add 根据父编码返回集合
     *
     * @return
     */
    @Override
    public Map<String, List<DictEntity>> findByParentcodesCache(String appId, List<String> parentcodes) {
        Map<String, List<DictEntity>> resultMap = new HashMap<>();
        for (String parentcode : parentcodes) {
            // 先从缓存中查询
            List<DictEntity> dictList = sysRedisService.getDictListByParentCode(parentcode);
            // 如果没有查到就去从数据库中查询
            if (ObjectUtil.isEmpty(dictList)) {
                dictList = dictDao.getDictListByCode(null, parentcode);
            }
            // 有数据就行格式化
            if (ObjectUtil.isNotEmpty(dictList)) {
                resultMap.put(parentcode, dictList.stream().filter(x -> x.getDictParentId().equals(parentcode)).collect(Collectors.toList()));
            }
        }
        return resultMap;
    }

    /**
     * 获取所有字典
     *
     * @return
     */
    @Override
    public List<DictEntity> getDictList() {
        List<DictEntity> dictList = sysRedisService.getDictList();
        if (ObjectUtil.isEmpty(dictList)) {
            dictList = dictDao.getDictList();
        }
        return dictList;
    }

    @Override
    public List<DictEntity> getListByAppId(String appId) {
        return this.baseMapper.getList(appId);
    }

    @Override
    public void deleteDictByAppId(String appId) {
        this.baseMapper.deleteDictByAppId(appId);
    }

    /**
     * 根据ids获取字典
     *
     * @param ids
     * @return
     */
    @Override
    public List<DictEntity> findByIds(String[] ids) {
        return dictDao.findByIds(ids);
    }


    /**
     * 拼接key
     */
    @Override
    public String splicing(DictEntity dictEntity) {
        if (ObjectUtil.isNull(dictEntity)) {
            return "";
        }
        return dictEntity.getAppId() + ":" + dictEntity.getDictParentId() + ":" + dictEntity.getDictCode();
    }

    @Override
    public TPfDict get(DictEntity model) {
        return dictDao.selectOne(buildQueryWrapper(model));
    }

    @Override
    public Page<DictEntity> findPage(DictEntity model) {
        Page<DictEntity> page = new Page(model.getPageNum(), model.getPageSize());
        return dictDao.findPage(page, model);
    }


    private LambdaQueryWrapper<TPfDict> buildQueryWrapper(DictEntity bo) {
        LambdaQueryWrapper<TPfDict> lqw = Wrappers.lambdaQuery();
        lqw.eq(ObjectUtil.isNotEmpty(bo.getId()), TPfDict::getId, bo.getId());
        lqw.like(ObjectUtil.isNotEmpty(bo.getDictCode()), TPfDict::getDictCode, bo.getDictCode());
        lqw.eq(ObjectUtil.isNotEmpty(bo.getDictParentId()), TPfDict::getDictParentId, bo.getDictParentId());
        lqw.like(ObjectUtil.isNotEmpty(bo.getDictName()), TPfDict::getDictName, bo.getDictName());
        lqw.eq(ObjectUtil.isNotEmpty(bo.getStatus()), TPfDict::getStatus, bo.getStatus());
        lqw.eq(ObjectUtil.isNotEmpty(bo.getCreatorId()), TPfDict::getCreatorId, bo.getCreatorId());
        lqw.eq(ObjectUtil.isNotEmpty(bo.getUpdatorId()), TPfDict::getUpdatorId, bo.getUpdatorId());
        lqw.eq(ObjectUtil.isNotEmpty(bo.getAppId()), TPfDict::getAppId, bo.getAppId());
        return lqw;
    }
}
