package com.ruoyi.system.service.impl;


import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.TreeSelect;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.domain.entity.ChinaArea;
import com.ruoyi.system.mapper.ChinaAreaMapper;
import com.ruoyi.system.service.IChinaAreaService;
import org.springframework.stereotype.Service;

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

import static com.ruoyi.common.constant.UserConstants.CHINA_AREA;


/**
 * @author tjf
 * @Date: 2022/03/25/9:39
 */
@Service
public class ChinaAreaServiceImpl implements IChinaAreaService {

    @Resource
    private RedisCache redisService;

    @Resource
    private ChinaAreaMapper chinaAreaMapper;
    /**
     * 获取行政区域规划下拉树列表
     * @param chinaArea
     * @return
     */
    @Override
    public AjaxResult selectChinaAreaList(ChinaArea chinaArea) {

        //先去从redis获取
        List<TreeSelect> treeSelects = redisService.getCacheList(CHINA_AREA+chinaArea.getPid());
        if (treeSelects != null && treeSelects.size() > 0){
            //log.info("从缓存中获取到区域集合");
            return AjaxResult.success(treeSelects);
        }
        List<ChinaArea> chinaAreas = chinaAreaMapper.selectChinaAreaList(chinaArea);
        if (chinaAreas != null && chinaAreas.size() > 0){
            //log.info("从数据库中获取到行政区域集合");
            redisService.setCacheList(CHINA_AREA+chinaArea.getPid(),chinaAreas);
        }
        return AjaxResult.success(chinaAreas);
    }


    /**
     * 构建前端所需要下拉树结构
     *
     * @param chinaAreaList 行政区域列表
     * @return 下拉树结构列表
     */
    public List<TreeSelect> buildChinaAreaTreeSelect(List<ChinaArea> chinaAreaList) {
        List<ChinaArea> chinaAreaTrees = buildChinaAreaTree(chinaAreaList);
        return chinaAreaTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
    }


    /**
     * 构建前端所需要树结构
     *
     * @param chinaAreaList 行政区域列表
     * @return 树结构列表
     */
    public List<ChinaArea> buildChinaAreaTree(List<ChinaArea> chinaAreaList) {
        List<ChinaArea> returnList = new ArrayList<ChinaArea>();
        List<String> tempList = new ArrayList<String>();
        for (ChinaArea chinaArea : chinaAreaList) {
            tempList.add(chinaArea.getAreaId());
        }
        for (Iterator<ChinaArea> iterator = chinaAreaList.iterator(); iterator.hasNext(); ) {
            ChinaArea chinaArea = (ChinaArea) iterator.next();
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(chinaArea.getPid())) {
                recursionFn(chinaAreaList, chinaArea);
                returnList.add(chinaArea);
            }
        }
        if (returnList.isEmpty()) {
            returnList = chinaAreaList;
        }
        return returnList;
    }


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

    /**
     * 得到子节点列表
     */
    private List<ChinaArea> getChildList(List<ChinaArea> chinaAreaList, ChinaArea c) {
        List<ChinaArea> tlist = new ArrayList<ChinaArea>();
        Iterator<ChinaArea> it = chinaAreaList.iterator();
        while (it.hasNext()) {
            ChinaArea n = (ChinaArea) it.next();
            if (StringUtils.isNotNull(n.getPid()) && n.getPid().equals(c.getAreaId())) {
                tlist.add(n);
            }
        }
        return tlist;
    }

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