package org.matrix.local.service;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.matrix.local.entity.Project;
import org.matrix.local.entity.User;
import org.matrix.local.entity.UserProject;
import org.matrix.local.entity.vo.LoginInfo;
import org.matrix.local.entity.vo.UserInfo;
import org.matrix.local.mapper.ProjectMapper;
import org.matrix.local.mapper.UserMapper;
import org.matrix.local.mapper.UserProjectMapper;
import org.matrix.local.util.MD5Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static java.util.Objects.nonNull;

/**
 * 用户相关接口
 */
@Slf4j
@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private ProjectMapper projectMapper;
    @Autowired
    private UserProjectMapper userProjectMapper;

    /**
     * 登录信息缓存Map
     * key为sessionId
     * value为对应的当前登录的user的id
     */
    private Map<String, Long> sessionMap = new HashMap<>();

    /**
     * 用户登录
     * 用户登录成功后 缓存其对应的sessionId到Map中
     *
     * @param loginInfo 用户的账号、密码
     * @param sessionId 对应的sessionId
     * @return 登录是否成功
     */
    public boolean login(LoginInfo loginInfo, String sessionId) {
        String account = loginInfo.getAccount();
        String password = MD5Util.encode(loginInfo.getPassword());
        User user = userMapper.selectOne(Wrappers.<User>lambdaQuery()
                .eq(User::getAccount, account)
                .eq(User::getPassword, password));
        if (nonNull(user)) {
            Long userId = user.getId();
            sessionMap.put(sessionId, userId);
            return true;
        } else {
            return false;
        }
    }

    /**
     * 查询当前登录的用户
     * 输入sessionId 查出其当前登录的user的信息
     *
     * @param sessionId sessionId
     * @return 当前登录的user的信息
     */
    public UserInfo findBySessionId(String sessionId) {
        boolean hasLogin = sessionMap.containsKey(sessionId);
        if (hasLogin) {
            Long userId = sessionMap.get(sessionId);
            User user = userMapper.selectById(userId);
            if (nonNull(user)) {
                return userInfo(user);
            }
        }
        return new UserInfo();
    }

    /**
     * 登出用户
     * 输入sessionId 清除其在Map中的信息
     *
     * @param sessionId sessionId
     */
    public void logout(String sessionId) {
        sessionMap.remove(sessionId);
    }

    //-------------------------------private--------------------------------

    private UserInfo userInfo(User user) {
        List<Project> projects = userProjectMapper.selectList(Wrappers.<UserProject>lambdaQuery().eq(UserProject::getUserId, user.getId())).stream()
                .map(UserProject::getProjectId)
                .map(projectMapper::selectById)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        return new UserInfo(
                user.getId(),
                user.getName(),
                user.getAccount(),
                user.getPassword(),
                projects
        );
    }

}
