package com.jeelowcode.service.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import com.jeelowcode.service.system.controller.vo.dept.dept.DeptListReqVO;
import com.jeelowcode.service.system.controller.vo.permission.role.RolePageReqVO;
import com.jeelowcode.service.system.controller.vo.user.sync.*;
import com.jeelowcode.service.system.controller.vo.user.user.UserSaveReqVO;
import com.jeelowcode.service.system.entity.AdminUserDO;
import com.jeelowcode.service.system.entity.DeptDO;
import com.jeelowcode.service.system.entity.RoleDO;
import com.jeelowcode.service.system.service.IAdminUserService;
import com.jeelowcode.service.system.service.IDeptService;
import com.jeelowcode.service.system.service.IRoleService;
import com.jeelowcode.service.system.service.IUserSyncService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 主数据同步用户信息接口实现类
 *
 * @author yangchenjj
 */
@Slf4j
@Service
public class UserSyncServiceImpl implements IUserSyncService {

    /**
     * 用户服务，懒加载避免循环依赖
     */
    @Lazy
    @Resource
    private IAdminUserService userService;
    /**
     * 角色服务，懒加载避免循环依赖
     */
    @Lazy
    @Resource
    private IRoleService roleService;
    /**
     * 部门服务，懒加载避免循环依赖
     */
    @Lazy
    @Resource
    private IDeptService deptService;


    /**
     * 从主数据同步用户
     *
     * @param reqVO 请求参数
     * @return 响应结果
     */
    @Override
    @Transactional
    public MasterRespResult syncUser(MasterSystemReqVO reqVO) {
        // 0.1.先检查是否有数据
        if (CollUtil.isEmpty(reqVO.getMasterData())) return MasterRespResult.buildSuccess(Collections.emptyList());
        // 0.2.准备好新用户需要创建的部门信息和角色信息
        List<DeptDO> deptList = deptService.getDeptList(new DeptListReqVO().setName("临时部门"));
        List<RoleDO> roleList = roleService.getRolePage(new RolePageReqVO().setCode("common")).getList();
        Set<Long> roleIds = roleList.stream().map(RoleDO::getId).collect(Collectors.toSet());
        List<UserSaveReqVO.DeptInfo> deptInfoList = deptList.stream().map(dept -> new UserSaveReqVO.DeptInfo()
                        .setDeptId(dept.getId())
                        .setRoleIds(roleIds))
                .collect(Collectors.toList());
        // 1.将数据解析出来，这里采用并行处理，这样可以提升性能
        List<MasterUserResultVO> mdMappings = reqVO.getMasterData().parallelStream().map(md -> {
            String username = getUsername(md);
            // 2.如果用户名为空，则返回数据消费失败结果
            if (StrUtil.isEmpty(username))
                return MasterUserResultVO.buildFail(md.getMdmCode(), reqVO.getMdType(), null);
            AdminUserDO adminUser = userService.getUserByUsername(username);
            if (Objects.isNull(adminUser)) {
                // 这里需要做插入操作
                try {
                    UserSaveReqVO userSaveReqVO = new UserSaveReqVO()
                            .setUsername(username).setNickname(md.getEmpName())
                            .setRemark(md.getDescription()).setEmail(md.getEmail())
                            .setMobile(md.getMobile()).setPassword(username)
                            .setSex(Convert.toInt(md.getSex(), 0))
                            .setTenantId(1L).setDeptInfoList(deptInfoList);
                    Long userId = userService.createUser(userSaveReqVO);
                    return MasterUserResultVO.buildSuccess(md.getMdmCode(), reqVO.getMdType(), String.valueOf(userId));
                } catch (Exception e) {
                    log.error("用户创建失败", e);
                    return MasterUserResultVO.buildFail(md.getMdmCode(), reqVO.getMdType(), null);
                }
            } else {
                // 这里需要做更新操作
                try {
                    UserSaveReqVO userSaveReqVO = new UserSaveReqVO()
                            .setId(adminUser.getId()).setUsername(username)
                            .setNickname(md.getEmpName()).setRemark(md.getDescription())
                            .setEmail(md.getEmail()).setMobile(md.getMobile())
                            .setSex(Convert.toInt(md.getSex(), 0))
                            .setTenantId(1L);
                    userService.updateUser(userSaveReqVO);
                    return MasterUserResultVO.buildSuccess(md.getMdmCode(), reqVO.getMdType(), String.valueOf(adminUser.getId()));
                } catch (Exception e) {
                    log.error("用户更新失败", e);
                    return MasterUserResultVO.buildFail(md.getMdmCode(), reqVO.getMdType(), String.valueOf(adminUser.getId()));
                }
            }
        }).collect(Collectors.toList());
        return MasterRespResult.buildSuccess(mdMappings);
    }


    /**
     * 获取用户名
     *
     * @param masterUser 主数据用户信息
     * @return 用户名
     */
    private String getUsername(MasterUserReqVO masterUser) {
        // 首先获取邮箱，如果邮箱数据存在，则从邮箱中取
        String email = masterUser.getEmail();
        if (StrUtil.isNotEmpty(email) && Validator.isEmail(email)) return email.split("@")[0];
        // 如果邮箱中没有，则从用户信息中取得
        if (CollUtil.isNotEmpty(masterUser.getSubUserInfo())) {
            String username = masterUser.getSubUserInfo().stream()
                    .filter(SubUserReqVO::userIdIsNotEmpty).findFirst()
                    .map(SubUserReqVO::getUserId).orElse(null);
            if (StrUtil.isNotEmpty(username)) return username;
        }
        // 最后，实在找不到，则无法解析到用户名信息，返回null
        return null;
    }

}
