package com.dsk.cscec.service.impl;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
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.dsk.common.core.domain.PageQuery;
import com.dsk.common.core.page.TableDataInfo;
import com.dsk.common.exception.ServiceException;
import com.dsk.common.utils.StringUtils;
import com.dsk.cscec.domain.BizDictData;
import com.dsk.cscec.domain.TreeSelect;
import com.dsk.cscec.domain.bo.BizDictDataBo;
import com.dsk.cscec.mapper.BizDictDataMapper;
import com.dsk.cscec.service.IBizDictDataService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 业务数据字典Service业务层处理
 *
 * @author ruoyi
 * @date 2021-11-08
 */
@Slf4j
@Service
public class BizDictDataServiceImpl extends ServiceImpl<BizDictDataMapper, BizDictData> implements IBizDictDataService {

    @Override
    public BizDictData queryById(Long id) {
        return baseMapper.queryByID(id);
    }

    @Override
    public TableDataInfo<BizDictData> queryPageList(BizDictDataBo bo, PageQuery query) {
        Page<BizDictData> result = baseMapper.selectPage(query.build(), buildQueryWrapper(bo));
        return TableDataInfo.build(result);
    }

    @Override
    public List<BizDictData> queryList(BizDictDataBo bo) {
        return baseMapper.selectList(buildQueryWrapper(bo));
    }

    private LambdaQueryWrapper<BizDictData> buildQueryWrapper(BizDictDataBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<BizDictData> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getCode()), BizDictData::getCode, bo.getCode());
        lqw.like(StringUtils.isNotBlank(bo.getName()), BizDictData::getName, bo.getName());
        lqw.eq(StringUtils.isNotBlank(bo.getType()), BizDictData::getType, bo.getType());
        lqw.eq(bo.getParentId() != null, BizDictData::getParentId, bo.getParentId());
        return lqw;
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(BizDictData entity) {
        //TODO 做一些数据校验,如唯一约束
        //code唯一校验
        if (StringUtils.isNotBlank(entity.getCode())) {
            LambdaQueryWrapper<BizDictData> lqw = Wrappers.lambdaQuery();
            lqw.eq(BizDictData::getType, entity.getType());
            lqw.eq(BizDictData::getCode, entity.getCode());
            lqw.ne(ObjectUtil.isNotNull(entity.getId()), BizDictData::getId, entity.getId());
            List<BizDictData> dictDataList = baseMapper.selectList(lqw);
            if (CollectionUtils.isNotEmpty(dictDataList)) {
                Assert.isTrue(false, "编码 " + entity.getCode() + " 已存在");
            }
        }

    }


    public List<BizDictData> buildDeptTree(List<BizDictData> depts) {
        List<BizDictData> returnList = new ArrayList<BizDictData>();
        List<String> tempList = new ArrayList<String>();
        for (BizDictData dept : depts) {
            tempList.add(dept.getId());
        }
        for (BizDictData dept : depts) {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(dept.getParentId())) {
                recursionFn(depts, dept);
                returnList.add(dept);
            }
        }
        if (returnList.isEmpty()) {
            returnList = depts;
        }
        return returnList;
    }


    /**
     * 递归列表
     */
    private void recursionFn(List<BizDictData> list, BizDictData t) {
        // 得到子节点列表
        List<BizDictData> childList = getChildList(list, t);
        t.setChildren(childList);
        for (BizDictData tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<BizDictData> getChildList(List<BizDictData> list, BizDictData t) {
        List<BizDictData> tlist = new ArrayList<BizDictData>();
        for (BizDictData n : list) {
            if (ObjectUtil.isNotNull(n.getParentId()) && n.getParentId().equals(t.getId())) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<BizDictData> list, BizDictData t) {
        return getChildList(list, t).size() > 0;
    }

    @Override
    public String importDict(List<BizDictData> dictList, String type, String operName) {
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (BizDictData dictData : dictList) {
            try {
                Assert.notNull(dictData.getName(), "字典名称不能为空");
                dictData.setType(type);
                //查询编码是否重复
                validEntityBeforeSave(dictData);
                //查询名称是否重复
                Assert.isFalse(baseMapper.countByName(dictData.getName(), type) != 0, "字典名称已存在");
                //查询是否有父级
                if (StrUtil.isNotBlank(dictData.getParentName())) {
                    BizDictData bizDictData = baseMapper.findByNameAndType(dictData.getParentName(), type);
                    if (bizDictData != null) {
                        dictData.setParentId(bizDictData.getId());
                        dictData.setAncestors(bizDictData.getAncestors() + "," + bizDictData.getId());
                    } else {
//                        bizDictData = new BizDictData();
//                        bizDictData.setName(dictData.getParentName());
//                        bizDictData.setType(type);
//                        this.save(bizDictData);
//                        dictData.setParentId(bizDictData.getId());
                        Assert.isTrue(false, "父级 " + dictData.getParentName() + " 不存在");
                    }
                } else {
                    dictData.setParentId("0");
                }

                this.save(dictData);
                successNum++;
                successMsg.append("<br/>" + successNum + "、字典 " + dictData.getName() + " 导入成功");
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、字典 " + dictData.getName() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
                log.error("BizDictDataServiceImpl.importDict() error:" + msg, e);
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    @Override
    public List<TreeSelect> buildDeptTreeSelect(BizDictDataBo bo) {
        List<BizDictData> list = baseMapper.selectList(buildQueryWrapper(bo));
        List<BizDictData> deptTrees = buildDeptTree(list);
        return deptTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
    }
}
