package com.njcn.product.system.dept.service.impl;

import cn.hutool.core.bean.BeanUtil;
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.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.common.pojo.constant.BizParamConstant;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.exception.BusinessException;

import com.njcn.product.system.dept.mapper.AreaMapper;
import com.njcn.product.system.dept.pojo.dto.AreaTreeDTO;
import com.njcn.product.system.dept.pojo.param.AreaParam;
import com.njcn.product.system.dept.pojo.po.Area;
import com.njcn.product.system.dept.pojo.vo.AreaTreeVO;
import com.njcn.product.system.dept.service.IAreaService;
import com.njcn.product.system.dict.enums.SystemResponseEnum;
import com.njcn.web.factory.PageFactory;
import com.njcn.web.utils.RequestUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

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

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hongawen
 * @since 2021-12-13
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class AreaServiceImpl extends ServiceImpl<AreaMapper, Area> implements IAreaService {


    @Override
    public Page<Area> listDictData(AreaParam.QueryParam queryParam) {
        QueryWrapper<Area> queryWrapper = new QueryWrapper<>();
        if (ObjectUtil.isNotNull(queryParam)) {
            //查询参数不为空，进行条件填充
            if (StrUtil.isNotBlank(queryParam.getSearchValue())) {
                //部门根据名称模糊查询
                queryWrapper
                        .and(param -> param.like("sys_area.name", queryParam.getSearchValue()));
            }
        }
        queryWrapper.ne("sys_area.state", DataStateEnum.DELETED.getCode());
        queryWrapper.ge("sys_area.type", queryParam.getType());
        //初始化分页数据
        return this.baseMapper.selectPage(new Page<>(PageFactory.getPageNum(queryParam), PageFactory.getPageSize(queryParam)), queryWrapper);
    }

    @Override
    public Area selectIdArea(String id) {
        return this.baseMapper.selectById(id);
    }

    @Override
    public List<Area> selectAreaByList(List<String> list) {
        return this.lambdaQuery().in(Area::getId, list).list();
    }

    @Override
    public List<Area> selectPid(List<String> ids) {
        return this.baseMapper.selectPid(ids, DataStateEnum.ENABLE.getCode());
    }


//    @Override
//    public List<AreaTreeVO> areaTree(String id, Integer type) {
//        List<AreaTreeVO> areaTreeVOList;
//        if (StrUtil.isBlank(id)) {
//            /*
//             * 用于首次访问区域。此处需要获取当前用户所绑定的部门下的行政区域id
//             * 现在默认为0
//             */
//            id = deptFeignClient.getAreaIdByDeptId(RequestUtil.getDeptIndex()).getData();
//        }
//        List<AreaTreeVO> areaTreeVOS;
//        if (type == 1) {
//            areaTreeVOList = this.baseMapper.getAreaIdTree(type, DataStateEnum.ENABLE.getCode());
//            List<AreaTreeVO> finalAreaTreeVOList = areaTreeVOList;
//            areaTreeVOS = areaTreeVOList.stream().filter(deptTreeVO ->
//                    BizParamConstant.PARENT_ID.equals(deptTreeVO.getPid())
//            ).peek((deptFirst) -> {
//                //map映射方法改变结果，调用getChildren()方法，把一级部门deptFirst和所有数据allDept作为参数传递，查询所有下级部门
//                deptFirst.setChildren(getChildren(deptFirst, finalAreaTreeVOList));
//            }).collect(Collectors.toList());
//        } else {
//            areaTreeVOS = this.baseMapper.getAreaTree(id, type, DataStateEnum.ENABLE.getCode());
//        }
//        return areaTreeVOS;
//    }

    /**
     * 递归查找所有企业的下级
     */
    private List<AreaTreeVO> getChildren(AreaTreeVO areaTreeVO, List<AreaTreeVO> allArea) {
        return allArea.stream().filter(area -> {
            //在全部数据中，找到和一级部门deptFirst的valueId相等的parentId
            return area.getPid().equals(areaTreeVO.getId());
        }).peek(deptId -> {
            //递归查询找到下级部门
            deptId.setChildren(getChildren(deptId, allArea));
        }).collect(Collectors.toList());
    }

    @Override
    public boolean addAreaParam(AreaParam areaParam) {
        checkAreaCode(areaParam, false);
        Area area = new Area();
        BeanUtil.copyProperties(areaParam, area);
        if (BizParamConstant.PARENT_ID.equals(areaParam.getPid())) {
            //上层节点
            area.setPids(BizParamConstant.PARENT_ID);
        } else {
            String pids = StrUtil.COMMA + areaParam.getPid();
            String pid = this.baseMapper.getIdString(area.getPid());
            //上层节点
            area.setPids(pid + pids);
        }
        //默认为正常状态
        area.setState(DataStateEnum.ENABLE.getCode());
        return this.save(area);
    }

    @Override
    public boolean updateArea(AreaParam.AreaUpdateParam updateParam) {
        checkAreaCode(updateParam, true);
        Area area = new Area();
        if (BizParamConstant.PARENT_ID.equals(updateParam.getPid())) {
            //上层节点
            area.setPids(BizParamConstant.PARENT_ID);
        } else {
            String pids = StrUtil.COMMA + updateParam.getPid();
            String pid = this.baseMapper.getIdString(area.getPid());
            //上层节点
            area.setPids(pid + pids);
        }
        BeanUtil.copyProperties(updateParam, area);
        return this.updateById(area);
    }

    @Override
    public boolean deleteArea(List<String> ids) {
        /*
         * 查询子节点
         */
        List<Area> list = this.baseMapper.selectPid(ids, DataStateEnum.ENABLE.getCode());
        /*
         * 将子节点叶添加到需要删除中
         */
        if (!list.isEmpty()) {
            for (Area area : list) {
                ids.add(area.getId());
            }
        }
        return this.lambdaUpdate().set(Area::getState, DataStateEnum.DELETED.getCode()).in(Area::getId, ids).update();
    }



//    @Override
//    public List<AreaTreeDTO> areaDeptTree(String id, Integer type) {
//        List<AreaTreeDTO> areaTreeVOList;
//        List<AreaTreeDTO> areaTreeVOS;
//        if (StrUtil.isBlank(id)) {
//            /*
//             * 用于首次访问区域。此处需要获取当前用户所绑定的部门下的行政区域id
//             * 现在默认为0
//             */
//            id = deptFeignClient.getAreaIdByDeptId(RequestUtil.getDeptIndex()).getData();
//        }
//        areaTreeVOList = this.baseMapper.getAreaDeptTree(id,type, DataStateEnum.ENABLE.getCode());
//        List<AreaTreeDTO> finalAreaTreeVOList = areaTreeVOList;
//        String finalId = id;
//        areaTreeVOS = areaTreeVOList.stream().filter(deptTreeVO ->
//                deptTreeVO.getPid().equals(finalId)
//        ).peek((deptFirst) -> {
//            //map映射方法改变结果，调用getChildren()方法，把一级部门deptFirst和所有数据allDept作为参数传递，查询所有下级部门
//            deptFirst.setChildren(getChildren(deptFirst, finalAreaTreeVOList));
//        }).collect(Collectors.toList());
//
//        return areaTreeVOS;
//    }

    @Override
    public Area areaPro(String id, Integer type) {
        QueryWrapper<Area> areaQueryWrapper = new QueryWrapper<>();
        areaQueryWrapper.eq("sys_area.id", id);
        areaQueryWrapper.eq("sys_area.type", type);
        areaQueryWrapper.eq("sys_area.state", DataStateEnum.ENABLE.getCode());
        Area area = this.baseMapper.selectOne(areaQueryWrapper);
        if (BizParamConstant.PARENT_ID.equals(area.getId()) || BizParamConstant.PARENT_ID.equals(area.getPid())) {
            return area;
        }else{
            id = area.getPid();
            area = areaPro(id, type);
        }
        return area;
    }

    @Override
    public Area areaDeptPro(String id) {
        Area areaDetail = this.baseMapper.areaDeptProDetail(id);
        return areaPro(areaDetail.getId(),areaDetail.getType());
    }


//    @Override
//    public List<AreaTreeVO> getDeptIdAreaTree() {
//
//        //获取当前系统登录的部门信息
//        String areaId = deptFeignClient.getAreaIdByDeptId(RequestUtil.getDeptIndex()).getData();
//        List<AreaTreeVO> areaTreeVOS = this.baseMapper.getAreaAll();
//        return areaTreeVOS.stream().filter(areaTreeVO ->
//                areaTreeVO.getId().equals(areaId)
//        ).peek((areaFirst) -> {
//            //map映射方法改变结果，调用getChildren()方法，把一级部门deptFirst和所有数据allDept作为参数传递，查询所有下级部门
//            areaFirst.setChildren(getChildren(areaFirst, areaTreeVOS));
//        }).collect(Collectors.toList());
//    }

    @Override
    public Area selectAreaByName(String name) {
        LambdaQueryWrapper<Area> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Area::getName, name);
        return this.baseMapper.selectOne(lambdaQueryWrapper);
    }

    /**
     * 递归查找所有企业的下级
     *
     */
    private List<AreaTreeDTO> getChildren(AreaTreeDTO areaTreeVO, List<AreaTreeDTO> allArea) {
        return allArea.stream().filter(area -> {
            //在全部数据中，找到和一级部门deptFirst的valueId相等的parentId
            return area.getPid().equals(areaTreeVO.getId());
        }).peek(deptId -> {
            //递归查询找到下级部门
            deptId.setChildren(getChildren(deptId, allArea));
        }).collect(Collectors.toList());
    }

    /**
     * 校验参数，检查是否存在相同编码的企业区域
     */
    private void checkAreaCode(AreaParam areaParam, boolean isExcludeSelf) {
        LambdaQueryWrapper<Area> dictTypeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        dictTypeLambdaQueryWrapper
                .eq(Area::getAreaCode, areaParam.getAreaCode())
                .eq(Area::getState, DataStateEnum.ENABLE.getCode());
        //更新的时候，需排除当前记录
        if (isExcludeSelf) {
            if (areaParam instanceof AreaParam.AreaUpdateParam) {
                dictTypeLambdaQueryWrapper.ne(Area::getId, ((AreaParam.AreaUpdateParam) areaParam).getId());
            }
        }
        int countByAccount = this.count(dictTypeLambdaQueryWrapper);
        //大于等于1个则表示重复
        if (countByAccount >= 1) {
            throw new BusinessException(SystemResponseEnum.AREA_CODE_REPEAT);
        }
    }

    @Override
    public List<AreaTreeVO> areaSelect() {
        List<AreaTreeVO> areaTreeVOS = this.baseMapper.getAreaAll();
        return areaTreeVOS.stream ( ).filter (temp ->BizParamConstant.PARENT_ID.equals(temp.getPid()))
                .peek((areaFirst) -> {
                    //map映射方法改变结果，调用getChildren()方法，把一级部门deptFirst和所有数据allDept作为参数传递，查询所有下级部门
                    areaFirst.setChildren (getChildren (areaFirst, areaTreeVOS));
                }).collect (Collectors.toList ( ));
    }

    @Override
    public List<Area> getPidAreaList(String areaId, Integer type) {
        List<Area> result = new ArrayList<>();
        Area area = this.getById(areaId);
        if(Objects.isNull(area)){
            return result;
        }
        if(BizParamConstant.PARENT_ID.equals(area.getId())){
            result.add(area);
        }else {
            LambdaQueryWrapper<Area> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(Area::getPid,area.getPid())
                    .eq(Area::getState,DataStateEnum.ENABLE.getCode()).eq(Area::getType,type).orderByAsc(Area::getAreaCode);
            result = this.list(lambdaQueryWrapper);
        }
        return result;
    }

}
