package com.qmth.sop.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qmth.sop.business.bean.dto.UserDto;
import com.qmth.sop.business.bean.result.CrmProjectResult;
import com.qmth.sop.business.bean.result.MenuResult;
import com.qmth.sop.business.cache.CommonCacheService;
import com.qmth.sop.business.entity.*;
import com.qmth.sop.business.mapper.SysUserRoleMapper;
import com.qmth.sop.business.service.*;
import com.qmth.sop.common.enums.DingObjTypeEnum;
import com.qmth.sop.common.enums.ExceptionResultEnum;
import com.qmth.sop.common.enums.RoleTypeEnum;
import com.qmth.sop.common.enums.UserSourceEnum;
import com.qmth.sop.common.util.ServletUtil;
import org.apache.commons.collections4.CollectionUtils;
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;

/**
 * <p>
 * 用户和角色关联表 服务实现类
 * </p>
 *
 * @author wangliang
 * @since 2023-07-17
 */
@Service
public class SysUserRoleServiceImpl extends ServiceImpl<SysUserRoleMapper, SysUserRole> implements SysUserRoleService {

    @Resource
    CommonCacheService commonCacheService;

    @Resource
    SysDingGroupService sysDingGroupService;

    @Resource
    SysDingObjService sysDingObjService;

    @Resource
    SysRoleService sysRoleService;

    @Resource
    TBServiceService tbServiceService;

    @Resource
    TBCrmService tbCrmService;

    @Resource
    SysUserService sysUserService;

    @Resource
    TBUserArchivesService tbUserArchivesService;

    @Resource
    TBUserArchivesSupplierService tbUserArchivesSupplierService;

    @Resource
    SysUserRoleService sysUserRoleService;

    /**
     * 获取用户菜单
     *
     * @return
     */
    @Override
    public MenuResult listByUserId() {
        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
        return commonCacheService.userMenuCache(sysUser.getId());
    }

    @Override
    public List<SysRole> listRoleByUserId(Long userId) {
        return this.baseMapper.listRoleByUserId(userId);
    }

    @Override
    public boolean userContainsRoles(Long userId, RoleTypeEnum... roleTypes) {
        boolean result = false;
        List<SysRole> sysRoleList = this.listRoleByUserId(userId);
        if (CollectionUtils.isNotEmpty(sysRoleList)) {
            List<RoleTypeEnum> targetRoleTypeList = Arrays.stream(roleTypes).collect(Collectors.toList());
            List<RoleTypeEnum> userRoleTypeList = sysRoleList.stream().map(SysRole::getType).collect(Collectors.toList());
            if (userRoleTypeList.containsAll(targetRoleTypeList)) {
                result = true;
            }
        }
        return result;
    }

    /**
     * 新增用户权限
     *
     * @param sysUser
     * @param roleIds
     */
    @Override
    @Transactional
    public void addUserRolePrivilege(SysUser sysUser, Long[] roleIds) {
        List<SysUserRole> sysUserRoleList = new ArrayList<>();
        for (int i = 0; i < roleIds.length; i++) {
            sysUserRoleList.add(new SysUserRole(sysUser.getId(), roleIds[i]));
        }
        this.saveBatch(sysUserRoleList);
    }

    /**
     * 根据角色id查询用户信息
     *
     * @param roleId
     * @return
     */
    @Override
    public List<SysUserRole> listByRoleId(Long roleId) {
        return this.baseMapper.listByRoleId(roleId);
    }

    /**
     * 根据角色类型查询用户信息
     *
     * @param roleTypeEnums
     * @return
     */
    @Override
    public List<UserDto> userListByRoleType(List<RoleTypeEnum> roleTypeEnums) {
        return this.baseMapper.userListByRoleType(roleTypeEnums);
    }

    /**
     * 根据服务单元查找用户
     *
     * @param serviceId
     * @param userId
     * @param sopNo
     * @return
     */
    @Override
    public List<String> listByServiceId(Long serviceId, Long userId, String sopNo) {
        SysUser sysUser = sysUserService.getById(userId);
        Optional.ofNullable(sysUser).orElseThrow(() -> ExceptionResultEnum.USER_NO_EXISTS.exception());

        if (sysUser.getSource() == UserSourceEnum.SYSTEM) {
            throw ExceptionResultEnum.ERROR.exception("非档案用户不能发起异常补卡申请");
        }
        TBUserArchives tbUserArchives = tbUserArchivesService.getOne(new QueryWrapper<TBUserArchives>().lambda().eq(TBUserArchives::getMobileNumber, sysUser.getMobileNumber()));
        Optional.ofNullable(tbUserArchives).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("档案用户不存在"));

        TBUserArchivesSupplier tbUserArchivesSupplier = tbUserArchivesSupplierService.getOne(new QueryWrapper<TBUserArchivesSupplier>().lambda().eq(TBUserArchivesSupplier::getUserArchivesId, tbUserArchives.getId()));
        Optional.ofNullable(tbUserArchivesSupplier).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("档案机构不存在"));

        List<SysRole> userArchivesRoleList = sysUserRoleService.listRoleByUserId(sysUser.getId());
        Map<Long, SysRole> userArchivesRoleMap = userArchivesRoleList.stream().collect(Collectors.toMap(SysRole::getId, Function.identity(), (dto1, dto2) -> dto1));

        List<SysDingGroup> sysDingGroupList = sysDingGroupService.list(new QueryWrapper<SysDingGroup>().lambda().eq(SysDingGroup::getServiceId, serviceId).eq(SysDingGroup::getSupplierId, tbUserArchivesSupplier.getSupplierId()));
        if (CollectionUtils.isEmpty(sysDingGroupList)) {
            throw ExceptionResultEnum.SERVICE_DING_GROUP_NO_DATA.exception();
        }
        List<String> userIdList = null;
        for (SysDingGroup sysDingGroup : sysDingGroupList) {
            //首选找考勤对象
            List<SysDingObj> sysDingObjList = sysDingObjService.list(new QueryWrapper<SysDingObj>().lambda().eq(SysDingObj::getDingGroupId, sysDingGroup.getId()));
            if (CollectionUtils.isEmpty(sysDingObjList)) {
                throw ExceptionResultEnum.SERVICE_DING_NO_DATA.exception();
            }
            List<SysDingObj> sysDingApproveList = new ArrayList<>(), sysDingList = new ArrayList<>();
            for (SysDingObj s : sysDingObjList) {
                if (s.getType() == DingObjTypeEnum.DING) {
                    sysDingList.add(s);
                } else if (s.getType() == DingObjTypeEnum.APPROVE) {
                    sysDingApproveList.add(s);
                }
            }
            for (SysDingObj s : sysDingList) {
                if (userArchivesRoleMap.containsKey(s.getRoleId())) {
                    userIdList = new ArrayList<>();
                    break;
                }
            }
            if (Objects.isNull(userIdList)) {
                continue;
            }
            if (CollectionUtils.isEmpty(sysDingApproveList)) {
                throw ExceptionResultEnum.SERVICE_DING_APPROVE_NO_DATA.exception();
            }
            List<Long> roleIsList = sysDingApproveList.stream().map(s -> s.getRoleId()).collect(Collectors.toList());
            //首选查角色类型
            List<SysRole> sysRoleList = sysRoleService.listByIds(roleIsList);
            List<Long> sysRoleOtherList = new ArrayList<>();
            for (SysRole s : sysRoleList) {
                if (s.getType() == RoleTypeEnum.BUSSINESS) {
                    List<TBService> tbServiceList = tbServiceService.listByIds(Arrays.asList(serviceId));
                    if (!CollectionUtils.isEmpty(tbServiceList)) {
                        List<String> serviceLeadIdList = new ArrayList<>();
                        for (TBService t : tbServiceList) {
                            if (Objects.nonNull(t.getServiceLeadId())) {
                                serviceLeadIdList.add(String.valueOf(t.getServiceLeadId()));
                            }
                        }
                        userIdList.addAll(serviceLeadIdList);
                    }
                } else if (s.getType() == RoleTypeEnum.REGION_MANAGER) {
                    CrmProjectResult crmProjectResult = tbCrmService.findCrmProjectBySopNoOrCrmNo(sopNo, null);
                    if (Objects.nonNull(crmProjectResult) && Objects.nonNull(crmProjectResult.getRegionManagerId())) {
                        userIdList.addAll(Arrays.asList(String.valueOf(crmProjectResult.getRegionManagerId())));
                    }
                } else if (s.getType() == RoleTypeEnum.REGION_COORDINATOR) {
                    CrmProjectResult crmProjectResult = tbCrmService.findCrmProjectBySopNoOrCrmNo(sopNo, null);
                    if (Objects.nonNull(crmProjectResult) && Objects.nonNull(crmProjectResult.getRegionCoordinatorId())) {
                        userIdList.addAll(Arrays.asList(String.valueOf(crmProjectResult.getRegionCoordinatorId())));
                    }
                } else {
                    sysRoleOtherList.add(s.getId());
                }
            }
            if (!CollectionUtils.isEmpty(sysRoleOtherList)) {
                List<SysUserRole> sysUserRoleList = this.list(new QueryWrapper<SysUserRole>().lambda().in(SysUserRole::getRoleId, sysRoleOtherList));
                List<String> otherRoleUserList = sysUserRoleList.stream().map(i -> String.valueOf(i.getUserId())).collect(Collectors.toList());
                userIdList.addAll(otherRoleUserList);
            }
            break;
        }
        if (CollectionUtils.isEmpty(userIdList)) {
            throw ExceptionResultEnum.ERROR.exception("未找到异常考勤审批用户");
        }
        return userIdList;
    }
}
