package com.tuoheng.admin.service.dept.add;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tuoheng.admin.constant.SystemConstant;
import com.tuoheng.admin.dto.RoadSectionDto;
import com.tuoheng.admin.entity.*;
import com.tuoheng.admin.enums.MarkEnum;
import com.tuoheng.admin.enums.code.dept.AddDeptCodeEnum;
import com.tuoheng.admin.mapper.DeptMapper;
import com.tuoheng.admin.mapper.RoadDeptMapper;
import com.tuoheng.admin.mapper.SectionDeptMapper;
import com.tuoheng.admin.mapper.UserMapper;
import com.tuoheng.admin.request.dept.AddDeptRequest;
import com.tuoheng.admin.utils.CurrentUserUtil;
import com.tuoheng.common.core.utils.DateUtils;
import com.tuoheng.common.core.utils.JsonResult;
import com.tuoheng.common.core.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 添加部门业务层处理
 *
 * @author wanjing
 * @team tuoheng
 * @date 2022-11-17
 */
@Slf4j
@Service
public class AddDeptService {

    @Autowired
    private DeptMapper deptMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoadDeptMapper roadDeptMapper;

    @Autowired
    private SectionDeptMapper sectionDeptMapper;

    /**
     * 添加部门数据
     *
     * @return
     */
    public JsonResult add(AddDeptRequest addDeptRequest) {
        log.info("进入添加部门业务接口");
        User user = CurrentUserUtil.getUserInfo();
        String userId = user.getId();
        String tenantId = user.getTenantId();
        JsonResult result = this.check(tenantId, addDeptRequest);
        if (0 != result.getCode()) {
            log.info("添加部门业务接口：校验失败：{}", result.getMsg());
            return result;
        }

        Dept dept = new Dept();
        dept.setTenantId(tenantId);
        dept.setName(addDeptRequest.getName());
        dept.setPid(addDeptRequest.getPid());
        dept.setCreateUser(CurrentUserUtil.getUserId());
        dept.setCreateTime(DateUtils.now());
        Integer rowId = deptMapper.insert(dept);
        log.info("新增部门, 返回结果: deptId={}", dept.getId());

        if (rowId <= 0) {
            log.info("添加部门业务接口：添加部门失败：{}", result.getMsg());
            return JsonResult.error(AddDeptCodeEnum.ADD_DEPT_IS_FAILED.getCode(), AddDeptCodeEnum.ADD_DEPT_IS_FAILED.getMsg());
        }

        this.updateSuperAdminUser(userId, tenantId, dept);

        // 新增公路/路段与部门数据
        this.addRoadAndSectionToDept(tenantId, dept.getId(), addDeptRequest.getRoadSectionDtoList());

        log.info("添加部门业务接口：添加部门成功：{}");
        return JsonResult.success(dept);
    }

    /**
     * 检查参数
     *
     * @param tenantId
     * @param addDeptRequest
     * @return
     */
    private JsonResult check(String tenantId, AddDeptRequest addDeptRequest) {
        if (null == addDeptRequest.getPid()) {
            return JsonResult.error(AddDeptCodeEnum.DEPT_PID_IS_NULL.getCode(), AddDeptCodeEnum.DEPT_PID_IS_NULL.getMsg());
        }

        if (StringUtils.isEmpty(addDeptRequest.getName())) {
            return JsonResult.error(AddDeptCodeEnum.DEPT_NAME_IS_NULL.getCode(), AddDeptCodeEnum.DEPT_NAME_IS_NULL.getMsg());
        }

        if (SystemConstant.ROOT_DEPT_PID.equals(addDeptRequest.getPid())) {
            Integer count = deptMapper.selectCount(new LambdaQueryWrapper<Dept>()
                    .eq(Dept::getTenantId, tenantId)
                    .eq(Dept::getPid, addDeptRequest.getPid())
                    .eq(Dept::getMark, MarkEnum.VALID.getCode()));

            // 顶级部门只能创建一个
            if (count > 0) {
                return JsonResult.error(AddDeptCodeEnum.ROOT_DEPT_IS_EXIST.getCode(), AddDeptCodeEnum.ROOT_DEPT_IS_EXIST.getMsg());
            }
        } else {
            // 判断上级部门是否存在
            Integer count = deptMapper.selectCount(new LambdaQueryWrapper<Dept>()
                    .eq(Dept::getTenantId, tenantId)
                    .eq(Dept::getId, addDeptRequest.getPid())
                    .eq(Dept::getMark, MarkEnum.VALID.getCode()));
            if (count <= 0) {
                return JsonResult.error(AddDeptCodeEnum.PARENT_DEPT_IS_NOT_EXIST.getCode(), AddDeptCodeEnum.PARENT_DEPT_IS_NOT_EXIST.getMsg());
            }

            // 判断是否已存在该部门名称，同部门下，部门名称不能重复
            count = deptMapper.selectCount(new LambdaQueryWrapper<Dept>()
                    .eq(Dept::getTenantId, tenantId)
                    .eq(Dept::getPid, addDeptRequest.getPid())
                    .eq(Dept::getName, addDeptRequest.getName())
                    .eq(Dept::getMark, MarkEnum.VALID.getCode()));

            // 系统中已存在
            if (count > 0) {
                return JsonResult.error(AddDeptCodeEnum.DEPT_NAME_IS_ALREADY_EXIST.getCode(), AddDeptCodeEnum.DEPT_NAME_IS_ALREADY_EXIST.getMsg());
            }
        }

       if (CollectionUtil.isNotEmpty(addDeptRequest.getRoadSectionDtoList())) {
           List<Section> sectionList;
           List<RoadSectionDto> roadSectionDtoList = addDeptRequest.getRoadSectionDtoList();
           for (RoadSectionDto roadSectionDto : roadSectionDtoList) {
               sectionList = roadSectionDto.getSectionList();
               if (CollectionUtils.isEmpty(sectionList)) {
                   return JsonResult.error(AddDeptCodeEnum.SECTION_IS_NULL.getCode(), AddDeptCodeEnum.SECTION_IS_NULL.getMsg());
               }
           }
       }
        return JsonResult.success();
    }

    /**
     * 新增公路/路段与部门数据
     *
     * @param tenantId           租户Id
     * @param deptId             部门Id
     * @param roadSectionDtoList 公路/路段集合
     * @return 结果
     */
    private void addRoadAndSectionToDept(String tenantId, String deptId, List<RoadSectionDto> roadSectionDtoList) {
        if (CollectionUtil.isNotEmpty(roadSectionDtoList)) {
            log.info("新增部门公路/路段数据为空");
            return;
        }
        List<RoadInformation> roadInformationList = new ArrayList<>();
        List<Section> sectionList = new ArrayList<>();
        RoadInformation road;
        List<Section> sectionListTmp;
        for (RoadSectionDto roadSectionDto : roadSectionDtoList) {
            road = roadSectionDto.getRoad();
            sectionListTmp = roadSectionDto.getSectionList();
            roadInformationList.add(road);
            sectionList.addAll(sectionListTmp);
        }

        // 添加部门和公路数据
        // 去重，防止前端提交了重复的数据
        roadInformationList = roadInformationList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(RoadInformation::getId))), ArrayList::new));
        this.addRoadToDept(tenantId, deptId, roadInformationList);

        // 添加部门和路段数据
        // 去重，防止前端提交了重复的数据
        sectionList = sectionList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Section::getId))), ArrayList::new));
        this.addSectionToDept(tenantId, deptId, sectionList);
    }

    /**
     * 新增公路部门数据
     * 1、先删除原有记录数据
     * 2、新增此次提交的数据
     *
     * @param tenantId            租户Id
     * @param deptId              部门Id
     * @param roadInformationList 公路集合
     * @return 结果
     */
    private void addRoadToDept(String tenantId, String deptId, List<RoadInformation> roadInformationList) {
        List<String> roadIdList = roadInformationList.stream().map(o -> o.getId()).collect(Collectors.toList());
        Map<String, Object> map = new HashMap<>();
        map.put("tenantId", tenantId);
        map.put("deptId", deptId);
        map.put("roadIdList", roadIdList);
        roadDeptMapper.deleteBatchByMap(map);

        List<RoadDept> list = new ArrayList<>();
        RoadDept roadDept;
        for (RoadInformation roadInformation : roadInformationList) {
            Integer count = roadDeptMapper.selectCount(new LambdaQueryWrapper<RoadDept>()
                    .eq(RoadDept::getTenantId, tenantId)
                    .eq(RoadDept::getDeptId, deptId)
                    .eq(RoadDept::getRoadId, roadInformation.getId()));
            if (count > 0) {
                // 已经存在，不用在添加，防止出现冗余数据
                continue;
            }
            roadDept = new RoadDept();
            roadDept.setTenantId(tenantId);
            roadDept.setDeptId(deptId);
            roadDept.setRoadId(roadInformation.getId());
            list.add(roadDept);
        }

        if (!CollectionUtils.isEmpty(list)) {
            roadDeptMapper.insertBatch(list);
        }
    }

    /**
     * 新增路段部门数据
     * 1、先删除原有记录数据
     * 2、新增此次提交的数据
     *
     * @param tenantId    租户Id
     * @param deptId      部门Id
     * @param sectionList 路段集合
     * @return 结果
     */
    private void addSectionToDept(String tenantId, String deptId, List<Section> sectionList) {
        List<String> sectionIdList = sectionList.stream().map(o -> o.getId()).collect(Collectors.toList());
        Map<String, Object> map = new HashMap<>();
        map.put("tenantId", tenantId);
        map.put("deptId", deptId);
        map.put("sectionIdList", sectionIdList);
        sectionDeptMapper.deleteBatchByMap(map);
        List<SectionDept> list = new ArrayList<>();
        SectionDept sectionDept;
        for (Section section : sectionList) {
            Integer count = sectionDeptMapper.selectCount(new LambdaQueryWrapper<SectionDept>()
                    .eq(SectionDept::getTenantId, tenantId)
                    .eq(SectionDept::getDeptId, deptId)
                    .eq(SectionDept::getSectionId, section.getId()));
            if (count > 0) {
                // 已经存在，不用在添加，防止出现冗余数据
                continue;
            }

            sectionDept = new SectionDept();
            sectionDept.setTenantId(tenantId);
            sectionDept.setDeptId(deptId);
            sectionDept.setSectionId(section.getId());
            list.add(sectionDept);
        }
        if (!CollectionUtils.isEmpty(list)) {
            sectionDeptMapper.insertBatch(list);
        }
    }

    /**
     * 如果创建的是顶级部门，将该部门与超级管理员关联
     */
    private void updateSuperAdminUser(String userId, String tenantId, Dept dept) {
        if (!SystemConstant.ROOT_DEPT_PID.equals(dept.getPid())) {
            return;
        }
        List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>()
                .eq(User::getTenantId, tenantId)
                .eq(User::getRoleId, 1)
                .eq(User::getMark, MarkEnum.VALID.getCode()));
        if (CollectionUtils.isEmpty(userList)) {
            log.info("用户为空");
            return;
        }
        List<String> userIdList = userList.stream().map(o -> o.getId()).collect(Collectors.toList());
        Map<String, Object> map = new HashMap<>();
        map.put("deptId", dept.getId());
        map.put("idList", userIdList);
        map.put("updateUser", userId);
        map.put("updateTime", DateUtils.now());
        userMapper.updateDeptIdByIdList(map);
    }

}
