package com.xjrsoft.module.system.service.impl;

import cn.dev33.satoken.oauth2.logic.SaOAuth2Template;
import cn.dev33.satoken.oauth2.model.SaClientModel;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xjrsoft.common.constant.GlobalConstant;
import com.xjrsoft.common.exception.MyException;
import com.xjrsoft.common.utils.VoToColumnUtil;
import com.xjrsoft.module.organization.entity.Role;
import com.xjrsoft.module.organization.entity.UserRoleRelation;
import com.xjrsoft.module.organization.mapper.RoleMapper;
import com.xjrsoft.module.organization.mapper.UserRoleRelationMapper;
import com.xjrsoft.module.organization.vo.UserRoleVo;
import com.xjrsoft.module.system.entity.OauthClientDetails;
import com.xjrsoft.module.system.service.IOauthClientDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.stream.Collectors;

/**
 * Sa-Token OAuth2.0 整合实现
 */
@Component
public class SaOAuth2TemplateImpl extends SaOAuth2Template {

    @Autowired
    private IOauthClientDetailsService oauthClientDetailsService;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private UserRoleRelationMapper userRoleRelationMapper;

    // 根据 id 获取 Client 信息
    @Override
    public SaClientModel getClientModel(String clientId) {
        OauthClientDetails oauthClientDetails = oauthClientDetailsService.getOne(Wrappers.<OauthClientDetails>query().lambda()
                .eq(OauthClientDetails::getClientId, clientId)
                .eq(OauthClientDetails::getStatus, 1));

        if (oauthClientDetails == null) {
            throw new MyException("找不到此数据");
        }
        return new SaClientModel()
                .setClientId(oauthClientDetails.getClientId())
                .setClientSecret(oauthClientDetails.getClientSecret())
                .setAllowUrl(oauthClientDetails.getAllowUrl())
                .setContractScope(oauthClientDetails.getScope())
                .setIsAutoMode(true);
    }

    // 根据ClientId 和 LoginId 获取openid
    @Override
    public String getOpenid(String clientId, Object loginId) {
        return "";
    }

    // 重写 Access-Token 生成策略：复用登录会话的Token
    @Override
    public String randomAccessToken(String clientId, Object loginId, String scope) {
        String tokenValue = StpUtil.createLoginSession(loginId);

        // 手动授权
        // 获取用户类型（根据固定角色进行匹配）
        List<UserRoleRelation> relations = userRoleRelationMapper.selectList(Wrappers.lambdaQuery(UserRoleRelation.class)
                .select(UserRoleRelation::getRoleId)
                .eq(UserRoleRelation::getUserId, loginId));

        List<Long> relationIds = relations.stream().map(UserRoleRelation::getRoleId).collect(Collectors.toList());

        List<Role> roleList = roleMapper.selectList(Wrappers.lambdaQuery(Role.class)
                .select(Role.class, x -> VoToColumnUtil.fieldsToColumns(UserRoleVo.class).contains(x.getColumn()))
                .in(relationIds.size() > 0, Role::getId, relationIds));

        List<String> roleCodeList = roleList.stream().map(Role::getCode).collect(Collectors.toList());
        List<Long> roleIdList = roleList.stream().map(Role::getId).collect(Collectors.toList());
        SaSession tokenSession = StpUtil.getSessionByLoginId(loginId);
        tokenSession.set(GlobalConstant.LOGIN_USER_ROLE_CODE_KEY, roleCodeList);
        tokenSession.set(GlobalConstant.LOGIN_USER_ROLE_ID_KEY, roleIdList);

        return tokenValue;
    }
}
