package com.yunzhupaas.permission.service.impl;

import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yunzhupaas.base.UserInfo;
import com.yunzhupaas.base.service.SuperServiceImpl;
import com.yunzhupaas.constant.MsgCode;
import com.yunzhupaas.constant.PermissionConst;
import com.yunzhupaas.message.entity.SynThirdInfoEntity;
import com.yunzhupaas.message.service.SynThirdInfoService;
import com.yunzhupaas.message.util.SynThirdConsts;
import com.yunzhupaas.permission.entity.PermissionEntityBase;
import com.yunzhupaas.permission.entity.PositionEntity;
import com.yunzhupaas.permission.entity.UserEntity;
import com.yunzhupaas.permission.entity.UserRelationEntity;
import com.yunzhupaas.permission.mapper.UserRelationMapper;
import com.yunzhupaas.permission.model.permission.PermissionModel;
import com.yunzhupaas.permission.model.userrelation.UserRelationForm;
import com.yunzhupaas.permission.service.*;
import com.yunzhupaas.permission.util.PermissionUtil;
import com.yunzhupaas.util.RandomUtil;
import com.yunzhupaas.util.StringUtil;
import com.yunzhupaas.util.UserProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

import static com.yunzhupaas.util.Constants.ADMIN_KEY;

/**
 * 用户关系
 *
 * @author 云筑产品开发平台组
 * @version V3.1.0
 * @copyright 深圳市乐程软件有限公司
 * @date 2024-09-26 上午9:18
 */
@Service
public class UserRelationServiceImpl extends SuperServiceImpl<UserRelationMapper, UserRelationEntity> implements UserRelationService {

    @Autowired
    private UserService userService;
    @Autowired
    private PositionService positionService;
    @Autowired
    private OrganizeService organizeService;
    @Autowired
    private OrganizeRelationService organizeRelationService;
    @Autowired
    private UserRelationService userRelationService;
    @Autowired
    private SynThirdInfoService synThirdInfoService;

    @Override
    public List<UserRelationEntity> getListByUserId(String userId) {
        return getListByUserIdAll(Collections.singletonList(userId));
    }

    @Override
    public List<UserRelationEntity> getListByUserIdAndObjType(String userId, String objectType) {
        QueryWrapper<UserRelationEntity> query = new QueryWrapper<>();
        query.lambda().in(UserRelationEntity::getUserId, userId);
        query.lambda().in(UserRelationEntity::getObjectType, objectType);
        query.lambda().orderByAsc(UserRelationEntity::getSortCode).orderByDesc(UserRelationEntity::getCreatorTime);
        return this.list(query);
    }

    @Override
    public List<UserRelationEntity> getListByUserIdAll(List<String> userId) {
        if (userId.size() > 0) {
            QueryWrapper<UserRelationEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().in(UserRelationEntity::getUserId, userId);
            return this.list(queryWrapper);
        }
        return new ArrayList<>();
    }

    @Override
    public List<UserRelationEntity> getListByObjectId(String objectId) {
        return getListByObjectId(objectId, null);
    }

    @Override
    public List<UserRelationEntity> getListByObjectType(String objectType) {
        QueryWrapper<UserRelationEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserRelationEntity::getObjectType, objectType);
        return this.list(queryWrapper);
    }

    @Override
    public List<UserRelationEntity> getListByObjectId(String objectId, String objectType) {
        QueryWrapper<UserRelationEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserRelationEntity::getObjectId, objectId);
        if(objectType != null){
            queryWrapper.lambda().eq(UserRelationEntity::getObjectType, objectType);
        }
        queryWrapper.lambda().orderByAsc(UserRelationEntity::getSortCode).orderByDesc(UserRelationEntity::getCreatorTime);
        return this.list(queryWrapper);
    }

    @Override
    public List<UserRelationEntity> getListByObjectIdAll(List<String> objectId) {
        List<UserRelationEntity> list = new ArrayList<>();
        if (objectId.size() > 0) {
            QueryWrapper<UserRelationEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().in(UserRelationEntity::getObjectId, objectId);
            list = this.list(queryWrapper);
        }
        return list;
    }

    @Override
    public void deleteAllByObjId(String objId) {
        QueryWrapper<UserRelationEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserRelationEntity::getObjectId, objId);
        this.remove(queryWrapper);
    }

    @Override
    public void deleteAllByUserId(String userId) {
        QueryWrapper<UserRelationEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserRelationEntity::getUserId, userId);
        queryWrapper.lambda().ne(UserRelationEntity::getObjectType, PermissionConst.GROUP);
        userRelationService.remove(queryWrapper);
    }

    @Override
    public void createByList(List<UserRelationEntity> userRelationEntityList) {
        userRelationEntityList.forEach(t -> {
            this.save(t);
        });
    }

    @Override
    public UserRelationEntity getInfo(String id) {
        QueryWrapper<UserRelationEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserRelationEntity::getId, id);
        return this.getOne(queryWrapper);
    }

    @Override
    @DSTransactional
    public void save(String objectId, List<UserRelationEntity> entitys) {
        List<UserRelationEntity> existList = this.getListByObjectId(objectId);
        List<UserRelationEntity> relationList = new ArrayList<>();
        for (int i = 0; i < entitys.size(); i++) {
            UserRelationEntity entity = entitys.get(i);
            entity.setId(RandomUtil.uuId());
            entity.setSortCode(Long.parseLong(i + ""));
            entity.setCreatorUserId(UserProvider.getUser().getUserId());
            if (existList.stream().filter(t -> t.getUserId().equals(entity.getUserId())).count() == 0) {
                relationList.add(entity);
            }
        }
        for (UserRelationEntity entity : relationList) {
            this.save(entity);
        }
    }

    @Override
    public void save(List<UserRelationEntity> list) {
        for (UserRelationEntity entity : list) {
            this.save(entity);
        }
    }

    @Override
    @DSTransactional
    public void delete(String[] ids) {
        for (String item : ids) {
            QueryWrapper<UserRelationEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(UserRelationEntity::getId, item);
            this.remove(queryWrapper);
        }
    }


    @Override
    @DSTransactional
    public void saveObjectId(String objectId, UserRelationForm userRelationForm) {
        // 修改前的岗位绑定人员ID
        List<String> beforeUserIds = userRelationService.getListByObjectId(objectId)
                .stream().map(UserRelationEntity::getUserId).collect(Collectors.toList());
        //清除原有成员数据
        deleteAllByObjId(objectId);
        UserInfo userInfo = UserProvider.getUser();
        List<UserRelationEntity> list = new ArrayList<>();
        int i = 0;
        for (String userId : userRelationForm.getUserIds()) {
            UserRelationEntity entity = new UserRelationEntity();
            entity.setId(RandomUtil.uuId());
            entity.setSortCode(Long.parseLong(i + ""));
            entity.setObjectId(objectId);
            entity.setObjectType(userRelationForm.getObjectType());
            entity.setCreatorUserId(userInfo.getUserId());
            entity.setUserId(userId);
            list.add(entity);
            i++;
        }
        save(objectId, list);

        // 并集：所有未修改的人员
        List<String> unUpdateUserId = beforeUserIds.stream().filter(b-> userRelationForm.getUserIds()
                .contains(b)).collect(Collectors.toList());
        // 差集：所有修改过的人员(包括：删除此岗位、添加此岗位的人员)
        beforeUserIds.addAll(userRelationForm.getUserIds());
        List<String> allUpdateIds = beforeUserIds.stream().filter(u-> !unUpdateUserId.contains(u))
                .collect(Collectors.toList());

        if (PermissionConst.POSITION.equals(userRelationForm.getObjectType())) {
            // 自动切换岗位
            organizeRelationService.autoSetPosition(allUpdateIds);
        }
        userService.delCurUser(MsgCode.PS010.get(), allUpdateIds,3);
    }

    @Override
    public List<UserRelationEntity> getRelationByUserIds(List<String> userIds) {
        if (userIds.size() == 0) {
            return new ArrayList<>();
        }
        QueryWrapper<UserRelationEntity> query = new QueryWrapper<>();
        query.lambda().in(UserRelationEntity::getUserId, userIds);
        query.lambda().eq(UserRelationEntity::getObjectType, PermissionConst.ORGANIZE);
        return this.list(query);
    }

    @Override
    public List<UserRelationEntity> getListByObjectType(String userId, String objectType) {
        QueryWrapper<UserRelationEntity> query = new QueryWrapper<>();
        query.lambda().eq(UserRelationEntity::getUserId, userId);
        if (StringUtil.isNotEmpty(objectType)) {
            query.lambda().eq(UserRelationEntity::getObjectType, objectType);
        }
        query.lambda().orderByAsc(UserRelationEntity::getSortCode).orderByDesc(UserRelationEntity::getCreatorTime);
        return this.list(query);
    }

    @Override
    public List<UserRelationEntity> getAllOrgRelationByUserId(String userId){
        return this.getListByObjectType(userId,PermissionConst.ORGANIZE);
    }

    @Override
    public List<PermissionModel> getObjectVoList(String objectType) {
        String userId = UserProvider.getUser().getUserId();
        UserEntity userEntity = userService.getInfo(userId);
        String majorOrgId = UserProvider.getUser().getOrganizeId();

        // 组装对应组织/岗位/角色对象
        switch (objectType) {
            case PermissionConst.ORGANIZE:
                // 使用in查询减少数据库查询次数
                List<String> ids = new ArrayList<>();
                this.getListByObjectType(userId, objectType).forEach(r -> ids.add(r.getObjectId()));
                List<PermissionModel> permissionModels = setModel(organizeService.getOrgEntityList(ids, false), majorOrgId);
                permissionModels.forEach(p->p.setFullName(PermissionUtil.getLinkInfoByOrgId(p.getId(), organizeService, false)));
                return permissionModels;
            case PermissionConst.POSITION:
                // 岗位遵循一对多关系
                List<PositionEntity> positionList = positionService.getListByUserId(userId);
                if (positionList.size() > 0) {
                    return setModel(positionList.stream().filter(p -> p.getOrganizeId().equals(majorOrgId))
                            .collect(Collectors.toList()), userEntity.getPositionId());
                }
            default:
                return new ArrayList<>();
        }
    }

    /**
     * 设置返回模型
     *
     * @param permissionList
     * @param majorId
     */
    private <T extends PermissionEntityBase> List<PermissionModel> setModel (List<T> permissionList, String majorId){
        List<PermissionModel> voList = new ArrayList<>();
        permissionList.forEach(p -> {
            PermissionModel model = new PermissionModel();
            if (p.getId().equals(majorId)) {
                model.setIsDefault(true);
            } else {
                model.setIsDefault(false);
            }
            model.setFullName(p.getFullName());
            model.setId(p.getId());
            model.setFullName(p.getFullName());
            voList.add(model);
        });
        return voList;
    }

    @Override
    public Boolean existByObj(String objectType, String objectId) {
        QueryWrapper<UserRelationEntity> query = new QueryWrapper<>();
        query.lambda()
                .eq(UserRelationEntity::getObjectType, objectType)
                .eq(UserRelationEntity::getObjectId, objectId);
        return this.count(query) > 0;
    }

    @Override
    public List<UserRelationEntity> getListByRoleId(String roleId) {
        List<UserRelationEntity> list = new ArrayList<>();
        organizeRelationService.getRelationListByRoleId(roleId).forEach(o->{
            QueryWrapper<UserRelationEntity> query = new QueryWrapper<>();
            query.lambda()
                    .eq(UserRelationEntity::getObjectType, PermissionConst.ORGANIZE)
                    .eq(UserRelationEntity::getObjectId, o.getOrganizeId());
            list.addAll(this.list(query));
        });
        return list;
    }

    @Override
    public List<UserRelationEntity> getListByUserId(String userId, String objectType) {
        QueryWrapper<UserRelationEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserRelationEntity::getUserId, userId);
        queryWrapper.lambda().eq(UserRelationEntity::getObjectType, objectType);
        return this.list(queryWrapper);
    }

    @Override
    public List<UserRelationEntity> getListByOrgId(List<String> orgIdList) {
        if (orgIdList.size() > 0) {
            QueryWrapper<UserRelationEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(UserRelationEntity::getObjectType, PermissionConst.ORGANIZE).in(UserRelationEntity::getObjectId, orgIdList);
            return this.list(queryWrapper);
        }
        return new ArrayList<>();
    }

    @Override
    public void syncDingUserRelation(String sysObjId, List<Long> deptIdList) {
        List<UserRelationEntity> list = new ArrayList<>();
        UserRelationEntity entity = null;
        // 查询对应的中间表，获取到对应的本地组织id
        QueryWrapper<SynThirdInfoEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().in(SynThirdInfoEntity::getThirdObjId,deptIdList);
        wrapper.lambda().eq(SynThirdInfoEntity::getThirdType, SynThirdConsts.THIRD_TYPE_DING_To_Sys);
        List<SynThirdInfoEntity> synThirdInfoLists = synThirdInfoService.getBaseMapper().selectList(wrapper);
        HashMap<String,String> map = new HashMap<>();
        for (SynThirdInfoEntity obj : synThirdInfoLists) {
            map.put(obj.getThirdObjId(),obj.getSysObjId());
        }
        // 已经存在的数据
        List<String> collect = deptIdList.stream().map(t -> String.valueOf(t)).collect(Collectors.toList());
        QueryWrapper<UserRelationEntity> relationWrapper = new QueryWrapper<>();
        relationWrapper.lambda().in(UserRelationEntity::getObjectId,collect);
        relationWrapper.lambda().eq(UserRelationEntity::getObjectType,"Organize");
        relationWrapper.lambda().eq(UserRelationEntity::getUserId,sysObjId);
        List<UserRelationEntity> userRelationEntities = this.getBaseMapper().selectList(relationWrapper);
        List<String> deleteIdS = userRelationEntities.stream().map(t -> t.getId()).collect(Collectors.toList());
        this.removeByIds(deleteIdS);

        UserEntity adminAccount = userService.getUserByAccount(ADMIN_KEY);
        String adminId = adminAccount == null ? null : adminAccount.getId();
        for (Long id : deptIdList) {
            String objectId = String.valueOf(id);
            entity= new UserRelationEntity();
            entity.setId(RandomUtil.uuId());
            entity.setObjectId(map.get(objectId));
            entity.setCreatorUserId(adminId);
            entity.setSortCode(0L);
            entity.setUserId(sysObjId);
            entity.setObjectType("Organize");
            list.add(entity);
        }
        this.saveBatch(list);
    }

}

