package com.zzsn.knowbase.service.impl;


import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzsn.knowbase.entity.*;
import com.zzsn.knowbase.mapper.KbAuthorizedUserMapper;
import com.zzsn.knowbase.mapper.KbKnowledgeProjectMapper;
import com.zzsn.knowbase.mapper.KbUserRoleMapMapper;
import com.zzsn.knowbase.service.*;
import com.zzsn.knowbase.util.SpringContextUtils;
import com.zzsn.knowbase.vo.Result;
import com.zzsn.knowbase.vo.UserKnowPermissionVo;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author obcy
 * @since 2024-01-04
 */
@Service
public class KbKnowledgeProjectServiceImpl extends ServiceImpl<KbKnowledgeProjectMapper, KbKnowledgeProject> implements KbKnowledgeProjectService {

    @Autowired
    KbAuthorizedUserService kbAuthorizedUserService;
    @Autowired
    KbKnowledgeProjectMapper kbKnowledgeProjectMapper;
    @Autowired
    KbAuthuserKnowledgeprojectMapService authuserKnowledgeprojectMapService;
    @Autowired
    KbAuthuserKnowMapService kbAuthuserKnowMapService;
    @Autowired
    KbUserRoleMapService kbUserRoleMapService;
    @Autowired
    KbUserRoleMapMapper userRoleMapMapper;
    @Autowired
    private KbAuthuserKnowMapService authuserKnowMapService;
    @Autowired
    KbRolePermissionMapService rolePermissionMapService;
    @Autowired
    KbPermissionsService permissionsService;
    @Autowired
    KbRoleService roleService;
    @Autowired
    KbAuthorizedUserMapper authorizedUserMapper;
    @Override
    @Transactional
    public Result<?> add(KbKnowledgeProject knowledgeProject) {
        if (StringUtils.isBlank(knowledgeProject.getPid())){
            knowledgeProject.setPid(KbKnowledgeProjectService.ROOT_PID_VALUE);
        }else {
            KbKnowledgeProject parent = super.getById(knowledgeProject.getPid());
            if(parent!=null && !KbKnowledgeProjectService.HASCHILD.equals(parent.getHasChild())){
                parent.setHasChild(KbKnowledgeProjectService.HASCHILD);
                super.updateById(parent);
            }
        }
        knowledgeProject.setStatus(0);
        knowledgeProject.setHasChild(KbKnowledgeProjectService.NOCHILD);
        /**第一次保存赋默认值*/
        knowledgeProject.setFullPath("0");
        knowledgeProject.setCreateTime(new Date());
        super.save(knowledgeProject);
        if (KbKnowledgeProjectService.ROOT_PID_VALUE.equals(knowledgeProject.getPid())){
            knowledgeProject.setFullPath(knowledgeProject.getId());
        }else {
            KbKnowledgeProject parent = super.getById(knowledgeProject.getPid());
            knowledgeProject.setFullPath(parent.getFullPath() +","+ knowledgeProject.getId());
        }
        super.updateById(knowledgeProject);
        return Result.OK();
    }

    public List<KbAuthuserKnowledgeprojectMap> getUserKnowProjectMapByUserId(String userId){
        //用户所拥有权限的知识库分类集合
        List<KbAuthuserKnowledgeprojectMap> list = authuserKnowledgeprojectMapService.list(Wrappers.<KbAuthuserKnowledgeprojectMap>lambdaQuery().eq(KbAuthuserKnowledgeprojectMap::getAuthUserId, userId));
        List<KbAuthuserKnowMap> list1 = kbAuthuserKnowMapService.list(Wrappers.<KbAuthuserKnowMap>lambdaQuery().eq(KbAuthuserKnowMap::getAuthUserId, userId));
        return list;
    }

    @Override
    @Transactional
    public Result<?> edit(KbKnowledgeProject knowledgeProject) {
        KbKnowledgeProject byId = super.getById(knowledgeProject.getId());
        if (ObjectUtils.isEmpty(byId)){
            return Result.error("未找到对应的知识库分类id");
        }
        String oldPid = byId.getPid();
        String newPid = knowledgeProject.getPid();
        if(!oldPid.equals(newPid)) {
            /**处理之前父节点的hasChild字段*/
            updateOldParentNode(oldPid);

            if(StringUtils.isBlank(newPid) || KbKnowledgeProjectService.ROOT_PID_VALUE.equals(newPid)){
                knowledgeProject.setPid(KbKnowledgeProjectService.ROOT_PID_VALUE);
                newPid = knowledgeProject.getPid();
            }
            /**处理新的父节点的hasChild字段*/
            if(!KbKnowledgeProjectService.ROOT_PID_VALUE.equals(knowledgeProject.getPid())) {
                super.update(Wrappers.<KbKnowledgeProject>lambdaUpdate().set(KbKnowledgeProject::getHasChild,KbKnowledgeProjectService.HASCHILD).eq(KbKnowledgeProject::getId,newPid));
            }
            knowledgeProject.setUpdateTime(new Date());
            super.updateById(knowledgeProject);


            /**处理本节点的所有子节点的绝对路径*/
            List<KbKnowledgeProject> list = super.list(Wrappers.<KbKnowledgeProject>lambdaQuery().like(KbKnowledgeProject::getFullPath,knowledgeProject.getId()));
            if (CollectionUtil.isNotEmpty(list)){
                String finalNewPid = newPid;
                if (!KbKnowledgeProjectService.ROOT_PID_VALUE.equals(finalNewPid)) {
                    /**非根节点 移动到其他非根节点*/
                    KbKnowledgeProject projectPid = super.getById(finalNewPid);

                    if (!KbKnowledgeProjectService.ROOT_PID_VALUE.equals(oldPid)) {
                        String id = knowledgeProject.getId();
                        String fullPath = knowledgeProject.getFullPath();
                        String replace = fullPath.replace(id, "");

                        list.forEach(e->{
                            e.setFullPath(projectPid.getFullPath()+"," + e.getFullPath().replace(replace, ""));
                        });
                    }else {
                        /**根节点 移动到其他非根节点*/
                        list.forEach(e->{
                            e.setFullPath(projectPid.getFullPath()+","+e.getFullPath());
                        });
                    }
                }else {
                    String id = knowledgeProject.getId();
                    String fullPath = knowledgeProject.getFullPath();
                    String replace = fullPath.replace(id, "");
                    /**移动到根节点*/
                    list.forEach(e->{
                        e.setFullPath(e.getFullPath().replace(replace, ""));
                    });
                }
            }
            super.updateBatchById(list);
        }else {
            knowledgeProject.setUpdateTime(new Date());
            super.updateById(knowledgeProject);
        }
        return Result.OK();

    }

    @Override
    public Result<?> del(String id) {
        KbKnowledgeProject byId = super.getById(id);
        super.remove(Wrappers.<KbKnowledgeProject>lambdaQuery().like(KbKnowledgeProject::getFullPath,id));
        if (StringUtils.isNotBlank(byId.getPid())&&!KbKnowledgeProjectService.ROOT_PID_VALUE.equals(byId.getPid())){
            updateOldParentNode(byId.getPid());
        }
        return Result.OK();
    }

    @Override
    public Result<?> lists(String sign, String projectId, String category) {

        KbAuthorizedUser userInfo = SpringContextUtils.getUserInfo();

        if (0 == userInfo.getIsAll()) {
            List<KbKnowledgeProject> kbKnowledgeProjects ;
            if ("1".equals(sign)&&"0".equals(projectId)){
                kbKnowledgeProjects = super.list(Wrappers.<KbKnowledgeProject>lambdaQuery()
                        .eq(KbKnowledgeProject::getPid, KbKnowledgeProjectService.ROOT_PID_VALUE)
                        .eq(StrUtil.isNotBlank(category),KbKnowledgeProject::getCategory,category));
            }else {
                kbKnowledgeProjects = super.list(Wrappers.<KbKnowledgeProject>lambdaQuery()
                        .eq(KbKnowledgeProject::getPid,projectId)
                        .eq(StrUtil.isNotBlank(category),KbKnowledgeProject::getCategory,category));
            }


            List<KbRole> list = roleService.list(Wrappers.<KbRole>lambdaQuery().eq(KbRole::getId, userInfo.getRoleId()));
            List<KbRolePermissionMap> permissionMaps = rolePermissionMapService.list(Wrappers.<KbRolePermissionMap>lambdaQuery().in(KbRolePermissionMap::getRoleId, list.stream().map(KbRole::getId).collect(Collectors.toList())));
            List<KbPermissions> permissions = permissionsService.list(Wrappers.<KbPermissions>lambdaQuery().in(KbPermissions::getId, permissionMaps.stream().map(KbRolePermissionMap::getPermissionId).collect(Collectors.toList())));

            kbKnowledgeProjects.forEach(e -> {
                e.setRoles(list);
                e.setPermissions(permissions);
            });
            //查询此用户，在其他节点有无特殊权限
            List<UserKnowPermissionVo> res = authorizedUserMapper.getUserPermission(userInfo.getId());
            List<UserKnowPermissionVo> collect = res.stream().filter(f -> !"0".equals(f.getKnowledgeProjectId())).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(collect)){
                //其他节点有额外权限
                kbKnowledgeProjects.forEach(e -> {
                    List<UserKnowPermissionVo> collect1 = collect.stream().filter(f -> f.getKnowledgeProjectId().equals(e.getId())).collect(Collectors.toList());
                    if (CollectionUtil.isNotEmpty(collect1)){
                        Map<String, List<UserKnowPermissionVo>> collect2 = collect1.stream().collect(Collectors.groupingBy(UserKnowPermissionVo::getRoleId));
                        List<KbRole> roles = new ArrayList<>();
                        List<KbPermissions> permissionsList = new ArrayList<>();

                        collect2.forEach((key,v)->{
                            KbRole kbRole = new KbRole();
                            kbRole.setRoleCode(v.get(0).getRoleCode());
                            kbRole.setRoleName(v.get(0).getRoleName());
                            kbRole.setId(key);
                            roles.add(kbRole);

                            v.forEach(p -> {
                                KbPermissions kbPermission = new KbPermissions();
                                kbPermission.setId(p.getPermissionId());
                                kbPermission.setPermissionCode(p.getPermissionCode());
                                kbPermission.setPermissionName(p.getPermissionName());
                                permissionsList.add(kbPermission);
                            });
                        });

                        e.setRoles(roles);
                        e.setPermissions(permissionsList);
                    }
                });
            }
            return Result.OK(kbKnowledgeProjects);

        }else {
            List<KbKnowledgeProject> kbKnowledgeProjects ;
            String userId = userInfo.getId();

            List<KbAuthuserKnowledgeprojectMap> list = authuserKnowledgeprojectMapService.list(Wrappers.<KbAuthuserKnowledgeprojectMap>lambdaQuery()
                    .eq(KbAuthuserKnowledgeprojectMap::getAuthUserId, userId)
            );
            List<KbKnowledgeProject> allknowProjectPermissId = super.list(Wrappers.<KbKnowledgeProject>lambdaQuery()
                    .in(KbKnowledgeProject::getId, list.stream().map(KbAuthuserKnowledgeprojectMap::getKnowledgeProjectId).collect(Collectors.toList()))
            );
            //查询出所有需要展示的节点
            Set<String> hasViewId = new HashSet<>();
            allknowProjectPermissId.forEach(e -> {
                Arrays.asList(e.getFullPath().split(",")).forEach(ee->{
                    hasViewId.add(ee);
                });
            });

            if ("1".equals(sign)&&StringUtils.isBlank(projectId)){

                kbKnowledgeProjects = super.list(Wrappers.<KbKnowledgeProject>lambdaQuery()
                        .eq(KbKnowledgeProject::getPid, KbKnowledgeProjectService.ROOT_PID_VALUE)
                        .eq(StrUtil.isNotBlank(category),KbKnowledgeProject::getCategory,category)
                        .in(KbKnowledgeProject::getId,hasViewId));
            }else {

                kbKnowledgeProjects = super.list(Wrappers.<KbKnowledgeProject>lambdaQuery()
                        .eq(KbKnowledgeProject::getPid,projectId)
                        .eq(StrUtil.isNotBlank(category),KbKnowledgeProject::getCategory,category)
                        .in(KbKnowledgeProject::getId,hasViewId));
            }
            //查询用户在每个节点对应的权限
            List<UserKnowPermissionVo> res = authorizedUserMapper.getUserPermission(userInfo.getId());

            kbKnowledgeProjects.forEach(e->{

                List<UserKnowPermissionVo> collect1 = res.stream().filter(f -> f.getKnowledgeProjectId().equals(e.getId())).collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(collect1)){
                    Map<String, List<UserKnowPermissionVo>> collect2 = collect1.stream().collect(Collectors.groupingBy(UserKnowPermissionVo::getRoleId));
                    List<KbRole> roles = new ArrayList<>();
                    List<KbPermissions> permissionsList = new ArrayList<>();

                    collect2.forEach((key,v)->{
                        KbRole kbRole = new KbRole();
                        kbRole.setRoleCode(v.get(0).getRoleCode());
                        kbRole.setRoleName(v.get(0).getRoleName());
                        kbRole.setId(key);
                        roles.add(kbRole);

                        v.forEach(p -> {
                            KbPermissions kbPermission = new KbPermissions();
                            kbPermission.setId(p.getPermissionId());
                            kbPermission.setPermissionCode(p.getPermissionCode());
                            kbPermission.setPermissionName(p.getPermissionName());
                            permissionsList.add(kbPermission);
                        });
                    });

                    e.setRoles(roles);
                    e.setPermissions(permissionsList);
                }
            });
            return Result.OK(kbKnowledgeProjects);
        }
    }

    private Set<String> getHasPermissId(String userId) {

        List<KbAuthuserKnowledgeprojectMap> list = authuserKnowledgeprojectMapService.list(Wrappers.<KbAuthuserKnowledgeprojectMap>lambdaQuery()
                .eq(KbAuthuserKnowledgeprojectMap::getAuthUserId, userId)
        );
        List<KbKnowledgeProject> list1 = super.list(Wrappers.<KbKnowledgeProject>lambdaQuery()
                .in(KbKnowledgeProject::getId, list.stream().map(KbAuthuserKnowledgeprojectMap::getKnowledgeProjectId).collect(Collectors.toList()))
        );
        Set<String> hasPermissId = new HashSet<>();
        list1.forEach(e -> {
            Arrays.asList(e.getFullPath().split(",")).forEach(ee->{
                hasPermissId.add(ee);
            });
        });
        return hasPermissId;
    }

    @Override
    public List<KbKnowledgeProject> getTreeListBy(String id) {
        return baseMapper.selectList(new LambdaQueryWrapper<KbKnowledgeProject>()
                .like(!"0".equals(id),KbKnowledgeProject::getFullPath, id)
        );
    }

    @Override
    public List<String> getKnowledgeListByUserId(String userId,List<String> knowProjectIdList) {
        return authuserKnowMapService.list(new LambdaQueryWrapper<KbAuthuserKnowMap>()
                .in(KbAuthuserKnowMap::getKnowledgeProjectId,knowProjectIdList)
                .eq(KbAuthuserKnowMap::getAuthUserId,userId))
                .stream().map(KbAuthuserKnowMap::getKnowledgeId)
                .collect(Collectors.toList());

    }

    @Override
    public List<KbAuthuserKnowledgeprojectMap> getKnowledgeProjectListByUserId(String userId) {
        return authuserKnowledgeprojectMapService.list(new LambdaQueryWrapper<KbAuthuserKnowledgeprojectMap>()
                .eq(KbAuthuserKnowledgeprojectMap::getAuthUserId,userId));
    }

    /**
     * 根据所传pid查询旧的父级节点的子节点并修改相应状态值
     * @param pid
     */
    private void updateOldParentNode(String pid) {
        if(!KbKnowledgeProjectService.ROOT_PID_VALUE.equals(pid)) {
            Integer count = baseMapper.selectCount(Wrappers.<KbKnowledgeProject>lambdaQuery().eq(KbKnowledgeProject::getPid,pid));
            if(count==null || count<=1) {
                super.update(Wrappers.<KbKnowledgeProject>lambdaUpdate().set(KbKnowledgeProject::getHasChild,KbKnowledgeProjectService.NOCHILD).eq(KbKnowledgeProject::getId,pid));
            }
        }
    }
}
