package jnpf.doclibrary.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import jnpf.base.ActionResult;
import jnpf.base.UserInfo;
import jnpf.doclibrary.mapper.InformationAuthorityMapper;
import jnpf.doclibrary.mapper.InformationLogMapper;
import jnpf.doclibrary.mapper.InformationMapper;
import jnpf.doclibrary.mapper.InformationRubbishMapper;
import jnpf.doclibrary.service.DocLibraryService;
import jnpf.doclibrary.service.SpaceService;
import jnpf.model.doclibrary.dto.FileQueryDto;
import jnpf.model.doclibrary.dto.InformationAuthorityDto;
import jnpf.model.doclibrary.dto.SpaceDto;
import jnpf.model.doclibrary.vo.InformationAuthorityVo;
import jnpf.model.doclibrary.vo.InformationVo;
import jnpf.permission.UserApi;
import jnpf.permission.V2UserApi;
import jnpf.permission.model.user.PartUserInfoVo;
import jnpf.permission.vo.v2.user.UserBoundVO;
import jnpf.util.FtbUtil;
import jnpf.util.UploaderUtil;
import jnpf.util.UserProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 资料库服务
 *
 * @author yanwenfu
 * @create 2023-07-20
 */
@Service
public class DocLibraryServiceImpl implements DocLibraryService {

    @Resource
    private InformationMapper informationMapper;
    @Resource
    private InformationLogMapper informationLogMapper;

    @Resource
    private InformationAuthorityMapper informationAuthorityMapper;

    @Resource
    private InformationRubbishMapper informationRubbishMapper;

    @Autowired
    private UserApi userApi;

    @Autowired
    private V2UserApi v2UserApi;

    @Resource
    private SpaceService spaceService;

    @Resource
    private UserProvider userProvider;

    @Override
    public List<InformationVo> relatedToMeFile(FileQueryDto fileQueryDto) {
        //得到企业下所有被标记为删除的id集合
        List<String> enabledMarkIds = informationMapper.getEnabledMarkInformation();
        List<InformationVo> informationVos = informationMapper.relatedToMeFile(fileQueryDto,enabledMarkIds);
        setOwnerNames(informationVos);
        return informationVos;
    }

    @Override
    public List<InformationVo> recentlyViewed(FileQueryDto fileQueryDto) {
        spaceService.deleteOverdueViewRecord();
        UserInfo userInfo = userProvider.get();
        //验证是否是超级管理员
//        Integer userModuleDataAuthorizesChem = userApi.getUserModuleDataAuthorizesChem("resource", userInfo.getUserId(), "information_admin");
        Boolean isAdministrator = userInfo.getIsAdministrator();
        //得到企业下所有被标记为删除的id集合
        List<String> enabledMarkIds = informationMapper.getEnabledMarkInformation();
        if (isAdministrator){
            //超级管理员拥有最高权限 跳过验证 看所有的不管是不是成员
            List<InformationVo> informationVos = informationMapper.recentlyViewed(fileQueryDto,enabledMarkIds);
            setOwnerNames(informationVos);
            return informationVos;
        }
        List<InformationVo> informationVos = informationMapper.recentlyViewedMember(fileQueryDto,enabledMarkIds);
        setOwnerNames(informationVos);
        return informationVos;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int rename(String id, FileQueryDto fileQueryDto) {
        //验证权限
        Integer integer = userPermissions(id);
        if (integer < 0 || integer >= 3){
            return -1;
        }
        //修改文件名称
        informationMapper.rename(id,fileQueryDto);
        InformationVo informationVo = informationMapper.getInformationById(id);
        addInformationLog(id,informationVo.getClassification(),fileQueryDto.getUserId(),fileQueryDto.getUserName(),"更新",null);
        return 0;
    }

    /**
     * 新增日志
     * @param informationId 文档/文件id
     * @param classification 文件类型 1.空间 2.文件夹 3.文档 4.文件
     * @param userId 用户id
     * @param userName 用户名称
     * @param action 动作
     * @param userNameList 被邀请人的名字列表
     */
    @Override
    public void addInformationLog(String informationId ,Integer classification ,String userId,String userName,String action,List<String> userNameList) {

        String typeName = null;
        if (3 == classification){
            typeName = "文档";
        }
        if (4 == classification){
            typeName = "文件";
        }
        if (null != typeName) {
            //张三创建了文档
            //张三更新了文档/文件
            //张三邀请赵利、王三、李四、...加入了此文件/文档
            //张三上传了文件/文档
            //新增日志
            String content;
            if ("邀请".equals(action)){
                StringBuilder userNames = null;
                for (String name : userNameList) {
                    if (null == userNames){
                        userNames = new StringBuilder(name);
                    }else {
                        userNames.append("、").append(name);
                    }
                }
                content = userName + action + userNames + "加入了此" + typeName;
            }else {
                content = userName + action + "了" + typeName;
            }
            informationLogMapper.addInformationLog(informationId, userId, action, content, FtbUtil.getId());
        }
    }

    @Override
    public boolean checkSpaceMember(String id) {
        UserInfo userInfo = userProvider.get();
        InformationVo informationById = informationMapper.getInformationById(id);
        if (null != informationById && informationById.getClassification() == 1) {
            //验证该id 是不是空间
            Integer integer = informationAuthorityMapper.checkSpaceMember(id, userInfo.getUserId());
            if (0 < integer) {
                return true;
            }
        }
        return false;
    }

    @Override
    public Integer exitSpaceButton(String id) {
        UserInfo userInfo = userProvider.get();
        //验证是否是超级管理员
//        Integer userModuleDataAuthorizesChem = userApi.getUserModuleDataAuthorizesChem("resource", userInfo.getUserId(), "information_admin");
        if (userInfo.getIsAdministrator()){
            //超级管理员拥有最高权限 跳过验证
            return 1;
        }
        InformationVo informationById = informationMapper.getInformationById(id);
        if (null != informationById && informationById.getClassification() == 1) {
            //验证该id 是不是空间
            InformationAuthorityVo informationAuthorityVo = informationAuthorityMapper.spaceMember(id, userInfo.getUserId());
            if (null != informationAuthorityVo) {
                if (0 == informationAuthorityVo.getLimitsOfAuthority()){
                    //是空间拥有者 展示解散空间按钮按
                    return 1;
                }
                // 是成员展示退出空间按钮
                return 2;
            }
        }
        //不是成员不展示
        return 0;
    }

    /**
     * 用户权限
     * @param informationId 空间/文件夹/文件id
     * @return 权限管理(0.超级管理员 1.管理员 2.可编辑 3.可上传下载 4.可下载 5.仅预览)
     */
    @Override
    public Integer userPermissions(String informationId ) {
        UserInfo userInfo = userProvider.get();
        //验证是否是超级管理员
//        Integer userModuleDataAuthorizesChem = userApi.getUserModuleDataAuthorizesChem("resource", userInfo.getUserId(), "information_admin");
        if (userInfo.getIsAdministrator()){
            //超级管理员拥有最高权限 跳过验证
            return 0;
        }

        InformationVo informationById = informationMapper.getInformationById(informationId);
        //获取当前文件的权限
        Integer informationAuthority = informationAuthorityMapper.getInformationAuthority(informationId,userInfo.getUserId());
        if (null == informationAuthority){
            //当本文件没有权限时 向上查找路径上的第一个有文件的权限 拥有该文件权限
           List<InformationAuthorityVo> informationAuthorityVoList = informationAuthorityMapper.getUpPathAuthority(informationId,userInfo.getUserId());
           if (null == informationAuthorityVoList || informationAuthorityVoList.isEmpty()){
               //所有上级都不是成员 向下找看看有没有有文件夹/文件是成员的
               Integer num = informationAuthorityMapper.getDownPathAuthority(informationId,userInfo.getUserId());
               //有 赋值为查看权
               if (0 < num){
                   return 5;
               }
               //没有 那么就没有权限
               return -1;
           }
           //找到最大的id
            List<String> list = new ArrayList<>(Arrays.asList(informationById.getFilePath().split(",")));
            Collections.reverse(list);
            outer : for (String s : list) {
                    for (InformationAuthorityVo informationAuthorityVo : informationAuthorityVoList) {
                        if (s.equals(informationAuthorityVo.getInformationId())) {
                            informationAuthority = informationAuthorityVo.getLimitsOfAuthority();
                            break outer;
                        }
                    }
                }
        }
        return informationAuthority;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteInformation(String id) {
        //验证权限
        Integer integer = userPermissions(id);
        if (integer < 0 || integer >= 3){
            return -1;
        }
        String userId = userProvider.get().getUserId();
        //删除文件
        informationMapper.delete(id,userId);
        //加入垃圾箱
        informationRubbishMapper.addRubbish(id,FtbUtil.getId(),userId);
        return 0;
    }

    @Override
    public List<InformationAuthorityVo> userList(String id) {
        List<InformationAuthorityVo> informationAuthorityVos = informationAuthorityMapper.getUserList(id);
        //赋值用户名称及头像
        List<String> userIds = informationAuthorityVos.stream().map(InformationAuthorityVo::getUserId).collect(Collectors.toList());
        // 查询成员信息
//        List<PartUserInfoVo> list = userApi.getInfoByIds(userIds);
        ActionResult<List<UserBoundVO>> userList = v2UserApi.getAllUserInfoBatch(userIds, null);
        Map<String, UserBoundVO> map = new HashMap<>();
        if (200 == userList.getCode() && CollectionUtil.isNotEmpty(userList.getData())) {
            map = userList.getData().stream().collect(Collectors.toMap(UserBoundVO::getId, a -> a, (k1, k2) -> k1));
        }
//        Map<String, PartUserInfoVo> map = list.stream().collect(Collectors.toMap(PartUserInfoVo::getUserId, Function.identity()));
        List<String> ids = new ArrayList<>();
        Map<String, UserBoundVO> finalMap = map;
        informationAuthorityVos.forEach(v -> {
//            PartUserInfoVo user = map.get(v.getUserId());
            UserBoundVO user = finalMap.get(v.getUserId());
            if (null != user) {
                v.setUserName(user.getUserName());
                v.setHeadIcon(UploaderUtil.uploaderImg(user.getHeadIcon()));
            }else {
                ids.add(v.getUserId());
            }
        });
        if (!ids.isEmpty()) {
            // 移除已删除用户
            informationAuthorityMapper.deleteByUsersAndId(id, ids);
            removeUser(informationAuthorityVos, ids);
        }
        return informationAuthorityVos;
    }

    public static List<InformationAuthorityVo>  removeUser(List<InformationAuthorityVo> users, List<String> userIds) {
        userIds.forEach(v->{
            for (InformationAuthorityVo user : users) {
                if (Objects.equals(v, user.getUserId())) {
                    users.remove(user);
                    break;
                }
            }
        });
        return users;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void transferOwnership(String id, FileQueryDto fileQueryDto) {
        //转移空间/文件夹/文件所有权
        UserInfo userInfo = userProvider.get();
        InformationVo informationById = informationMapper.getInformationById(id);
        //先将原来的文件拥有者的权限改为管理员
        informationAuthorityMapper.updateUserAuthority(informationById.getOwner(),id,2);
        //将information中的拥有者改为新的用户
        informationMapper.updateOwner(id , fileQueryDto.getUserId(),userInfo.getUserId());
        //查看新的用户是否属于权限表中  没有新增
        String idByUserId = informationAuthorityMapper.getIdByUserId(id , fileQueryDto.getUserId());
        if (null != idByUserId){
            //有修改该用户的权限
            informationAuthorityMapper.updateById(idByUserId,0,userInfo.getUserId());
        }else {
            informationAuthorityMapper.addUserAuthority(FtbUtil.getId(),userInfo.getUserId(),id,0,fileQueryDto.getUserId());
        }
    }

    @Override
    public void editPermissions(String id, InformationAuthorityVo informationAuthorityVo) {
        String userId = userProvider.get().getUserId();
        informationAuthorityMapper.updateById(informationAuthorityVo.getId(),informationAuthorityVo.getLimitsOfAuthority(),userId);
    }

    @Override
    public void removeUser(String id) {
        informationAuthorityMapper.deleteById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void space(SpaceDto spaceDto) {
        UserInfo userInfo = userProvider.get();
        //空间赋值id
        String id = FtbUtil.getId();
        spaceDto.setId(id);
        //赋值路径
        spaceDto.setFilePath("0,"+id+",");
        spaceDto.setClassification(1);
        informationMapper.addInformation(spaceDto,userInfo.getUserId());
        //绑定空间成员
        spaceDto.getUserList().forEach(v->v.setId(FtbUtil.getId()));
        informationAuthorityMapper.addUserAuthorityList(id,userInfo.getUserId(),spaceDto.getUserList());

    }

    @Override
    public void folder(SpaceDto spaceDto) {
        InformationVo informationById = informationMapper.getInformationById(spaceDto.getFilePId());
        UserInfo userInfo = userProvider.get();
        //文件夹赋值id
        String id = FtbUtil.getId();
        spaceDto.setId(id);
        //赋值路径
        spaceDto.setFilePath(informationById.getFilePath()+id+",");
        spaceDto.setClassification(2);
        informationMapper.addInformation(spaceDto,userInfo.getUserId());
        //将创建人写入权限表
        List<InformationAuthorityDto> userList = new ArrayList<>();
        InformationAuthorityDto informationAuthorityDto = new InformationAuthorityDto();
        informationAuthorityDto.setId(FtbUtil.getId());
        informationAuthorityDto.setUserId(userInfo.getUserId());
        informationAuthorityDto.setLimitsOfAuthority(0);
        userList.add(informationAuthorityDto);
        informationAuthorityMapper.addUserAuthorityList(id,userInfo.getUserId(),userList);
    }

    @Override
    public void move(String id, FileQueryDto fileQueryDto) {
        //通过移动后的空间/文件id查出信息
        InformationVo informationById = informationMapper.getInformationById(fileQueryDto.getToInformationId());
        //拿到当前文件夹和文件夹下数据信息
        List<InformationVo> informationVos = informationMapper.getSubordinate(id);
        UserInfo userInfo = userProvider.get();
        //替换路径
        informationVos.forEach(v->{
            String[] split = v.getFilePath().split(id + ",");
            String s="";
            if (split.length > 1){
                s = split[1];
            }
            String filepath = informationById.getFilePath()+id+","+s;
            //修改文件路径
            informationMapper.updateFilePath(v.getId(),filepath,userInfo.getUserId());
        });
        //修改文件父级
        informationMapper.updateFilePId(id,fileQueryDto.getToInformationId(),userInfo.getUserId());
    }

    @Override
    public PageInfo<InformationVo> relatedToMeFilePage(FileQueryDto fileQueryDto) {
        //参数处理 如果是全部处理为空
        if("全部".equals(fileQueryDto.getFileType())){fileQueryDto.setFileType(null);}
        //得到企业下所有被标记为删除的id集合
        List<String> enabledMarkIds = informationMapper.getEnabledMarkInformation();
        PageHelper.startPage(fileQueryDto.getCurrentPage(), fileQueryDto.getPageSize());
        PageInfo<InformationVo> info = new PageInfo<>(informationMapper.relatedToMeFile(fileQueryDto,enabledMarkIds));
        setOwnerName(info);
        return info;
    }

    @Override
    public PageInfo<InformationVo> recentlyViewedPage(FileQueryDto fileQueryDto) {
        spaceService.deleteOverdueViewRecord();
        //参数处理 如果是全部处理为空
        if("全部".equals(fileQueryDto.getFileType())){fileQueryDto.setFileType(null);}
        UserInfo userInfo = userProvider.get();
        //验证是否是超级管理员
//        Integer userModuleDataAuthorizesChem = userApi.getUserModuleDataAuthorizesChem("resource", userInfo.getUserId(), "information_admin");
        //得到企业下所有被标记为删除的id集合
        List<String> enabledMarkIds = informationMapper.getEnabledMarkInformation();
        if (userInfo.getIsAdministrator()){
            //超级管理员拥有最高权限 跳过验证 看所有的不管是不是成员
            PageHelper.startPage(fileQueryDto.getCurrentPage(), fileQueryDto.getPageSize());
            PageInfo<InformationVo> info = new PageInfo<>(informationMapper.recentlyViewed(fileQueryDto,enabledMarkIds));
            setOwnerName(info);
            return info;
        }
        PageHelper.startPage(fileQueryDto.getCurrentPage(), fileQueryDto.getPageSize());
        PageInfo<InformationVo> info = new PageInfo<>(informationMapper.recentlyViewedMember(fileQueryDto,enabledMarkIds));
        setOwnerName(info);
        return info;

    }

    private void setOwnerName(PageInfo<InformationVo> info) {
        if(null != info.getList() && info.getList().size() > 0){
            //赋值拥有者名称
            List<String> userIds = info.getList().stream().map(InformationVo::getCreatorUserId).collect(Collectors.toList());
            // 查询成员信息
//            List<PartUserInfoVo> list = userApi.getInfoByIds(userIds);
//            Map<String, PartUserInfoVo> map = list.stream().collect(Collectors.toMap(PartUserInfoVo::getUserId, Function.identity()));
            ActionResult<List<UserBoundVO>> userList = v2UserApi.getAllUserInfoBatch(userIds, null);
            Map<String, UserBoundVO> map = new HashMap<>();
            if (200 == userList.getCode() && CollectionUtil.isNotEmpty(userList.getData())) {
                map = userList.getData().stream().collect(Collectors.toMap(UserBoundVO::getId, a -> a, (k1, k2) -> k1));
            }
            Map<String, UserBoundVO> finalMap = map;
            info.getList().forEach(v->{
//                PartUserInfoVo partUserInfoVo = map.get(v.getCreatorUserId());
                UserBoundVO partUserInfoVo = finalMap.get(v.getCreatorUserId());
                if (null != partUserInfoVo){
                    v.setCreatorName(partUserInfoVo.getUserName());
                }
            });
        }
    }

    private void setOwnerNames(List<InformationVo> informationVos) {
        if(null != informationVos && informationVos.size() > 0){
            //赋值拥有者名称
            List<String> userIds = informationVos.stream().map(InformationVo::getCreatorUserId).collect(Collectors.toList());
            // 查询成员信息
//            List<PartUserInfoVo> list = userApi.getInfoByIds(userIds);
//            Map<String, PartUserInfoVo> map = list.stream().collect(Collectors.toMap(PartUserInfoVo::getUserId, Function.identity()));
            ActionResult<List<UserBoundVO>> userList = v2UserApi.getAllUserInfoBatch(userIds, null);
            Map<String, UserBoundVO> map = new HashMap<>();
            if (200 == userList.getCode() && CollectionUtil.isNotEmpty(userList.getData())) {
                map = userList.getData().stream().collect(Collectors.toMap(UserBoundVO::getId, a -> a, (k1, k2) -> k1));
            }
            Map<String, UserBoundVO> finalMap = map;
            informationVos.forEach(v->{
//                PartUserInfoVo partUserInfoVo = map.get(v.getCreatorUserId());
                UserBoundVO partUserInfoVo = finalMap.get(v.getCreatorUserId());
                if (null != partUserInfoVo){
                    v.setCreatorName(partUserInfoVo.getUserName());
                }
            });
        }
    }

    @Override
    public Integer exitSpace(String id) {
        //如果我是空间拥有者 不能退出
        UserInfo userInfo = userProvider.get();
        InformationVo informationById = informationMapper.getInformationById(id);
        if (informationById.getOwner().equals(userInfo.getUserId())){
            return -1;
        }
        informationAuthorityMapper.deleteByUserAndId(id,userInfo.getUserId());
        return 0;
    }

    @Override
    public void editPermissionsBatch(String id, FileQueryDto fileQueryDto) {
        String userId = userProvider.get().getUserId();
        fileQueryDto.getInformationAuthorityVos().forEach(v->{
            informationAuthorityMapper.updateById(v.getId(),v.getLimitsOfAuthority(),userId);
        });
    }

    @Override
    public void removeUserBatch(List<InformationAuthorityVo> informationAuthorityVos) {
        if (null != informationAuthorityVos && informationAuthorityVos.size() >0){
            informationAuthorityVos.forEach(v->{
                informationAuthorityMapper.deleteById(v.getId());
            });
        }
    }

    @Override
    public void membersBatch(SpaceDto spaceDto) {
        UserInfo userInfo = userProvider.get();
        //绑定空间成员
        spaceDto.getUserList().forEach(v->v.setId(FtbUtil.getId()));
        informationAuthorityMapper.addUserAuthorityList(spaceDto.getId(),userInfo.getUserId(),spaceDto.getUserList());
        //新增日志
        InformationVo informationVo = informationMapper.getInformationById(spaceDto.getId());
        //
        List<String> userIds = spaceDto.getUserList().stream().map(InformationAuthorityDto::getUserId).collect(Collectors.toList());
        // 查询成员信息
//        List<PartUserInfoVo> list = userApi.getInfoByIds(userIds);
//        List<String> userNames = list.stream().map(PartUserInfoVo::getRealName).collect(Collectors.toList());

        ActionResult<List<UserBoundVO>> userList = v2UserApi.getAllUserInfoBatch(userIds, null);
        List<String> userNames = new ArrayList<>();
        if (200 == userList.getCode() && CollectionUtil.isNotEmpty(userList.getData())) {
            userNames = userList.getData().stream().map(UserBoundVO::getUserName).collect(Collectors.toList());
        }
        addInformationLog(spaceDto.getId(),informationVo.getClassification(),userInfo.getUserId(),userInfo.getUserName(),"邀请",userNames);
    }
}
