package com.yifu.cloud.plus.v1.yifu.auth.filter;

import com.alibaba.fastjson.JSONObject;
import com.yifu.cloud.plus.v1.yifu.auth.config.WxConfig;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.SecurityConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.security.token.WxAuthenticationToken;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @param
 * @Author: wangan
 * @Date: 2020/7/20
 * @Description: 微信登录
 * @return:
 **/
@Slf4j
public class WxLoginAuthenticationFilter extends AbstractAuthenticationProcessingFilter {


    private static final String SPRING_SECURITY_RESTFUL_LOGIN_URL = "/oauth/wxLogin";

    private boolean postOnly = true;


    private RestTemplate restTemplate = new RestTemplate();

    @Autowired
    private WxConfig wxConfig;

    public WxLoginAuthenticationFilter() {
        super(new AntPathRequestMatcher(SPRING_SECURITY_RESTFUL_LOGIN_URL, "POST"));
    }
    /**
     *
     * @Author pwang
     * @Date 2021-07-23 16:37
     * code 对应的code 必传
     * cleintType 应用类型 非必传applets表示小程序不传调公众号号接口
     * @return  agentId 对应的agentId 非必传 不传查配置的默认应用信息（合同审批）
     **/

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        if (postOnly && !request.getMethod().equals("POST")) {
            throw new AuthenticationServiceException(
                    "Authentication method not supported: " + request.getMethod());
        }
        AbstractAuthenticationToken authRequest;
        String code = obtainParameter(request, "code");
        if (Common.isEmpty(code)) {
            throw new AuthenticationServiceException("未获取到授权码:"+code);
        }
//        String result = restTemplate.getForObject(String.format(SecurityConstants.WX_GET_ACCOSS_TOKEN, wxConfig.getCorpid(), wxConfig.getCorpsecret()), String.class);
//        if (Common.isEmpty(result)) {
//            throw new AuthenticationServiceException("微信授权失败");
//        }
//        String access_token = JSONObject.parseObject(result).getString("access_token");
//        if (Common.isEmpty(access_token)) {
//            throw new AuthenticationServiceException("微信授权失败");
//        }
        String agentId = obtainParameter(request, "agentId");
        String access_token = null;
        if (Common.isNotNull(agentId)) {
            //根据agentId确定corpsecret
            access_token = wxConfig.getAccessToken(restTemplate,agentId);
        }else{
            //兼容老版本写法取默认的corpsecret
            access_token = wxConfig.getAccessToken(restTemplate);
        }
//        log.info("access_token={}", access_token);
        String cleintType = obtainParameter(request, "cleintType");
        String userResult = null;
        if(Common.isNotNull(cleintType)){
            //指定应用类型按参数判断
             if(cleintType.equals(SecurityConstants.WX_APPLETS_KEY)){
                 //小程序
                userResult = restTemplate.getForObject(SecurityConstants.WX_APPLETS_GET_USER_ID, String.class, access_token, code);
             }else{
                throw new AuthenticationServiceException("无此应用类型");
             }
        }else{
            //兼容老逻辑 查公众号接口
             userResult = restTemplate.getForObject(SecurityConstants.WX_GET_USER_ID, String.class, access_token, code);
        }
        if (Common.isEmpty(userResult)) {
            log.info(userResult);
            throw new AuthenticationServiceException("获取企业微信用户失败");
        }

        //log.error(JSONObject.toJSONString(userResult));
        JSONObject jsonObject = JSONObject.parseObject(userResult);
        if (StringUtils.equals(wxConfig.getAccossTokenInvliad(), jsonObject.getString(wxConfig.getErrcode()))) {
            wxConfig.removeAccessToken(agentId);
            log.info(userResult);
            throw new AuthenticationServiceException("无效的微信accoss_token");
        }else if(!StringUtils.equals(wxConfig.getAccossTokenSuccess(), jsonObject.getString(wxConfig.getErrcode()))){
            wxConfig.removeAccessToken(agentId);
            log.info(userResult);
            throw new AuthenticationServiceException("企业微信认证错误，企业微信返回错误码:"+jsonObject.getString(wxConfig.getErrcode())+"（错误码地址：https://work.weixin.qq.com/api/doc/90001/90148/90455）");
        }
        String UserId = null;
        if(Common.isNotNull(cleintType)){
            //指定应用类型按参数判断
            if(cleintType.equals(SecurityConstants.WX_APPLETS_KEY)){
                //小程序
                UserId = jsonObject.getString("userid");
            }else{
                throw new AuthenticationServiceException("无此应用类型");
            }
        }else{
            //兼容老逻辑 查公众号接口
            UserId = jsonObject.getString("UserId");
        }
        if (Common.isEmpty(UserId)) {
            throw new AuthenticationServiceException("微信用户匹配失败");
        }
        log.info("获取企业微信用户====UserId={}", UserId);
        String principal;
        String credentials = null;
        String wxUserId = UserId; //企业微信账号
        principal = wxUserId;

        principal = principal.trim();
        authRequest = new WxAuthenticationToken(principal, credentials);

        // Allow subclasses to set the "details" property
        setDetails(request, authRequest);
        Authentication authenticate = this.getAuthenticationManager().authenticate(authRequest);
        return authenticate;
    }

    private void setDetails(HttpServletRequest request,
                            AbstractAuthenticationToken authRequest) {
        authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
    }

    private String obtainParameter(HttpServletRequest request, String parameter) {
        String result = request.getParameter(parameter);
        return result == null ? "" : result;
    }
}

//            //企业微信登录
//            String wxUserId="1111";
//            principal = wxUserId;
//            credentials = null;
//            authRequest = new WxAuthenticationToken(principal, credentials);

//人力云调用企业微信进行网页授权
//            String result = restTemplate.getForObject("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=wwbcb090af0dfe50e5&corpsecret=R0nKkvsY-oF41fuQvUXZ-kFG3_g_Ce0bpZt6mByx524", String.class);
//            if (Common.isEmpty(result)) {
//                throw new AuthenticationServiceException("微信授权失败");
//            }
//            String access_token = JSONObject.parseObject(result).getString("access_token");
//            if(Common.isEmpty(access_token)){
//                throw new AuthenticationServiceException("微信授权失败");
//            }
//            String userResult = restTemplate.getForObject("https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token={ACCESS_TOKEN}&code=CODE", String.class, access_token);
////            if (Common.isEmpty(userResult)) {
////                throw new AuthenticationServiceException("获取企业微信用户失败");
////            }
////            String UserId = JSONObject.parseObject(userResult).getString("UserId");
//            String UserId="1111";
//            if(Common.isEmpty(UserId)){
//                throw new AuthenticationServiceException("未查询到企业微信用户对应的hr系统用户");
//            }
//            R<SysUser> remoteSysUerR = remoteUserService.getSimpleUserByWxUserId(UserId, SecurityConstants.FROM_IN);
//            if (remoteSysUerR == null) {
//                throw new RuntimeException("调用用户服务失败");
//            }
//            if (CommonConstants.SUCCESS != remoteSysUerR.getCode()) {
//                throw new RuntimeException("调用用户服务返回失败");
//            }
//            SysUser sysUser = remoteSysUerR.getData();
//            if (sysUser == null) {
//                throw new RuntimeException("未查询到用户信息");
//            }
//            //获取用户信息
//            principal = sysUser.getUsername().trim();
//            authRequest = new QrAuthenticationToken(principal, null);
//
//            // Allow subclasses to set the "details" property
//            setDetails(request, authRequest);
//            return this.getAuthenticationManager().authenticate(authRequest);
