package com.ningdatech.pmapi.common.helper.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.ningdatech.pmapi.common.helper.UserInfoHelper;
import com.ningdatech.pmapi.organization.model.entity.DingEmployeeInfo;
import com.ningdatech.pmapi.organization.model.entity.DingOrganization;
import com.ningdatech.pmapi.organization.service.IDingEmployeeInfoService;
import com.ningdatech.pmapi.organization.service.IDingOrganizationService;
import com.ningdatech.pmapi.sys.mapper.RoleMapper;
import com.ningdatech.pmapi.sys.model.entity.Role;
import com.ningdatech.pmapi.sys.model.entity.UserRole;
import com.ningdatech.pmapi.sys.service.IUserRoleService;
import com.ningdatech.pmapi.user.constant.UserAvailableEnum;
import com.ningdatech.pmapi.user.entity.UserInfo;
import com.ningdatech.pmapi.user.entity.enumeration.RoleEnum;
import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO;
import com.ningdatech.pmapi.user.service.IUserInfoService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

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

/**
 * @author liuxinxin
 * @date 2023/2/10 下午4:40
 */
@Component
@RequiredArgsConstructor
public class UserInfoHelperImpl implements UserInfoHelper {


    private final IUserInfoService userInfoService;
    private final IDingEmployeeInfoService iDingEmployeeInfoService;
    private final IDingOrganizationService iDingOrganizationService;
    private final IUserRoleService iUserRoleService;
    private final RoleMapper roleMapper;


    @Override
    public String getOrganizationCode(Long userId) {
        UserFullInfoDTO userFullInfo = getUserFullInfo(userId);
        return userFullInfo.getOrganizationCode();
    }

    @Override
    public UserFullInfoDTO getUserFullInfo(Long userId) {
        UserInfo userInfo = userInfoService.getById(userId);
        if (Objects.isNull(userInfo)) {
            return null;
        }
        // 返回用户全量信息
        return getUserFullInfo(userInfo);
    }

    @Override
    public UserFullInfoDTO getUserFullInfo(UserInfo userInfo) {
        UserFullInfoDTO userFullInfo = new UserFullInfoDTO();
        // 获取浙政钉雇员信息 组织信息
        String employeeCode = userInfo.getEmployeeCode();
        if (StringUtils.isNotBlank(employeeCode)) {
            List<DingEmployeeInfo> dingEmployeeInfoList = iDingEmployeeInfoService
                    .list(Wrappers.lambdaQuery(DingEmployeeInfo.class)
                            .eq(DingEmployeeInfo::getEmployeeCode, employeeCode)
                            .eq(DingEmployeeInfo::getMainJob, "true"));
            DingEmployeeInfo dingEmployeeInfo = dingEmployeeInfoList.get(0);


            // 装配用户任职所在单位
            String empPosUnitCode = dingEmployeeInfo.getEmpPosUnitCode();
            if (StringUtils.isNotBlank(empPosUnitCode)) {
                DingOrganization dingOrganization = iDingOrganizationService.getByOrgCode(empPosUnitCode);
                if (Objects.nonNull(dingOrganization)) {
                    userFullInfo.setEmpPosUnitCode(empPosUnitCode);
                    userFullInfo.setEmpPosUnitName(dingOrganization.getOrganizationName());
                    userFullInfo.setRegionCode(dingOrganization.getDivisionCode());
                }
            }

            // 装配用户所在orgCode
            String organizationCode = dingEmployeeInfo.getOrganizationCode();
            List<DingOrganization> dingOrganizationList = iDingOrganizationService.list(Wrappers
                    .lambdaQuery(DingOrganization.class)
                    .eq(DingOrganization::getOrganizationCode, organizationCode));
            if (CollectionUtil.isNotEmpty(dingOrganizationList)) {
                DingOrganization dingOrganization = dingOrganizationList.get(0);
                userFullInfo.setOrganizationCode(dingOrganization.getOrganizationCode());
                userFullInfo.setOrganizationName(dingOrganization.getOrganizationName());
                // 测试使用
                userFullInfo.setRegionLevel(3);
            }
        }

        List<Role> roleList = new ArrayList<>();
        // 获取用户角色列表信息
        List<UserRole> userRoleList = iUserRoleService
                .list(Wrappers.lambdaQuery(UserRole.class)
                        .eq(UserRole::getUserId, userInfo.getId()));
        if (CollectionUtil.isNotEmpty(userRoleList)) {
            List<Long> roleIdList = userRoleList.stream()
                    .map(UserRole::getRoleId).distinct()
                    .collect(Collectors.toList());
            roleList = roleMapper.selectBatchIds(roleIdList);
        }
        userFullInfo.setUserRoleList(roleList);

        // 装配用户任职所在单位

        // 装配返回
        userFullInfo.setUserId(userInfo.getId());
        userFullInfo.setIdentifier(userInfo.getRealName());
        userFullInfo.setRealName(userInfo.getRealName());
        userFullInfo.setEmployeeCode(employeeCode);
        userFullInfo.setUsername(userInfo.getRealName());
        userFullInfo.setMobile(userInfo.getMobile());
        userFullInfo.setAccountId(userInfo.getAccountId());

        String available = userInfo.getAvailable();
        if (StringUtils.isNotBlank(available)) {
            userFullInfo.setAvailable(UserAvailableEnum.valueOf(available));
        }
        return userFullInfo;
    }

    /**
     * 批量查询 这里 会没有角色
     *
     * @param userInfos \
     * @return \
     */
    @Override
    public List<UserFullInfoDTO> getUserFullInfos(List<UserInfo> userInfos) {
        if (CollUtil.isEmpty(userInfos)) {
            return Collections.emptyList();
        }
        Map<String, UserInfo> userMap = userInfos.stream().collect(Collectors.toMap(UserInfo::getEmployeeCode, e -> e));
        // 获取浙政钉雇员信息 组织信息
        List<String> employeeCodes = userInfos.stream().map(UserInfo::getEmployeeCode).collect(Collectors.toList());
        List<DingEmployeeInfo> dingEmployeeInfoList = iDingEmployeeInfoService
                .list(Wrappers.lambdaQuery(DingEmployeeInfo.class)
                        .in(DingEmployeeInfo::getEmployeeCode, employeeCodes)
                        .eq(DingEmployeeInfo::getMainJob, "true"));

        if (CollUtil.isEmpty(dingEmployeeInfoList)) {
            return Collections.emptyList();
        }

        // 装配用户任职所在单位
        List<String> empPosUnitCodes = dingEmployeeInfoList.stream().map(DingEmployeeInfo::getEmpPosUnitCode).collect(Collectors.toList());
        List<String> orgCodes = dingEmployeeInfoList.stream().map(DingEmployeeInfo::getOrganizationCode).collect(Collectors.toList());
        List<String> allOrgCodes = Stream.concat(empPosUnitCodes.stream(), orgCodes.stream()).collect(Collectors.toList());
        if (CollUtil.isEmpty(allOrgCodes)) {
            return Collections.emptyList();
        }
        List<DingOrganization> dingOrganizations = iDingOrganizationService.listByCodes(allOrgCodes);
        if (CollUtil.isEmpty(dingOrganizations)) {
            return Collections.emptyList();
        }
        Map<String, DingOrganization> orgMap = dingOrganizations.stream().collect(Collectors.toMap(DingOrganization::getOrganizationCode, d -> d));

        return dingEmployeeInfoList.stream().map(e -> {
            UserFullInfoDTO userFullInfo = new UserFullInfoDTO();
            if (orgMap.containsKey(e.getEmpPosUnitCode())) {
                DingOrganization organization = orgMap.get(e.getEmpPosUnitCode());
                userFullInfo.setEmpPosUnitCode(e.getEmpPosUnitCode());
                userFullInfo.setEmpPosUnitName(organization.getOrganizationName());
                userFullInfo.setRegionCode(organization.getDivisionCode());
            }
            if (orgMap.containsKey(e.getOrganizationCode())) {
                DingOrganization organization = orgMap.get(e.getOrganizationCode());
                userFullInfo.setOrganizationCode(organization.getOrganizationCode());
                userFullInfo.setOrganizationName(organization.getOrganizationName());
                // 测试使用
                userFullInfo.setRegionLevel(3);
            }
            if (userMap.containsKey(e.getEmployeeCode())) {
                UserInfo userInfo = userMap.get(e.getEmployeeCode());
                // 装配返回
                userFullInfo.setUserId(userInfo.getId());
                userFullInfo.setIdentifier(userInfo.getRealName());
                userFullInfo.setRealName(userInfo.getRealName());
                userFullInfo.setEmployeeCode(e.getEmployeeCode());
                userFullInfo.setUsername(userInfo.getRealName());
                userFullInfo.setMobile(userInfo.getMobile());
                userFullInfo.setAccountId(userInfo.getAccountId());
                String available = userInfo.getAvailable();
                if (StringUtils.isNotBlank(available)) {
                    userFullInfo.setAvailable(UserAvailableEnum.valueOf(available));
                }
            }
            return userFullInfo;
        }).collect(Collectors.toList());
    }

    @Override
    public String getUserName(Long userId) {
        UserFullInfoDTO userFullInfo = getUserFullInfo(userId);
        return userFullInfo.getRealName();
    }

    @Override
    public boolean isSuperOrRegionAdmin(Long userId) {
        UserFullInfoDTO userFullInfo = getUserFullInfo(userId);
        if (CollUtil.isNotEmpty(userFullInfo.getUserRoleList())) {
            for (Role role : userFullInfo.getUserRoleList()) {
                if (RoleEnum.SUPER_ADMIN.name().equals(role.getCode()) ||
                        RoleEnum.REGION_MANAGER.name().equals(role.getCode())) {
                    return Boolean.TRUE;
                }
            }
        }
        return Boolean.FALSE;
    }

    @Override
    public UserFullInfoDTO getUserFullInfoByEmployeeCode(String employeeCode) {
        UserInfo userInfo = userInfoService.getUserInfoByEmployeeCode(employeeCode);
        return getUserFullInfo(userInfo);
    }

    @Override
    public List<UserFullInfoDTO> getUserFullInfoByEmployeeCodes(Collection<String> employeeCodes) {
        List<UserInfo> userInfos = userInfoService.getUserInfoByEmployeeCodes(employeeCodes);
        return getUserFullInfos(userInfos);
    }

    @Override
    public String getUserEmpPosUnitCode(Long userId) {
        UserFullInfoDTO userFullInfo = getUserFullInfo(userId);
        return userFullInfo.getEmpPosUnitCode();
    }
}
