package com.dji.sample.manage.service.impl;

import com.auth0.jwt.JWT;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dji.sample.common.model.CustomClaim;
import com.dji.sample.common.util.JwtUtil;
import com.dji.sample.common.util.SecurityUtils;
import com.dji.sample.component.mqtt.config.MqttPropertyConfiguration;
import com.dji.sample.manage.dao.IUserMapper;
import com.dji.sample.manage.model.dto.*;
import com.dji.sample.manage.model.entity.OrgEntity;
import com.dji.sample.manage.model.entity.UserEntity;
import com.dji.sample.manage.model.entity.UserOrgEntity;
import com.dji.sample.manage.model.entity.WorkspaceEntity;
import com.dji.sample.manage.model.enums.RoleTypeEnum;
import com.dji.sample.manage.model.enums.UserTypeEnum;
import com.dji.sample.manage.model.param.searchParam.UserSearchParam;
import com.dji.sample.manage.service.IOrgService;
import com.dji.sample.manage.service.IUserOrgService;
import com.dji.sample.manage.service.IUserService;
import com.dji.sample.manage.service.IWorkspaceService;
import com.dji.sdk.common.HttpResultResponse;
import com.dji.sdk.common.Pagination;
import com.dji.sdk.common.PaginationData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;

import static com.dji.sample.common.util.SecurityUtils.*;

@Service
@Transactional
public class UserServiceImpl extends ServiceImpl<IUserMapper, UserEntity> implements IUserService {

    @Autowired
    private IUserMapper mapper;

    @Autowired
    private MqttPropertyConfiguration mqttPropertyConfiguration;

    @Autowired
    private IOrgService orgService;
    @Autowired
    private IUserOrgService userOrgService;

    @Autowired
    private IWorkspaceService workspaceService;

    @Override
    public HttpResultResponse getUserByUsername(String username, String workspaceId) {

        UserEntity userEntity = this.getUserByUsername(username);
        if (userEntity == null) {
            return new HttpResultResponse()
                    .setCode(HttpStatus.UNAUTHORIZED.value())
                    .setMessage("invalid username");
        }

        UserDTO user = this.entityConvertToDTO(userEntity);
        user.setWorkspaceId(workspaceId);

        return HttpResultResponse.success(user);
    }

    /**
     * Verify the username and password to log in.
     * @param loginDTO
     * @return
     */
    @Override
    public
    HttpResultResponse userLogin(UserLoginDTO loginDTO) {
        String username = loginDTO.getUsername();
        Integer flag = loginDTO.getFlag();
        String password = loginDTO.getPassword();
        String orgId = loginDTO.getOrgId();
        String orgName = loginDTO.getOrgName();
        if (!StringUtils.hasText(loginDTO.getOrgId()) && !StringUtils.hasText(loginDTO.getOrgName())) {
            orgId = "123456";
        }
        // check user
        UserEntity userEntity = this.getUserByUsername(username);
        if (userEntity == null) {
            return new HttpResultResponse()
                    .setCode(HttpStatus.UNAUTHORIZED.value())
                    .setMessage("invalid username");
        }
        // 修改逻辑 跳过web判定
        if (flag != UserTypeEnum.WEB.getVal()) {
            if (flag.intValue() != userEntity.getUserType().intValue()) {
                return HttpResultResponse.error("The account type does not match.");
            }
        }
        // 密码加密验证
        // if (!password.equals(userEntity.getPassword())) {
        if (!SecurityUtils.matchesPassword(password, userEntity.getPassword())) {
            return new HttpResultResponse()
                    .setCode(HttpStatus.UNAUTHORIZED.value())
                    .setMessage("invalid password");
        }

        Optional<WorkspaceDTO> workspaceOpt = workspaceService.getWorkspaceByWorkspaceId(userEntity.getWorkspaceId());
        if (workspaceOpt.isEmpty()) {
            return new HttpResultResponse()
                    .setCode(HttpStatus.UNAUTHORIZED.value())
                    .setMessage("invalid workspace id");
        }

        // 查询 org
        LambdaQueryWrapper<OrgEntity> orgQueryWrapper = new LambdaQueryWrapper<>();
        orgQueryWrapper.eq(OrgEntity::getWorkspaceId, userEntity.getWorkspaceId());
        if (StringUtils.hasText(orgId)) {
            orgQueryWrapper.eq(OrgEntity::getOrgId, orgId);
        } else if (StringUtils.hasText(orgName)) {
            orgQueryWrapper.eq(OrgEntity::getOrgName, orgName);
        } else {
            return new HttpResultResponse()
                    .setCode(HttpStatus.UNAUTHORIZED.value())
                    .setMessage("invalid org info");
        }
        List<OrgEntity> orgEntityList = orgService.list(orgQueryWrapper);
        if (CollectionUtils.isEmpty(orgEntityList)) {
            return new HttpResultResponse()
                    .setCode(HttpStatus.UNAUTHORIZED.value())
                    .setMessage("invalid org id");
        }
        OrgEntity orgEntity = orgEntityList.get(0);
        // 查询权限
        Integer roleType;
        // 系统管理员
        if (userEntity.getRoleType() != null && userEntity.getRoleType() == RoleTypeEnum.SYS_ADMIN.getVal()) {
            roleType = userEntity.getRoleType();
        } else {
            // 团队权限
            LambdaQueryWrapper<UserOrgEntity> userOrgWrapper = new LambdaQueryWrapper<>();
            userOrgWrapper.eq(UserOrgEntity::getUserId, userEntity.getUserId());
            userOrgWrapper.eq(UserOrgEntity::getOrgId, orgEntity.getOrgId());
            List<UserOrgEntity> userOrgEntityList = userOrgService.list(userOrgWrapper);
            if (CollectionUtils.isEmpty(userOrgEntityList)) {
                return new HttpResultResponse()
                        .setCode(HttpStatus.UNAUTHORIZED.value())
                        .setMessage("invalid org role");
            }
            UserOrgEntity userOrgEntity = userOrgEntityList.get(0);
            roleType = userOrgEntity.getRoleType();
        }

        // 创建token
        CustomClaim customClaim = new CustomClaim(userEntity.getUserId(),
                userEntity.getUsername(), userEntity.getUserType(),
                roleType,
                workspaceOpt.get().getWorkspaceId(), orgEntity.getOrgId());

        // create token
        String token = JwtUtil.createToken(customClaim.convertToMap());

        UserDTO userDTO = entityConvertToDTO(userEntity);
        userDTO.setMqttAddr(MqttPropertyConfiguration.getBasicMqttAddress());
        userDTO.setAccessToken(token);
        userDTO.setWorkspaceId(workspaceOpt.get().getWorkspaceId());
        userDTO.setRoleType(roleType);
        userDTO.setOrgId(orgEntity.getOrgId());

        return HttpResultResponse.success(userDTO);
    }

    @Override
    public HttpResultResponse userLogin(String username, String password, Integer flag) {
        // check user
        UserEntity userEntity = this.getUserByUsername(username);
        if (userEntity == null) {
            return new HttpResultResponse()
                    .setCode(HttpStatus.UNAUTHORIZED.value())
                    .setMessage("invalid username");
        }
        // 修改逻辑 跳过web判定
        if (flag != UserTypeEnum.WEB.getVal()) {
            if (flag.intValue() != userEntity.getUserType().intValue()) {
                return HttpResultResponse.error("The account type does not match.");
            }
        }
        // 密码加密验证
        // if (!password.equals(userEntity.getPassword())) {
        if (!SecurityUtils.matchesPassword(password, userEntity.getPassword())) {
            return new HttpResultResponse()
                    .setCode(HttpStatus.UNAUTHORIZED.value())
                    .setMessage("invalid password");
        }

        Optional<WorkspaceDTO> workspaceOpt = workspaceService.getWorkspaceByWorkspaceId(userEntity.getWorkspaceId());
        if (workspaceOpt.isEmpty()) {
            return new HttpResultResponse()
                    .setCode(HttpStatus.UNAUTHORIZED.value())
                    .setMessage("invalid workspace id");
        }

        // 创建token
        CustomClaim customClaim = new CustomClaim(userEntity.getUserId(),
                userEntity.getUsername(), userEntity.getUserType(),
                userEntity.getRoleType(),
                workspaceOpt.get().getWorkspaceId(), null);

        // create token
        String token = JwtUtil.createToken(customClaim.convertToMap());

        UserDTO userDTO = entityConvertToDTO(userEntity);
        userDTO.setMqttAddr(MqttPropertyConfiguration.getBasicMqttAddress());
        userDTO.setAccessToken(token);
        userDTO.setWorkspaceId(workspaceOpt.get().getWorkspaceId());
        return HttpResultResponse.success(userDTO);
    }

    @Override
    public Optional<UserDTO> refreshToken(String token) {
        if (!StringUtils.hasText(token)) {
            return Optional.empty();
        }
        CustomClaim customClaim;
        try {
            DecodedJWT jwt = JwtUtil.verifyToken(token);
            customClaim = new CustomClaim(jwt.getClaims());
        } catch (TokenExpiredException e) {
            customClaim = new CustomClaim(JWT.decode(token).getClaims());
        } catch (Exception e) {
            e.printStackTrace();
            return Optional.empty();
        }
        String refreshToken = JwtUtil.createToken(customClaim.convertToMap());

        UserDTO user = entityConvertToDTO(this.getUserByUsername(customClaim.getUsername()));
        if (Objects.isNull(user)) {
            return Optional.empty();
        }
        user.setWorkspaceId(customClaim.getWorkspaceId());
        user.setAccessToken(refreshToken);
        user.setRoleType(customClaim.getRoleType());
        user.setOrgId(customClaim.getOrgId());
        return Optional.of(user);
    }

    /**
     * Create a user object containing a new token.
     * @param token
     * @return
     */
    @Override
    public Optional<UserDTO> changeOrgRefreshToken(String token, String orgId) {
        if (!StringUtils.hasText(token)) {
            return Optional.empty();
        }
        if (!StringUtils.hasText(orgId)) {
            return Optional.empty();
        }

        CustomClaim customClaim;
        try {
            DecodedJWT jwt = JwtUtil.verifyToken(token);
            customClaim = new CustomClaim(jwt.getClaims());
        } catch (TokenExpiredException e) {
            customClaim = new CustomClaim(JWT.decode(token).getClaims());
        } catch (Exception e) {
            e.printStackTrace();
            return Optional.empty();
        }

        // 查询权限
        Integer roleType;
        // 组织 验证
        customClaim.setOrgId(orgId);
        if (customClaim.getRoleType() == RoleTypeEnum.SYS_ADMIN.getVal()) {
            roleType = customClaim.getRoleType();
        } else {
            // 查询团队权限
            LambdaQueryWrapper<UserOrgEntity> userOrgWrapper = new LambdaQueryWrapper<>();
            userOrgWrapper.eq(UserOrgEntity::getUserId, customClaim.getId());
            userOrgWrapper.eq(UserOrgEntity::getOrgId, orgId);
            List<UserOrgEntity> userOrgEntityList = userOrgService.list(userOrgWrapper);
            if (CollectionUtils.isEmpty(userOrgEntityList)) {
                throw new RuntimeException("invalid org role");
            }
            UserOrgEntity userOrgEntity = userOrgEntityList.get(0);
            roleType = userOrgEntity.getRoleType();
            customClaim.setRoleType(roleType);
        }

        String refreshToken = JwtUtil.createToken(customClaim.convertToMap());

        UserDTO user = entityConvertToDTO(this.getUserByUsername(customClaim.getUsername()));
        if (Objects.isNull(user)) {
            return Optional.empty();
        }
        user.setWorkspaceId(customClaim.getWorkspaceId());
        user.setAccessToken(refreshToken);
        user.setRoleType(roleType);
        user.setOrgId(orgId);
        return Optional.of(user);
    }
    @Override
    public PaginationData<UserListDTO> getUsersByWorkspaceId(long page, long pageSize, String workspaceId) {
        Page<UserEntity> userEntityPage = mapper.selectPage(
                new Page<>(page, pageSize),
                new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getWorkspaceId, workspaceId));

        List<UserListDTO> usersList = userEntityPage.getRecords()
                .stream()
                .map(this::entity2UserListDTO)
                .collect(Collectors.toList());
        return new PaginationData<>(usersList, new Pagination(userEntityPage.getCurrent(), userEntityPage.getSize(), userEntityPage.getTotal()));
    }

    /**
     * Query information about all users.
     * @param workspaceId   uuid
     * @return
     */
    @Override
    public PaginationData<UserListDTO> getUsers(UserSearchParam param, String workspaceId, long page, long pageSize) {
        LambdaQueryWrapper<UserEntity> userQueryWrapper = new LambdaQueryWrapper<>();
        userQueryWrapper.eq(UserEntity::getWorkspaceId, workspaceId);

        // 查询指定 团队的人员
        if (StringUtils.hasText(param.getOrgId())) {
            // 需要增加限制
            LambdaQueryWrapper<UserOrgEntity> userOrgQueryWrapper = new LambdaQueryWrapper<>();
            userOrgQueryWrapper.eq(UserOrgEntity::getWorkspaceId, workspaceId);
            userOrgQueryWrapper.eq(UserOrgEntity::getOrgId, param.getOrgId());
            List<UserOrgEntity> userOrgEntities = userOrgService.list(userOrgQueryWrapper);
            if (CollectionUtils.isEmpty(userOrgEntities)) {
                return new PaginationData<>();
            }
            List<String> userOrgUserIdList = userOrgEntities.stream().map(UserOrgEntity::getUserId).distinct().collect(Collectors.toList());
            if (CollectionUtils.isEmpty(userOrgUserIdList)) {
                return new PaginationData<>();
            }
            userQueryWrapper.in(UserEntity::getUserId, userOrgUserIdList);
        } else {
            // 假如不是 系统管理员 只能查询自己团队的用户
            if (aboveSysAdminRole()) {

            } else {
                String orgId = getOrgId();
                LambdaQueryWrapper<UserOrgEntity> userOrgQueryWrapper = new LambdaQueryWrapper<>();
                userOrgQueryWrapper.eq(UserOrgEntity::getWorkspaceId, workspaceId);
                userOrgQueryWrapper.eq(UserOrgEntity::getOrgId, orgId);
                List<UserOrgEntity> userOrgEntities = userOrgService.list(userOrgQueryWrapper);
                if (CollectionUtils.isEmpty(userOrgEntities)) {
                    return new PaginationData<>();
                }
                List<String> userOrgUserIdList = userOrgEntities.stream().map(UserOrgEntity::getUserId).distinct().collect(Collectors.toList());
                if (CollectionUtils.isEmpty(userOrgUserIdList)) {
                    return new PaginationData<>();
                }
                userQueryWrapper.in(UserEntity::getUserId, userOrgUserIdList);
            }
        }

        Page<UserEntity> userEntityPage = this.page(new Page<>(page, pageSize), userQueryWrapper);
        List<UserListDTO> usersList = userEntityPage.getRecords()
                .stream()
                .map(this::entity2UserListDTO)
                .collect(Collectors.toList());
        return new PaginationData<>(usersList, new Pagination(userEntityPage.getCurrent(), userEntityPage.getSize(), userEntityPage.getTotal()));
    }

    @Override
    public Boolean updateUser(String workspaceId, String userId, UserListDTO user) {
        UserEntity userEntity = mapper.selectOne(
                new LambdaQueryWrapper<UserEntity>()
                        .eq(UserEntity::getUserId, userId)
                        .eq(UserEntity::getWorkspaceId, workspaceId));
        if (userEntity == null) {
            return false;
        }
        userEntity.setMqttUsername(user.getMqttUsername());
        userEntity.setMqttPassword(user.getMqttPassword());
        userEntity.setUpdateTime(System.currentTimeMillis());
        int id = mapper.update(userEntity, new LambdaUpdateWrapper<UserEntity>()
                .eq(UserEntity::getUserId, userId)
                .eq(UserEntity::getWorkspaceId, workspaceId));

        return id > 0;
    }

    @Override
    public Boolean deleteUser(String workspaceId, String userId) {

        // 管理员以上才能删除
        aboveAdminRoleAndThrowError();
//        if (isNotAdmin()) {
//            throw new RuntimeException("The current user is not an admin and has no permissions");
//        }
        LambdaQueryWrapper<UserEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserEntity::getWorkspaceId, workspaceId);
        queryWrapper.eq(UserEntity::getUserId, userId);

        // 需要先查询
        UserEntity userEntity = this.mapper.selectOne(queryWrapper);
        // 不能删除自身
        if (userEntity.getUserId().equals(getUserId())) {
            throw new RuntimeException("can't delete self");
        }
        // 不能删除高级用户
        if (userEntity.getRoleType() == RoleTypeEnum.SYS_ADMIN.getVal()) {
            aboveSysAdminRoleAndThrowError();
        }
//        if (userEntity.getUserType() == UserTypeEnum.WEB.getVal()) {
//            throw new RuntimeException("Failed to delete admin");
//        }
        // 然后 假如是删除管理员 不能删除 项目管理员
        if (userEntity.getRoleType() == RoleTypeEnum.ORG_ADMIN.getVal()) {
            throw new RuntimeException("can't delete workspace project admin");
        }
        if (userEntity.getRoleType() == RoleTypeEnum.ADMIN.getVal()) {
            LambdaQueryWrapper<WorkspaceEntity> workspaceWrapper = new LambdaQueryWrapper<>();
            workspaceWrapper.eq(WorkspaceEntity::getAdminUserId, userEntity.getUserId());
            List<WorkspaceEntity> workspaceEntities = workspaceService.list(workspaceWrapper);
            if (!CollectionUtils.isEmpty(workspaceEntities)) {
                throw new RuntimeException("can't delete workspace admin");
            }
        }

        int delete = mapper.delete(queryWrapper);

        // 删除相关用户组织表
        LambdaQueryWrapper<UserOrgEntity> userOrgQueryWrapper = new LambdaQueryWrapper<>();
        userOrgQueryWrapper.eq(UserOrgEntity::getUserId, userEntity.getUserId());
        userOrgQueryWrapper.eq(UserOrgEntity::getWorkspaceId, userEntity.getWorkspaceId());
        boolean userOrgDelRes = userOrgService.remove(userOrgQueryWrapper);

        return delete > 0;
    }


    @Override
    public Boolean addUser(String workspaceId, UserEntity user) {

        // 管理员才能创建用户
        aboveAdminRoleAndThrowError();

        // 用户名不能重复
        String username = user.getUsername();
        LambdaQueryWrapper<UserEntity> userQueryWrapper = new LambdaQueryWrapper<>();
        userQueryWrapper.eq(UserEntity::getUsername, username);
        // userQueryWrapper.eq(UserEntity::getWorkspaceId, workspaceId);
        List<UserEntity> nameUserList = this.mapper.selectList(userQueryWrapper);
        if (!CollectionUtils.isEmpty(nameUserList)) {
            throw new RuntimeException("the username is already existed");
        }

        UserEntity userEntity = new UserEntity();

        // 普通用户不能创建管理员
//        if (user.getUserType() == UserTypeEnum.WEB.getVal()) {
//            if (isNotAdmin()) {
//                throw new RuntimeException("The current user is not an admin and has no permissions");
//            }
//        }

        // 不能创建高级用户
        if (user.getRoleType() == RoleTypeEnum.SYS_ADMIN.getVal()) {
            aboveSysAdminRoleAndThrowError();
        }

        userEntity.setUserType(user.getUserType() != null ? user.getUserType() : UserTypeEnum.PILOT.getVal());
        userEntity.setRoleType(user.getRoleType() != null ? user.getRoleType() : RoleTypeEnum.MEMBER.getVal());
        userEntity.setUserId(UUID.randomUUID().toString());
        userEntity.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        userEntity.setUsername(user.getUsername());
        userEntity.setWorkspaceId(workspaceId);

        int insert = this.mapper.insert(userEntity);

        // 增加用户权限
        UserOrgEntity userOrgEntity = new UserOrgEntity();
        userOrgEntity.setWorkspaceId(workspaceId);
        userOrgEntity.setOrgId(getOrgId());
        userOrgEntity.setUserId(userEntity.getUserId());
        userOrgEntity.setRoleType(user.getRoleType() != null ? user.getRoleType() : RoleTypeEnum.MEMBER.getVal());
        // private Integer status;
        userOrgEntity.setCreatorId(getUserId());
        userOrgEntity.setCreatorName(getUsername());
        userOrgEntity.setCreateTime(System.currentTimeMillis());
        userOrgEntity.setUpdaterId(getUserId());
        userOrgEntity.setUpdaterName(getUsername());
        userOrgEntity.setUpdateTime(System.currentTimeMillis());
        boolean userOrgSaveRes = userOrgService.save(userOrgEntity);

        return insert > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public UserEntity addWorkspaceAdminUser(UserEntity user) {

        // 系统管理员才能创建
        aboveSysAdminRoleAndThrowError();

        // 用户名不能重复
        String username = user.getUsername();
        LambdaQueryWrapper<UserEntity> userQueryWrapper = new LambdaQueryWrapper<>();
        userQueryWrapper.eq(UserEntity::getUsername, username);
        // userQueryWrapper.eq(UserEntity::getWorkspaceId, user.getWorkspaceId());
        List<UserEntity> nameUserList = this.list(userQueryWrapper);
        if (!CollectionUtils.isEmpty(nameUserList)) {
            throw new RuntimeException("the username is already existed");
        }

        UserEntity userEntity = new UserEntity();

        userEntity.setUserType(UserTypeEnum.WEB.getVal());
        userEntity.setRoleType(RoleTypeEnum.ADMIN.getVal());
        userEntity.setUserId(UUID.randomUUID().toString());
        userEntity.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        userEntity.setUsername(user.getUsername());
        userEntity.setWorkspaceId(user.getWorkspaceId());

        boolean save = this.save(userEntity);

        return userEntity;

    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public UserEntity addOrgAdminUser(UserEntity user) {

        // 系统管理员才能创建
        aboveSysAdminRoleAndThrowError();

        // 判断用户是否存在 用户存在直接返回
        // 用户名不能重复
        String username = user.getUsername();
        LambdaQueryWrapper<UserEntity> userQueryWrapper = new LambdaQueryWrapper<>();
        userQueryWrapper.eq(UserEntity::getUsername, username);
        // userQueryWrapper.eq(UserEntity::getWorkspaceId, user.getWorkspaceId());
        List<UserEntity> nameUserList = this.list(userQueryWrapper);
        if (!CollectionUtils.isEmpty(nameUserList)) {
            // throw new RuntimeException("the username is already existed");
            return nameUserList.get(0);
        }

        UserEntity userEntity = new UserEntity();

        userEntity.setUserType(UserTypeEnum.WEB.getVal());
        // userEntity.setRoleType(RoleTypeEnum.ADMIN.getVal());
        userEntity.setUserId(UUID.randomUUID().toString());
        userEntity.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        userEntity.setUsername(user.getUsername());
        userEntity.setWorkspaceId(user.getWorkspaceId());

        boolean save = this.save(userEntity);

        return userEntity;

    }

    /**
     * Convert database entity objects into user data transfer object.
     * @param entity
     * @return
     */
    private UserListDTO entity2UserListDTO(UserEntity entity) {
        UserListDTO.UserListDTOBuilder builder = UserListDTO.builder();
        if (entity != null) {
            builder.userId(entity.getUserId())
                    .id(entity.getId())
                    .username(entity.getUsername())
                    .mqttUsername(entity.getMqttUsername())
                    .mqttPassword(entity.getMqttPassword())
                    .userType(UserTypeEnum.find(entity.getUserType()).getDesc())
                    .roleTypeName(RoleTypeEnum.find(entity.getRoleType()).getDesc())
                    .roleType(entity.getRoleType())
                    .createTime(LocalDateTime.ofInstant(
                            Instant.ofEpochMilli(entity.getCreateTime()), ZoneId.systemDefault()));
            Optional<WorkspaceDTO> workspaceOpt = workspaceService.getWorkspaceByWorkspaceId(entity.getWorkspaceId());
            workspaceOpt.ifPresent(workspace -> builder.workspaceName(workspace.getWorkspaceName()));
        }

        return builder.build();
    }

    /**
     * Query a user by username.
     * @param username
     * @return
     */
    private UserEntity getUserByUsername(String username) {
        return mapper.selectOne(new QueryWrapper<UserEntity>()
                .eq("username", username));
    }

    /**
     * Query a user by username.
     * @param userId
     * @return
     */
    private UserEntity getUserByUserId(String userId) {
        return mapper.selectOne(new QueryWrapper<UserEntity>()
                .eq("user_id", userId));
    }

    /**
     * Convert database entity objects into user data transfer object.
     * @param entity
     * @return
     */
    private UserDTO entityConvertToDTO(UserEntity entity) {
        if (entity == null) {
            return null;
        }
        return UserDTO.builder()
                .userId(entity.getUserId())
                .username(entity.getUsername())
                .userType(entity.getUserType())
                .roleType(entity.getRoleType())
                .mqttUsername(entity.getMqttUsername())
                .mqttPassword(entity.getMqttPassword())
                .mqttAddr(MqttPropertyConfiguration.getBasicMqttAddress())
                .build();
    }

    /**
     * Query user's details based on userId
     * @param userId
     * @param workspaceId
     * @return
     */
    @Override
    public HttpResultResponse getUserByUserId(String userId, String workspaceId) {

        UserEntity userEntity = this.getUserByUserId(userId);
        if (userEntity == null) {
            return new HttpResultResponse()
                    .setCode(HttpStatus.UNAUTHORIZED.value())
                    .setMessage("invalid userId");
        }

        UserDTO user = this.entityConvertToDTO(userEntity);
        user.setWorkspaceId(workspaceId);

        return HttpResultResponse.success(user);
    }
}
