package jnpf.attendance.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import jnpf.attendance.mapper.PermissionDictMapper;
import jnpf.attendance.service.AttendancePermissionDictService;
import jnpf.entity.PermissionDict;
import jnpf.exception.HandleException;
import jnpf.model.attendance.dto.SavePermissionDto;
import jnpf.model.attendance.vo.PermissionDictVo;
import jnpf.util.JsonUtil;
import jnpf.util.RandomUtil;
import jnpf.util.UserProvider;
import jnpf.util.mapper.MybatisUtil;
import org.springframework.stereotype.Service;

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

/**
 * 考勤权限字典
 */
@Service
public class AttendancePermissionDictServiceImpl implements AttendancePermissionDictService {

    @Resource
    private PermissionDictMapper permissionDictMapper;

    @Override
    public void save(SavePermissionDto savePermissionDto) throws HandleException {
        PermissionDict byName = findByName(savePermissionDto.getName(), savePermissionDto.getModuleType());
        PermissionDict permissionDict = JsonUtil.getJsonToBean(savePermissionDto, PermissionDict.class);
        if (savePermissionDto.getId() == null) {
            //新增
            if (byName != null) {
                throw new HandleException("该数据已存在");
            }
            permissionDict.setId(RandomUtil.uuId());
            permissionDict.setCreatorTime(new Date());
            permissionDict.setCreatorUserId(UserProvider.getLoginUserId());
            permissionDictMapper.insert(permissionDict);
            return;
        }
        if (byName != null && !byName.getId().equals(permissionDict.getId())) {
            throw new HandleException("该数据已存在");
        }
        permissionDict.setLastModifyTime(new Date());
        permissionDict.setLastModifyUserId(UserProvider.getLoginUserId());
        permissionDictMapper.updateById(permissionDict);
    }

    @Override
    public List<PermissionDictVo> queryPermissionDictList(Integer moduleType) {
//        List<PermissionDict> permissionDictList = MybatisUtil.findListByFiled(permissionDictMapper, PermissionDict::getModuleType, moduleType, true);
        QueryWrapper<PermissionDict> curQueryWrapper = new QueryWrapper<>();
        curQueryWrapper.lambda()
                .eq(PermissionDict::getModuleType, 1);
        List<PermissionDict> curPermissionList = permissionDictMapper.selectList(curQueryWrapper);
        List<PermissionDictVo> curVoList = treeGroupVo(curPermissionList);
        QueryWrapper<PermissionDict> childQueryWrapper = new QueryWrapper<>();
        childQueryWrapper.lambda()
                .eq(PermissionDict::getModuleType, 2);
        List<PermissionDict> childPermissionList = permissionDictMapper.selectList(childQueryWrapper);
        List<PermissionDictVo> childVoList = treeGroupVo(childPermissionList);
        curVoList.addAll(childVoList);
        return curVoList;
    }

    @Override
    public void delete(String id) {
        PermissionDict permissionDict = permissionDictMapper.selectById(id);
        List<String> deleteIds = new ArrayList<>();
        deleteIds.add(permissionDict.getId());
        recursionDeleteChild(permissionDict.getId(), deleteIds);
        UpdateWrapper<PermissionDict> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda()
                .in(PermissionDict::getId, deleteIds);
        PermissionDict delete = new PermissionDict();
        delete.setDeleteMark(1);
        permissionDictMapper.update(delete, updateWrapper);
    }

    @Override
    public PermissionDict detail(String id) {
        return permissionDictMapper.selectById(id);
    }

    private void recursionDeleteChild(String id, List<String> deleteIds) {
        List<PermissionDict> permissionDictList = MybatisUtil.findListByFiled(permissionDictMapper, PermissionDict::getParent, id, true);
        if (CollectionUtil.isEmpty(permissionDictList)) {
            return;
        }
        List<String> deleteIdList = permissionDictList.stream().map(PermissionDict::getId).collect(Collectors.toList());
        deleteIds.addAll(deleteIdList);
        for (PermissionDict permissionDict : permissionDictList) {
            recursionDeleteChild(permissionDict.getId(), deleteIds);
        }
    }

    private List<PermissionDictVo> treeGroupVo(List<PermissionDict> permissionDictList) {
        List<PermissionDictVo> allGroupList = JsonUtil.getJsonToList(permissionDictList, PermissionDictVo.class);
        List<PermissionDictVo> groupVoList = allGroupList.stream().filter(group -> {
            return group.getParent().equals("0");
        }).collect(Collectors.toList());
        return groupVoList.stream().peek(group -> group.setChild(recursiveQuery(group, allGroupList))).collect(Collectors.toList());
    }

    private List<PermissionDictVo> recursiveQuery(PermissionDictVo root, List<PermissionDictVo> permissionDictVoList) {
        if (CollectionUtil.isEmpty(permissionDictVoList)) {
            root.setChild(null);
        }
        List<PermissionDictVo> children = new ArrayList<>();
        permissionDictVoList.forEach(item -> {
            if (Objects.equals(item.getParent(), root.getId())) {
                item.setChild(recursiveQuery(item, permissionDictVoList));
                children.add(item);
            }
        });
        return children;
    }

    public PermissionDict findByName(String name, Integer moduleType) {
        QueryWrapper<PermissionDict> queryWrapper = new QueryWrapper<>();
        queryWrapper.
                eq("F_DeleteMark", 0)
                .lambda()
                .eq(PermissionDict::getName, name)
                .eq(PermissionDict::getType, moduleType);
        return permissionDictMapper.selectOne(queryWrapper);
    }
}
