package com.yida.data.auth.service.impl;

import cc.mrbird.febs.common.redis.service.RedisService;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xkcoding.justauth.AuthRequestFactory;
import com.yida.data.auth.entity.BindUser;
import com.yida.data.auth.manager.UserManager;
import com.yida.data.auth.mapper.RoleMapper;
import com.yida.data.auth.properties.FebsAuthProperties;
import com.yida.data.auth.service.SocialLoginService;
import com.yida.data.auth.service.UserConnectionService;
import com.yida.data.common.core.entity.FebsResponse;
import com.yida.data.common.core.entity.constant.*;
import com.yida.data.common.core.entity.smart.EduSmartWelcomeGuideRosterRelation;
import com.yida.data.common.core.entity.smart.EduSmartWelcomeGuideStep;
import com.yida.data.common.core.entity.system.*;
import com.yida.data.common.core.entity.user.EduStaff;
import com.yida.data.common.core.enums.RoleName;
import com.yida.data.common.core.exception.FebsException;
import com.yida.data.common.core.utils.Asserts;
import com.yida.data.common.core.utils.FebsUtil;
import com.yida.data.common.core.utils.WxPublicUtil;
import com.yida.data.common.core.utils.WxUtil;
import com.yida.data.common.service.CommonService;
import com.yida.data.school.feign.smart.RemoteSmartWelcomeService;
import com.yida.data.system.feign.RemoteDeptService;
import com.yida.data.system.feign.RemoteRoleService;
import com.yida.data.system.feign.RemoteUserService;
import com.yida.data.user.feign.RemoteStaffService;
import com.yida.data.user.feign.RemoteStudentApplyService;
import com.yida.data.user.feign.RemoteStudentService;
import com.yida.data.user.feign.RemoteTeacherService;
import com.yida.data.user.vo.ParentInfoVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.AuthRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.TokenRequest;
import org.springframework.security.oauth2.provider.password.ResourceOwnerPasswordTokenGranter;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author MrBird
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SocialLoginServiceImpl implements SocialLoginService {

    private static final String USERNAME = "username";
    private static final String PASSWORD = "password";
    private static final String NOT_BIND = "not_bind";
    private static final String SOCIAL_LOGIN_SUCCESS = "social_login_success";

    private final UserManager userManager;
    private final RoleMapper roleMapper;
    private final AuthRequestFactory factory;
    private final FebsAuthProperties properties;
    private final PasswordEncoder passwordEncoder;
    private final UserConnectionService userConnectionService;
    private final ResourceOwnerPasswordTokenGranter granter;
    private final RedisClientDetailsService redisClientDetailsService;

    private final RemoteStaffService remoteStaffService;
    private final RemoteStudentService remoteStudentService;
    private final RemoteTeacherService remoteTeacherService;
    private final RemoteSmartWelcomeService remoteSmartWelcomeService;

    private final WxUtil wxUtil;
    private final WxPublicUtil wxPublicUtil;
    private final RedisService redisService;
    private final CommonService commonService;

    @Override
    public AuthRequest renderAuth(String oauthType) throws FebsException {
        return factory.get(getAuthSource(oauthType));
    }

    @Override
    public FebsResponse resolveBind(String oauthType, AuthCallback callback) throws FebsException {
        FebsResponse febsResponse = new FebsResponse();
        AuthRequest authRequest = factory.get(getAuthSource(oauthType));
        AuthResponse<?> response = authRequest.login(resolveAuthCallback(callback));
        if (response.ok()) {
            febsResponse.data(response.getData());
        } else {
            throw new FebsException(String.format("第三方登录失败，%s", response.getMsg()));
        }
        return febsResponse;
    }

    @Override
    public FebsResponse resolveLogin(String oauthType, AuthCallback callback) throws FebsException {
        FebsResponse febsResponse = new FebsResponse();
        AuthRequest authRequest = factory.get(getAuthSource(oauthType));
        AuthResponse<?> response = authRequest.login(resolveAuthCallback(callback));
        if (response.ok()) {
            AuthUser authUser = (AuthUser) response.getData();
            UserConnection userConnection = userConnectionService
                    .selectByCondition(authUser.getSource().toString(), authUser.getUuid());
            if (userConnection == null) {
                febsResponse.message(NOT_BIND).data(authUser);
            } else {
                SystemUser user = userManager.findByName(userConnection.getUserName());
                if (user == null) {
                    throw new FebsException("系统中未找到与第三方账号对应的账户");
                }
                OAuth2AccessToken oAuth2AccessToken = getOauth2AccessToken(user);
                febsResponse.message(SOCIAL_LOGIN_SUCCESS).data(oAuth2AccessToken);
                febsResponse.put(USERNAME, user.getUsername());
            }
        } else {
            throw new FebsException(String.format("第三方登录失败，%s", response.getMsg()));
        }
        return febsResponse;
    }

    @Override
    public OAuth2AccessToken bindLogin(BindUser bindUser, AuthUser authUser) throws FebsException {
        SystemUser systemUser = userManager.findByName(bindUser.getBindUsername());
        if (systemUser == null || !passwordEncoder.matches(bindUser.getBindPassword(), systemUser.getPassword())) {
            throw new FebsException("绑定系统账号失败，用户名或密码错误！");
        }
        this.createConnection(systemUser, authUser);
        return this.getOauth2AccessToken(systemUser);
    }

    @Override
    public OAuth2AccessToken signLogin(BindUser registUser, AuthUser authUser) throws FebsException {
        SystemUser user = this.userManager.findByName(registUser.getBindUsername());
        if (user != null) {
            throw new FebsException("该用户名已存在！");
        }
        String encryptPassword = passwordEncoder.encode(registUser.getBindPassword());
        SystemUser systemUser = this.userManager.registUser(registUser.getBindUsername(), encryptPassword);
        this.createConnection(systemUser, authUser);
        return this.getOauth2AccessToken(systemUser);
    }

    @Override
    public void bind(BindUser bindUser, AuthUser authUser) throws FebsException {
        String username = bindUser.getBindUsername();
        if (isCurrentUser(username)) {
            UserConnection userConnection = userConnectionService
                    .selectByCondition(authUser.getSource().toString(), authUser.getUuid());
            if (userConnection != null) {
                throw new FebsException("绑定失败，该第三方账号已绑定" + userConnection.getUserName() + "系统账户");
            }
            SystemUser systemUser = new SystemUser();
            systemUser.setUsername(username);
            this.createConnection(systemUser, authUser);
        } else {
            throw new FebsException("绑定失败，您无权绑定别人的账号");
        }
    }

    @Override
    public void unbind(BindUser bindUser, String oauthType) throws FebsException {
        String username = bindUser.getBindUsername();
        if (isCurrentUser(username)) {
            this.userConnectionService.deleteByCondition(username, oauthType);
        } else {
            throw new FebsException("解绑失败，您无权解绑别人的账号");
        }
    }

    @Override
    public List<UserConnection> findUserConnections(String username) {
        return this.userConnectionService.selectByCondition(username);
    }

    @Override
    public Map<String, Object> qywxLogin(String code, String state, String corpId, Integer type) {
        log.info("code:{},state:{},corpid:{}", code, state, corpId);
        Dept school = commonService.getSchoolByCorpId(corpId);
        // 获取secret
        EduApp eduApp = commonService.getAppByCodeAndSchool(state, corpId, null);
        log.info("corpId:{},app:{}", corpId, eduApp != null ? eduApp.toString() : "null");
        if (eduApp == null || StrUtil.isBlank(eduApp.getWxSecret())) {
            throw new FebsException("该应用暂未登记");
        }
        // 获取access token
        String accessToken = wxUtil.getAccessToken(corpId, eduApp.getWxSecret());
        // 查询用户信息
        JSONObject user = wxUtil.getUserInfo(accessToken, code);
        log.info("user:[{}]", user);
        // 分别为 企业用户 家长
        ParentInfoVO parent = null;
        EduStaff teacher = null;
        // 家长和教师标识
        Object userId = user.get("UserId");
        Object parentUserid = user.get("parent_userid");
        if (type == 0) {
            if (userId != null) {
                teacher = remoteStaffService
                        .getStaffByWxOrMobileOrOpenId(userId.toString(), null, null, school.getDeptId())
                        .getData();
            } else if (parentUserid != null) {
                // 通过家长信息转化为职工信息
                parent = remoteStudentService.getParentWithStudent(null, parentUserid.toString(),
                        school.getDeptId()).getData();
                if (parent != null) {
                    teacher = remoteStaffService
                            .getStaffByWxOrMobileOrOpenId(null, parent.getMobile(), null, school.getDeptId())
                            .getData();
                }
            }
        } else {
            if (parentUserid != null) {
                parent = remoteStudentService.getParentWithStudent(null, parentUserid.toString(),
                        school.getDeptId()).getData();
            } else if (userId != null) {
                // 通过职工信息转化为家长信息
                teacher = remoteStaffService
                        .getStaffByWxOrMobileOrOpenId(userId.toString(), null, null, school.getDeptId())
                        .getData();
                if (teacher != null) {
                    parent = remoteStudentService.getParentWithStudent(teacher.getMobile(), null,
                            school.getDeptId()).getData();
                }
            }
        }
        if (teacher == null && parent == null) {
            throw new FebsException("该用户暂未注册");
        }
        // 教师用户查询是否绑定手机号（家长必定有手机号）
        if (type == 0 && StrUtil.isBlank(teacher.getMobile())) {
            throw new FebsException("请绑定企业微信手机号");
        }
        redisService.hset(CachePrefixConstant.USER_LOGIN_DEPT, type == 0 ? teacher.getMobile() :
                parent.getMobile(), school.getDeptId());
        // 查询系统用户
        SystemUser systemUser = userManager.findByName(type == 0 ? teacher.getMobile() : parent.getMobile());
        // 系统用户不存在 进行注册
        if (systemUser == null) {
            systemUser = new SystemUser();
            systemUser.setNickname(type == 0 ? teacher.getName() : parent.getMobile());
            systemUser.setUsername(type == 0 ? teacher.getMobile() : parent.getMobile());
            systemUser.setPassword(passwordEncoder.encode(SystemUser.DEFAULT_PASSWORD));
            systemUser.setSex(type == 0 ? teacher.getSex() : "2");
            systemUser.setAvatar(type == 0 ? teacher.getAvatar() : SystemUser.DEFAULT_AVATAR);
            systemUser.setMobile(type == 0 ? teacher.getMobile() : parent.getMobile());
            systemUser.setUserOrigin(0);
            systemUser.setDeptId(school.getDeptId());
            systemUser.setRoleName(type == 0 ? RoleName.STAFF.getName() : RoleName.PARENT.getName());
            systemUser.setUserType(type == 0 ? 1 : 0);
//            systemUser = remoteUserService.addUser(systemUser).getData();
            userManager.registUser(systemUser);
        } else if (!systemUser.getRoleName().contains(type == 0 ? RoleName.STAFF.getName() : RoleName.PARENT.getName())) {
            Role role = roleMapper.selectOne(Wrappers.<Role>lambdaQuery()
                    .eq(Role::getRoleName, type == 0 ? RoleName.STAFF.getName() : RoleName.PARENT.getName()));
            userManager.addRole(systemUser.getUserId(), role.getRoleId());
            systemUser.setRoleId(systemUser.getRoleId() + "," + role.getRoleId());
            systemUser.setRoleName(systemUser.getRoleName() + "," + role.getRoleName());
        }
        // 登录返回token和用户信息
        Map<String, Object> res = new HashMap<>();
        res.put("token", getOauth2AccessToken(systemUser));
        systemUser.setPassword(null);
        systemUser.setIdentityId(type == 0 ? teacher.getId() : parent.getParentId());
        res.put("user", systemUser);
        res.put("identity", type == 0 ? teacher : parent);
        return res;
    }

    @Override
    public Map<String, Object> appLogin(String areaId, Long schoolId, String mobile, String userId,
                                        Integer type) {
        Dept school = commonService.getDept(schoolId);
        Asserts.isNotNull(school, "该学校不存在");
        // 分别为 企业用户 家长
        ParentInfoVO parent = null;
        EduStaff teacher = null;
        // 家长和教师标识
        if (type == 0) {
            teacher = remoteStaffService.getStaffByWxOrMobileOrOpenId(null, mobile, null, school.getDeptId()).getData();
        } else {
            parent = remoteStudentService.getParentWithStudent(mobile, null, school.getDeptId()).getData();
        }
        if (teacher == null && parent == null) {
            throw new FebsException("该用户未注册");
        }
        redisService.hset(CachePrefixConstant.USER_LOGIN_DEPT, type == 0 ? teacher.getMobile() :
                parent.getMobile(), school.getDeptId());
        // 查询系统用户
        SystemUser systemUser = userManager.findByName(type == 0 ? teacher.getMobile() : parent.getMobile());
        // 系统用户不存在 进行注册
        if (systemUser == null) {
//            Role role = remoteRoleService.getRoleByNameNoPermission(type == 0 ? "教师" : "家长").getData();
            systemUser = new SystemUser();
            systemUser.setNickname(type == 0 ? teacher.getName() : parent.getMobile());
            systemUser.setUsername(type == 0 ? teacher.getMobile() : parent.getMobile());
            systemUser.setPassword(passwordEncoder.encode(SystemUser.DEFAULT_PASSWORD));
            systemUser.setSex(type == 0 ? teacher.getSex() : "2");
            systemUser.setAvatar(type == 0 ? teacher.getAvatar() : SystemUser.DEFAULT_AVATAR);
            systemUser.setMobile(type == 0 ? teacher.getMobile() : parent.getMobile());
            systemUser.setUserOrigin(0);
            systemUser.setDeptId(type == 0 ? teacher.getSchoolId() : schoolId);
            systemUser.setRoleName(type == 0 ? RoleName.STAFF.getName() : RoleName.PARENT.getName());
            systemUser.setUserType(type == 0 ? 1 : 0);
            systemUser.setYidaAppUserId(userId);
            userManager.registUser(systemUser);
        } else if (!systemUser.getRoleName().contains(type == 0 ? RoleName.STAFF.getName() : RoleName.PARENT.getName())) {
            Role role = roleMapper.selectOne(Wrappers.<Role>lambdaQuery()
                    .eq(Role::getRoleName, type == 0 ? RoleName.STAFF.getName() : RoleName.PARENT.getName()));
            userManager.addRole(systemUser.getUserId(), role.getRoleId());
            systemUser.setRoleId(systemUser.getRoleId() + "," + role.getRoleId());
            systemUser.setRoleName(systemUser.getRoleName() + "," + role.getRoleName());
        }
        // 用户未绑定appid
        if (type == 0 && teacher.getYidaAppUserId() == null) {
            remoteTeacherService.saveYidaAppUserId(teacher.getId(), userId);
        } else if (type == 1 && parent.getParentYidaAppId() == null) {
            remoteStudentService.saveYidaAppUserId(parent.getParentId(), userId);
        }
        // 登录返回token和用户信息
        Map<String, Object> res = new HashMap<>();
        res.put("token", getOauth2AccessToken(systemUser));
        systemUser.setPassword(null);
        systemUser.setIdentityId(type == 0 ? teacher.getId() : parent.getParentId());
        res.put("user", systemUser);
        res.put("identity", type == 0 ? teacher : parent);
        return res;
    }

//    @Override
//    public Map<String, Object> wxpublicLogin(String code, String appId, Integer type, Long schoolId) {
//        Dept school = null;
//        if (StringUtils.isNotBlank(appId)) {
//            school = commonService.getSchoolByAppId(appId);
//        } else if (Objects.nonNull(schoolId)) {
//            school = commonService.getDept(schoolId);
//        }
//        if (Objects.isNull(school)) {
//            throw new FebsException("学校信息错误");
//        }
//
//        EduDeptWxPublic wxPublic = commonService.getWxPublic(school.getDeptId());
//        // 查询用户信息
//        String openId = wxPublicUtil.getOpenId(wxPublic.getAppId(), wxPublic.getSecret(), code);
//        log.info(openId);
//        // 分别为 企业用户 家长
//        ParentInfoVO parent = null;
//        EduStaff staff = null;
//        if (type == 0) {
//            staff = remoteStaffService.getStaffByWxOrMobileOrOpenId(null, null, openId, school.getDeptId()).getData();
//        } else {
//        }
//        if (staff == null && parent == null) {
//            throw new FebsException("该用户暂未注册");
//        }
//        // 教师用户查询是否绑定手机号（家长必定有手机号）
//        if (type == 0 && StrUtil.isBlank(staff.getMobile())) {
//            throw new FebsException("请绑定手机号");
//        }
//        redisService.hset(CachePrefixConstant.USER_LOGIN_DEPT, type == 0 ? staff.getMobile() :
//                parent.getMobile(), school.getDeptId());
//        // 查询系统用户
//        SystemUser systemUser = userManager.findByName(type == 0 ? staff.getMobile() : parent.getMobile());
//        // 系统用户不存在 进行注册
//        if (systemUser == null) {
////            Role role = remoteRoleService.getRoleByNameNoPermission(type == 0 ? "教师" : "家长").getData();
//            systemUser = new SystemUser();
//            systemUser.setNickname(type == 0 ? staff.getName() : parent.getMobile());
//            systemUser.setUsername(type == 0 ? staff.getMobile() : parent.getMobile());
//            systemUser.setPassword(passwordEncoder.encode(SystemUser.DEFAULT_PASSWORD));
//            systemUser.setSex(type == 0 ? staff.getSex() : "2");
//            systemUser.setAvatar(type == 0 ? staff.getAvatar() : SystemUser.DEFAULT_AVATAR);
//            systemUser.setMobile(type == 0 ? staff.getMobile() : parent.getMobile());
//            systemUser.setUserOrigin(0);
//            systemUser.setDeptId(school.getDeptId());
//            systemUser.setRoleName(type == 0 ? RoleName.STAFF.getName() : RoleName.PARENT.getName());
//            systemUser.setUserType(type == 0 ? 1 : 0);
//            userManager.registUser(systemUser);
//        } else if (!systemUser.getRoleName().contains(type == 0 ? RoleName.STAFF.getName() : RoleName.PARENT.getName())) {
//            Role role = roleMapper.selectOne(Wrappers.<Role>lambdaQuery()
//                    .eq(Role::getRoleName, type == 0 ? RoleName.STAFF.getName() : RoleName.PARENT.getName()));
//            userManager.addRole(systemUser.getUserId(), role.getRoleId());
//            systemUser.setRoleId(systemUser.getRoleId() + "," + role.getRoleId());
//            systemUser.setRoleName(systemUser.getRoleName() + "," + role.getRoleName());
//        }
//        // 登录返回token和用户信息
//        Map<String, Object> res = new HashMap<>();
//        res.put("token", getOauth2AccessToken(systemUser));
//        systemUser.setPassword(null);
//        systemUser.setIdentityId(type == 0 ? staff.getId() : parent.getParentId());
//        res.put("user", systemUser);
//        res.put("identity", type == 0 ? staff : parent);
//        return res;
//    }

    @Override
    public Map<String, Object> wxpublicLogin(String code, String appId, Integer type, Long schoolId, String mobile) {
        Dept school = null;
        if (StringUtils.isNotBlank(appId)) {
            school = commonService.getSchoolByAppId(appId);
        } else if (Objects.nonNull(schoolId)) {
            school = commonService.getDept(schoolId);
        }
        if (Objects.isNull(school)) {
            throw new FebsException("学校信息错误");
        }
        // 查询用户信息
        String openId = wxPublicUtil.getOpenId(school.getWxPublicAppId(), school.getWxPublicSecret(), code);
        // 分别为 企业用户 家长
        ParentInfoVO parent = null;
        EduStaff teacher = null;
        // 家长和教师标识
        if (type == 0) {
            teacher = remoteStaffService.getStaffByWxOrMobileOrOpenId(null, mobile, null, school.getDeptId()).getData();
        } else {
            parent = remoteStudentService.getParentWithStudent(mobile, null, school.getDeptId()).getData();
        }
        if (teacher == null && parent == null) {
            throw new FebsException("该用户暂未注册");
        }
        redisService.hset(CachePrefixConstant.USER_LOGIN_DEPT, type == 0 ? teacher.getMobile() :
                parent.getMobile(), school.getDeptId());

        if (type == 0) {
            teacher.setWxPublicOpenId(openId);
            remoteStaffService.saveWxPublicOpenId(teacher.getId(), openId);
        } else if (type == 1) {
            remoteStudentService.saveWxPublicOpenId(parent.getParentId(), openId);
        }
        // 查询系统用户
        SystemUser systemUser = userManager.findByName(type == 0 ? teacher.getMobile() : parent.getMobile());
        // 系统用户不存在 进行注册
        if (systemUser == null) {
            systemUser = new SystemUser();
            systemUser.setNickname(type == 0 ? teacher.getName() : parent.getMobile());
            systemUser.setUsername(type == 0 ? teacher.getMobile() : parent.getMobile());
            systemUser.setPassword(passwordEncoder.encode(SystemUser.DEFAULT_PASSWORD));
            systemUser.setSex(type == 0 ? teacher.getSex() : "2");
            systemUser.setAvatar(type == 0 ? teacher.getAvatar() : SystemUser.DEFAULT_AVATAR);
            systemUser.setMobile(type == 0 ? teacher.getMobile() : parent.getMobile());
            systemUser.setUserOrigin(0);
            systemUser.setDeptId(school.getDeptId());
            systemUser.setRoleName(type == 0 ? RoleName.STAFF.getName() : RoleName.PARENT.getName());
            systemUser.setUserType(type == 0 ? 1 : 0);
            userManager.registUser(systemUser);
        } else if (!systemUser.getRoleName().contains(type == 0 ? RoleName.STAFF.getName() : RoleName.PARENT.getName())) {
            Role role = roleMapper.selectOne(Wrappers.<Role>lambdaQuery()
                    .eq(Role::getRoleName, type == 0 ? RoleName.STAFF.getName() : RoleName.PARENT.getName()));
            userManager.addRole(systemUser.getUserId(), role.getRoleId());
            systemUser.setRoleId(systemUser.getRoleId() + "," + role.getRoleId());
            systemUser.setRoleName(systemUser.getRoleName() + "," + role.getRoleName());
        }
        // 登录返回token和用户信息
        Map<String, Object> res = new HashMap<>();
        res.put("token", getOauth2AccessToken(systemUser));
        systemUser.setPassword(null);
        systemUser.setIdentityId(type == 0 ? teacher.getId() : parent.getParentId());
        res.put("user", systemUser);
        res.put("identity", type == 0 ? teacher : parent);
        return res;
    }

    private void createConnection(SystemUser systemUser, AuthUser authUser) {
        UserConnection userConnection = new UserConnection();
        userConnection.setUserName(systemUser.getUsername());
        userConnection.setProviderName(authUser.getSource().toString());
        userConnection.setProviderUserId(authUser.getUuid());
        userConnection.setProviderUserName(authUser.getUsername());
        userConnection.setImageUrl(authUser.getAvatar());
        userConnection.setNickName(authUser.getNickname());
        userConnection.setLocation(authUser.getLocation());
        this.userConnectionService.createUserConnection(userConnection);
    }

    private AuthCallback resolveAuthCallback(AuthCallback callback) {
        int stateLength = 3;
        String state = callback.getState();
        String[] strings = StringUtils.splitByWholeSeparatorPreserveAllTokens(state, StringConstant.DOUBLE_COLON);
        if (strings.length == stateLength) {
            callback.setState(strings[0] + StringConstant.DOUBLE_COLON + strings[1]);
        }
        return callback;
    }

    private AuthSource getAuthSource(String type) throws FebsException {
        if (StrUtil.isNotBlank(type)) {
            return AuthSource.valueOf(type.toUpperCase());
        } else {
            throw new FebsException(String.format("暂不支持%s第三方登录", type));
        }
    }

    private boolean isCurrentUser(String username) {
        String currentUsername = FebsUtil.getCurrentUsername();
        return StringUtils.equalsIgnoreCase(username, currentUsername);
    }

    private OAuth2AccessToken getOauth2AccessToken(SystemUser user) throws FebsException {
        final HttpServletRequest httpServletRequest = FebsUtil.getHttpServletRequest();
        httpServletRequest.setAttribute(ParamsConstant.LOGIN_TYPE, SocialConstant.SOCIAL_LOGIN);
        String socialLoginClientId = properties.getSocialLoginClientId();
        ClientDetails clientDetails = null;
        try {
            clientDetails = redisClientDetailsService.loadClientByClientId(socialLoginClientId);
        } catch (Exception e) {
            throw new FebsException("获取第三方登录可用的Client失败");
        }
        if (clientDetails == null) {
            throw new FebsException("未找到第三方登录可用的Client");
        }
        Map<String, String> requestParameters = new HashMap<>(5);
        requestParameters.put(ParamsConstant.GRANT_TYPE, GrantTypeConstant.PASSWORD);
        requestParameters.put(USERNAME, user.getUsername());
        requestParameters.put(PASSWORD, SocialConstant.setSocialLoginPassword());

        String grantTypes = String.join(StringConstant.COMMA, clientDetails.getAuthorizedGrantTypes());
        TokenRequest tokenRequest = new TokenRequest(requestParameters, clientDetails.getClientId(),
                clientDetails.getScope(), grantTypes);
        return granter.grant(GrantTypeConstant.PASSWORD, tokenRequest);
    }

    @Override
    public Map<String, Object> h5Login(Long schoolId, String mobile, Integer type) {
        Dept school = commonService.getDept(schoolId);
        Asserts.isNotNull(school, "该学校不存在");
        // 分别为 企业用户 家长
        ParentInfoVO parent = null;
        EduStaff teacher = null;
        // 家长和教师标识
        if (type == 0) {
            teacher = remoteStaffService.getStaffByWxOrMobileOrOpenId(null, mobile, null, school.getDeptId()).getData();
        } else {
            parent = remoteStudentService.getParentWithStudent(mobile, null, school.getDeptId()).getData();
        }
        if (teacher == null && parent == null) {
            throw new FebsException("该用户未注册");
        }
        redisService.hset(CachePrefixConstant.USER_LOGIN_DEPT, type == 0 ? teacher.getMobile() :
                parent.getMobile(), school.getDeptId());
        // 查询系统用户
        SystemUser systemUser = userManager.findByName(type == 0 ? teacher.getMobile() : parent.getMobile());
        // 系统用户不存在 进行注册
        if (systemUser == null) {
            systemUser = new SystemUser();
            systemUser.setNickname(type == 0 ? teacher.getName() : parent.getMobile());
            systemUser.setUsername(type == 0 ? teacher.getMobile() : parent.getMobile());
            systemUser.setPassword(passwordEncoder.encode(SystemUser.DEFAULT_PASSWORD));
            systemUser.setSex(type == 0 ? teacher.getSex() : "2");
            systemUser.setAvatar(type == 0 ? teacher.getAvatar() : SystemUser.DEFAULT_AVATAR);
            systemUser.setMobile(type == 0 ? teacher.getMobile() : parent.getMobile());
            systemUser.setUserOrigin(0);
            systemUser.setDeptId(type == 0 ? teacher.getSchoolId() : schoolId);
            systemUser.setRoleName(type == 0 ? RoleName.STAFF.getName() : RoleName.PARENT.getName());
            systemUser.setUserType(type == 0 ? 1 : 0);
            userManager.registUser(systemUser);
        } else if (!systemUser.getRoleName().contains(type == 0 ? RoleName.STAFF.getName() : RoleName.PARENT.getName())) {
            Role role = roleMapper.selectOne(Wrappers.<Role>lambdaQuery()
                    .eq(Role::getRoleName, type == 0 ? RoleName.STAFF.getName() : RoleName.PARENT.getName()));
            userManager.addRole(systemUser.getUserId(), role.getRoleId());
            systemUser.setRoleId(systemUser.getRoleId() + "," + role.getRoleId());
            systemUser.setRoleName(systemUser.getRoleName() + "," + role.getRoleName());
        }
        // 登录返回token和用户信息
        Map<String, Object> res = new HashMap<>();
        res.put("token", getOauth2AccessToken(systemUser));
        systemUser.setPassword(null);
        systemUser.setIdentityId(type == 0 ? teacher.getId() : parent.getParentId());
        res.put("user", systemUser);
        res.put("identity", type == 0 ? teacher : parent);
        return res;
    }

    @Override
    public Map<String, Object> checkOpenId(String code, Long deptId) {
        Dept school = commonService.getDept(deptId);
        if (Objects.isNull(school)) {
            throw new FebsException("学校信息错误");
        }
        // 查询用户信息
        String openId = wxPublicUtil.getOpenId(school.getWxPublicAppId(), school.getWxPublicSecret(), code);
        // 查询openId是否绑定了对应的信息
        EduSmartWelcomeGuideRosterRelation relation = remoteSmartWelcomeService.getOpenIdRelation(openId, deptId).getData();
        Map<String, Object> map = new HashMap<>();
        // true代表已经绑定，false代表未绑定
        map.put("status", Objects.nonNull(relation));
        // 微信openId
        map.put("openId", openId);
        return map;
    }

    @Override
    public Map<String, Object> wxPublicLogin(String openId, Long deptId) {
        // 查询关联关系
        EduSmartWelcomeGuideRosterRelation relation = remoteSmartWelcomeService.getOpenIdRelation(openId, deptId).getData();
        if (Objects.isNull(relation) || Objects.isNull(relation.getGuideRoster())) {
            throw new FebsException("信息错误");
        }
        // 用户信息
        SystemUser systemUser = userManager.findByName(relation.getGuideRoster().getMobile());
        // 登录返回token和用户信息
        Map<String, Object> res = new HashMap<>();
        res.put("token", getOauth2AccessToken(systemUser));
        systemUser.setPassword(null);
        res.put("user", systemUser);
//        // 查询人员步骤信息
//        List<EduSmartWelcomeGuideStep> stepList = remoteSmartWelcomeService.listStepInfo(relation.getId(), relation.getGuideId()).getData();
//        relation.setStepList(stepList);
        res.put("info", relation);
        return res;
    }
}
