package com.yida.data.system.service.impl;


import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yida.data.common.core.entity.constant.AreaConstant;
import com.yida.data.common.core.entity.system.EduArea;
import com.yida.data.system.mapper.EduAreaMapper;
import com.yida.data.system.service.EduAreaService;
import com.yida.data.system.vo.CascadeAreaVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

@Slf4j
@Service
public class EduAreaServiceImpl extends ServiceImpl<EduAreaMapper, EduArea> implements EduAreaService {

    @Resource
    private EduAreaMapper areaMapper;

    @Override
    public EduArea saveArea(EduArea area) {
        if (area.getId() != null) {
            if (area.getType() == 0 || area.getType() == 1) {
                // 更新子节点的父信息
                List<EduArea> children =
                    areaMapper.selectList(Wrappers.lambdaQuery(new EduArea()).eq(EduArea::getParentId, area.getId()));
                if (children != null && children.size() > 0) {
                    areaMapper.updateParentName(area.getName(),
                        children.stream().map(EduArea::getId).collect(Collectors.toList()));
                }
            }
        }
        saveOrUpdate(area);
        return area;
    }

    @Transactional
    @Override
    public void deleteArea(Long areaId) {
        //List<EduUser> userList=userRepository.findByAreaId(areaId);
        //if (userList!=null&&userList.size()>0){
        //    eduUserMapper.cleanArea(userList.stream().map(EduUser::getId).collect(Collectors.toList()));
        //}
        List<EduArea> childList = areaMapper.selectList(Wrappers.lambdaQuery(new EduArea()).eq(EduArea::getParentId, areaId));
        if (childList != null && childList.size() > 0) {
            if (childList.get(0).getType() == 1) {
                List<EduArea> secondChildList =
                    areaMapper.selectList(Wrappers.lambdaQuery(new EduArea()).in(EduArea::getParentId,
                        childList.stream().map(EduArea::getId).collect(Collectors.toList())));
                childList.addAll(secondChildList);
            }
            remove(Wrappers.lambdaQuery(new EduArea()).in(EduArea::getId,
                childList.stream().map(EduArea::getId).collect(Collectors.toList())
            ));
        }
        removeById(areaId);
    }

    @Override
    public List<EduArea> findAreaTreeOrList(Long parentId, Integer isOnlyNext, Integer isTree) {
        // 是否包含下一级子节点  查询所有区域时不递归查询
        List<EduArea> areaList = parentId == null && isOnlyNext == 1 ? list() : findAllChild(
            parentId == null ? Collections.singletonList(AreaConstant.PROVINCE_PARENT_ID) :
                Collections.singletonList(parentId), isOnlyNext == 1);
        log.info("查询完成");
        if (isTree == null || isTree == 0) {
            // 拿到所有父节点进行建树
            List<EduArea> parentNodes = new ArrayList<>();
            areaList.forEach(x -> {
                if ((parentId == null && x.getType() == 0) || (parentId != null && parentId.equals(x.getParentId()))) {
                    parentNodes.add(x);
                }
            });
            Map<Integer, List<EduArea>> group = areaList.stream().collect(Collectors.groupingBy(EduArea::getType));
            for (EduArea parentNode : parentNodes) {
                buildTree(parentNode, group.get(1), group.get(2), group.get(3));
            }
            return parentNodes;
        } else {
            return areaList;
        }
    }

    @Override
    public List<EduArea> findAllChild(List<Long> areaId, Boolean includeChild) {
        List<EduArea> res = new ArrayList<>();
        List<EduArea> child = CollUtil.isNotEmpty(areaId)
            ? list(Wrappers.lambdaQuery(new EduArea()).in(EduArea::getParentId, areaId))
            : list(Wrappers.lambdaQuery(new EduArea()).eq(EduArea::getType, 0));
        if (CollUtil.isNotEmpty(child)) {
            res.addAll(child);
            if (includeChild && child.get(0).getType() != 3) {
                res.addAll(findAllChild(child.stream().map(x -> x.getId()).collect(Collectors.toList()), true));
            }
        }
        return res;
    }

    @Override
    public EduArea getInfo(Long areaId) {
        return getById(areaId);
    }

    @Override
    public EduArea getInfoByName(String name, Long parentId) {
        return getOne(Wrappers.lambdaQuery(new EduArea()).eq(EduArea::getParentId, parentId).like(EduArea::getName,
            name));
    }

    @Override
    public String getFullAreaNameById(Long areaId) {
        String fullName = "";
        EduArea area = getById(areaId);
        if (area != null) {
            if (area.getParentId() != null) {
                fullName = getFullAreaNameById(area.getParentId()) + area.getName();
            } else {
                fullName = area.getName();
            }
        }
        return fullName;
    }

    @Override
    public List<Long> findAreaParentId(Long areaId) {
        ArrayList<Long> list = new ArrayList<>();
        Long countyId = areaMapper.selectById(areaId).getParentId();
        Long cityId = areaMapper.selectById(countyId).getParentId();
        Long provinceId = areaMapper.selectById(cityId).getParentId();
        list.add(countyId);
        list.add(cityId);
        list.add(provinceId);
        return list;
    }

    @Override
    public CascadeAreaVO findAllAreaInfo(Long areaId) {

        // 街道
        EduArea street = this.getById(areaId);
        CascadeAreaVO streetVO = CascadeAreaVO.builder()
                .value(String.valueOf(street.getId()))
                .label(street.getName())
                .leaf("4")
                .build();
        // 县
        EduArea county = this.getById(street.getParentId());
        CascadeAreaVO countyVO = CascadeAreaVO.builder()
                .value(String.valueOf(county.getId()))
                .label(county.getName())
                .children(Collections.singletonList(streetVO))
                .leaf("3")
                .build();
        // 市
        EduArea city = this.getById(county.getParentId());
        city.setChildren(Collections.singletonList(county));
        CascadeAreaVO cityVO = CascadeAreaVO.builder()
                .value(String.valueOf(city.getId()))
                .label(city.getName())
                .children(Collections.singletonList(countyVO))
                .leaf("2")
                .build();
        // 省
        EduArea province = this.getById(city.getParentId());
        return CascadeAreaVO.builder()
                .value(String.valueOf(province.getId()))
                .label(province.getName())
                .children(Collections.singletonList(cityVO))
                .leaf("1")
                .build();
    }

    /**
     * 自动建树
     */
    private EduArea buildTree(EduArea parent, List<EduArea> city, List<EduArea> county, List<EduArea> town) {
        List<EduArea> list = parent.getType() == 0 ? city
            : parent.getType() == 1 ? county : town;
        parent.setChildren(CollUtil.isNotEmpty(list) ? list.stream().filter(x -> parent.getId().equals(x.getParentId()))
            .collect(Collectors.toList()) : null);
        if (CollUtil.isNotEmpty(parent.getChildren()) && parent.getType() != 2) {
            for (EduArea child : parent.getChildren()) {
                buildTree(child, city, county, town);
            }
        }
        return parent;
    }

    /**
     * 获取子节点
     */
    private List<EduArea> getChildrens(Long parentId, List<EduArea> list) {
        List<EduArea> childNodes = new ArrayList<>();
        for (EduArea area : list) {
            if (parentId.equals(area.getParentId())) {
                childNodes.add(area);
            }
        }
        return childNodes;
    }
}
