package com.gitee.sop.admin.service.sys;

import com.gitee.sop.admin.common.support.ServiceSupport;
import com.gitee.sop.admin.common.util.CopyUtil;
import com.gitee.sop.admin.dao.entity.SysDept;
import com.gitee.sop.admin.dao.entity.SysUserDept;
import com.gitee.sop.admin.dao.mapper.SysDeptMapper;
import com.gitee.sop.admin.dao.mapper.SysUserDeptMapper;
import com.gitee.sop.admin.service.sys.dto.DeptUserResultDTO;
import com.gitee.sop.admin.service.sys.dto.SysDeptDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;


/**
 * @author 六如
 */
@Service
public class SysUserDeptService implements ServiceSupport<SysUserDept, SysUserDeptMapper> {

    @Autowired
    SysDeptMapper sysDeptMapper;

    public Map<Long, SysDeptDTO> getUserDeptId(Collection<Long> userIds) {
        Map<Long, SysDept> deptIdMap = sysDeptMapper.query()
                .map(SysDept::getId, Function.identity());
        return this.query()
                .in(SysUserDept::getUserId, userIds)
                .map(SysUserDept::getUserId, sysUserDept -> {
                    SysDept sysDept = deptIdMap.get(sysUserDept.getDeptId());
                    return CopyUtil.copyBean(sysDept, SysDeptDTO::new);
                }, (v1, v2) -> v2);
    }

    /**
     * 查找部门及子部门下所有用户
     *
     * @param deptId 部门
     * @return 返回空表示选中了根节点或没有选
     */
    public DeptUserResultDTO listDeptUserIdsDeep(Long deptId) {
        if (deptId == null) {
            return new DeptUserResultDTO(false, null);
        }
        SysDept sysDept = sysDeptMapper.getById(deptId);
        // 选中了根节点或没有选
        if (sysDept == null || Objects.equals(sysDept.getParentId(), 0L)) {
            return new DeptUserResultDTO(false, null);
        }
        List<Long> userIdsAll = new ArrayList<>();
        List<Long> userIds = this.query()
                .eq(SysUserDept::getDeptId, deptId)
                .listUniqueValue(SysUserDept::getUserId);

        appendChildren(userIdsAll, deptId);

        userIdsAll.addAll(userIds);
        return new DeptUserResultDTO(true, userIdsAll);
    }

    private void appendChildren(List<Long> userIdsAll, Long deptId) {
        List<Long> deptIds = sysDeptMapper.query()
                .eq(SysDept::getParentId, deptId)
                .listUniqueValue(SysDept::getId);
        if (deptIds.isEmpty()) {
            return;
        }
        List<Long> userIds = this.query()
                .in(SysUserDept::getDeptId, deptIds)
                .listUniqueValue(SysUserDept::getUserId);
        userIdsAll.addAll(userIds);

        for (Long childDeptId : deptIds) {
            appendChildren(userIdsAll, childDeptId);
        }
    }

    /**
     * 保存用户部门
     *
     * @param userId  用户id
     * @param deptIds 部门id
     * @return 返回影响行数
     */
    public int saveUserDept(Long userId, List<Long> deptIds) {
        this.query()
                .eq(SysUserDept::getUserId, userId)
                .delete();

        if (CollectionUtils.isEmpty(deptIds)) {
            return 0;
        }

        List<SysUserDept> saveList = deptIds.stream()
                .map(deptId -> {
                    SysUserDept sysUserDept = new SysUserDept();
                    sysUserDept.setUserId(userId);
                    sysUserDept.setDeptId(deptId);
                    return sysUserDept;
                })
                .collect(Collectors.toList());

        return this.saveBatch(saveList);
    }


}
