package com.xinelu.manage.service.termbank.impl;

import com.xinelu.common.constant.Constants;
import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.utils.SecurityUtils;
import com.xinelu.common.utils.codes.GenerateSystemCodeUtil;
import com.xinelu.manage.domain.termbank.TermBank;
import com.xinelu.manage.mapper.termbank.TermBankMapper;
import com.xinelu.manage.service.termbank.ITermBankService;
import com.xinelu.manage.vo.termbank.TermBankTreeVO;
import com.xinelu.manage.vo.termbank.TermBankVO;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 常用术语(知识库)Service业务层处理
 *
 * @author xinelu
 * @date 2024-06-07
 */
@Service
public class TermBankServiceImpl implements ITermBankService {
    @Resource
    private TermBankMapper termBankMapper;
    @Resource
    private GenerateSystemCodeUtil generateSystemCodeUtil;

    /**
     * 查询常用术语(知识库)
     *
     * @param id 常用术语(知识库)主键
     * @return 常用术语(知识库)
     */
    @Override
    public TermBank selectTermBankById(Long id) {
        return termBankMapper.selectTermBankById(id);
    }

    /**
     * 查询常用术语(知识库)列表
     *
     * @param termBank 常用术语(知识库)
     * @return 常用术语(知识库)
     */
    @Override
    public List<TermBank> list(TermBank termBank) {
        return termBankMapper.selectTermBankList(termBank);
    }

    public List<TermBank> selectTermBankList(TermBank termBank) {
        termBank.setTermLevel(1L);
        return termBankMapper.selectTermBankList(termBank);
    }

    /**
     * 新增常用术语(知识库)
     *
     * @param termBank 常用术语(知识库)
     * @return 结果
     */
    @Override
    public AjaxResult insertTermBank(TermBank termBank) {
        if (Objects.nonNull(termBank) && Objects.nonNull(termBank.getTermLevel()) && termBank.getTermLevel() < Constants.TERM_MAX_LEVEL) {
            termBank.setTermLevel(termBank.getTermLevel() + 1);
        }
        if (Objects.nonNull(termBank) && Objects.nonNull(termBank.getTermLevel()) && termBank.getTermLevel() > (Constants.TERM_MAX_LEVEL)) {
            return AjaxResult.error("常用话术层数最大值为" + Constants.TERM_MAX_LEVEL + "层");
        }
        if (Objects.nonNull(termBank) && StringUtils.isBlank(termBank.getParentTermCode())) {
            termBank.setTermLevel(Constants.TERM_MIN_LEVEL);
        }
        termBank.setCreateTime(LocalDateTime.now());
        termBank.setCreateBy(SecurityUtils.getUsername());
        termBank.setTermCode(Constants.TERM_CODE + generateSystemCodeUtil.generateSystemCode(Constants.TERM_CODE));
        return AjaxResult.success(termBankMapper.insertTermBank(termBank));
    }

    /**
     * 修改常用术语(知识库)
     *
     * @param termBank 常用术语(知识库)
     * @return 结果
     */
    @Override
    public AjaxResult updateTermBank(TermBank termBank) {
        termBank.setTermLevel(1L);
        if (StringUtils.isNotBlank(termBank.getParentTermCode())) {
            TermBank parentTermCode = termBankMapper.selectTermBankByParentTermCode(termBank.getParentTermCode());
            if (Objects.nonNull(parentTermCode) && Objects.nonNull(parentTermCode.getTermLevel())) {
                termBank.setTermLevel(parentTermCode.getTermLevel() + 1);
            }
        }
        if (Objects.nonNull(termBank.getTermLevel()) && termBank.getTermLevel() > (Constants.TERM_MAX_LEVEL)) {
            return AjaxResult.error("常用话术层数最大值为" + Constants.TERM_MAX_LEVEL + "层");
        }
        if (StringUtils.isBlank(termBank.getParentTermCode())) {
            termBank.setTermLevel(Constants.TERM_MIN_LEVEL);
        }
        termBank.setUpdateTime(LocalDateTime.now());
        return AjaxResult.success(termBankMapper.updateTermBank(termBank));
    }

    /**
     * 批量删除常用术语(知识库)
     *
     * @param ids 需要删除的常用术语(知识库)主键
     * @return 结果
     */
    @Override
    public int deleteTermBankByIds(Long[] ids) {
        return termBankMapper.deleteTermBankByIds(ids);
    }

    /**
     * 删除常用术语(知识库)信息
     *
     * @param id 常用术语(知识库)主键
     * @return 结果
     */
    @Override
    public int deleteTermBankById(Long id) {
        return termBankMapper.deleteTermBankById(id);
    }

    /**
     * 常用术语层级树图
     */
    @Override
    public List<TermBankTreeVO> bankLevel(Long level) {
        List<TermBankVO> termBanks = termBankMapper.selectTermBankTree(level);
        if (CollectionUtils.isEmpty(termBanks)) {
            return new ArrayList<>();
        }
        List<TermBankVO> termBankVOS = buildDeptTree(termBanks);
        return termBankVOS.stream().map(TermBankTreeVO::new).collect(Collectors.toList());
    }

    public List<TermBankVO> buildDeptTree(List<TermBankVO> termBanks) {
        List<TermBankVO> returnList = new ArrayList<>();
        List<String> tempList = termBanks.stream().filter(Objects::nonNull).map(TermBank::getTermCode).filter(Objects::nonNull).collect(Collectors.toList());
        for (TermBankVO termBank : termBanks) {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(termBank.getParentTermCode())) {
                recursionFn(termBanks, termBank);
                returnList.add(termBank);
            }
        }
        if (returnList.isEmpty()) {
            returnList = termBanks;
        }
        return returnList;
    }

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

    private List<TermBankVO> getChildList(List<TermBankVO> list, TermBankVO t) {
        List<TermBankVO> tlist = new ArrayList<TermBankVO>();
        Iterator<TermBankVO> it = list.iterator();
        while (it.hasNext()) {
            TermBankVO n = (TermBankVO) it.next();
            if (Objects.nonNull(n.getParentTermCode()) && n.getParentTermCode().equals(t.getTermCode())) {
                tlist.add(n);
            }
        }
        return tlist;
    }

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