package com.cim.idm.mwmsextend.event.consumable;

import com.cim.idm.wmsextend.generic.errorHandler.CustomException;
import com.cim.idm.wmsextend.generic.util.SMessageUtil;
import com.cim.idm.framework.data.EventInfo;
import com.cim.idm.wmspackage.user.UserServiceProxy;
import com.cim.idm.wmspackage.user.management.data.AuthTokenResultModel;
import com.cim.idm.wmspackage.user.management.data.UserInfo;
import com.cim.idm.wmspackage.user.management.data.UserInfoExtend;
import com.cim.idm.wmspackage.user.management.data.UserInfoKey;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;

import org.apache.commons.collections4.MapUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom.Document;
import org.jdom.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.Map;
import java.util.Objects;


public class loginByCodeEvent {
	
	public static Log logger = LogFactory.getLog(loginByCodeEvent.class);

    @Autowired
    private RestTemplate restTemplate;
    

    private static final String SUCCESS_CODE = "200";

    private static final String sysId = "1";
    
    static String client_id = "";
    static String client_secret = "";
    static String url = "";
    
    public loginByCodeEvent() {
    	String mode = System.getProperty("mode");
    	if ("TST".equals(mode)) {
    		client_id = "1e130d3af47544c29fd92fa01a3e61fd";
			client_secret = "ywHLpxzlR4XRxOP0AB5Z";
			url = "http://10.44.254.26/portal/auth/";
    	} else if ("PRD".equals(mode)) {
    		client_id = "b82c48ddf7f646819b9db502f7c1f308";
			client_secret = "RUCL6Pi629Gin6QJmMSZ";
			url = "http://10.45.128.178/portal/auth/";
    	}
    }
    
	public void event(EventInfo eventInfo, Document message) throws Exception {
		Element root = message.getDocument().getRootElement();
		Element body = root.getChild("Body");
		String sendSubjectName = root.getChild("Header").getChildText("ORIGINALSOURCESUBJECTNAME");
		String code = SMessageUtil.getElementValueByName(body, "CODE");
		String redirect_uri = SMessageUtil.getElementValueByName(body, "REDIRECT_URI");
		
		AuthTokenResultModel authTokenResultModel = this.loginByCode(code,redirect_uri);
        String userAccount = this.checkToken(authTokenResultModel.getAccess_token());
        UserInfoKey userProfileKey = new UserInfoKey();
        userProfileKey.setUserId(userAccount);
        UserInfo userInfo = UserServiceProxy.getUserInfoService().selectByKey(userProfileKey);
        if (!Objects.isNull(userInfo)) {
            UserInfoExtend userInfoExtend = new UserInfoExtend(userInfo);
            userInfoExtend.setAuthTokenResultModel(authTokenResultModel);
            
            Element userIDElement = new Element("USERID");
            userIDElement.setText(userInfoExtend.getKey().getUserId());
            body.addContent(userIDElement);
            
            Element userNameElement = new Element("USERNAME");
            userNameElement.setText(userInfoExtend.getUserName());
            body.addContent(userNameElement);
            
            Element userSiteElement = new Element("SITENAME");
            userSiteElement.setText(userInfoExtend.getSiteName());
            body.addContent(userSiteElement);
            
            Element userGroupElement = new Element("USERGROUPNAME");
            userGroupElement.setText(userInfoExtend.getUserGroupName());
            body.addContent(userGroupElement);
            
            Element phoneElement = new Element("PHONENUMBER");
            phoneElement.setText(userInfoExtend.getPhoneNumber());
            body.addContent(phoneElement);
            
            return;
        }
        return ;
	}
	
	public AuthTokenResultModel loginByCode(String code, String redirect_uri) throws Exception {
        MultiValueMap<String,String> paramMap = new LinkedMultiValueMap<>();
        paramMap.add("grant_type", "authorization_code");
        paramMap.add("code", code);
        paramMap.add("redirect_uri", redirect_uri);
        paramMap.add("client_id", client_id);
        logger.info("client_id" + "========>" + client_id);
        paramMap.add("client_secret", client_secret);
        logger.info("client_secret" + "========>" + client_secret);
//        paramMap.add("scope", "openid");

        return this.getAuthToken(paramMap);
    }
	
	private  AuthTokenResultModel getAuthToken(MultiValueMap<String,String> paramMap) throws Exception{
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(paramMap, headers);
        ResponseEntity<AuthTokenResultModel> response = null;
        try {
            response = restTemplate.postForEntity(url + "oauth2/token", request, AuthTokenResultModel.class);
        } catch (Exception e){
            logger.error("portal login error",e);
            throw new CustomException("",new Object[]{e.getMessage()});
        }
        AuthTokenResultModel body = response.getBody();
        if(body == null){
            return null;
        }
        JWT jwt = JWTUtil.parseToken(body.getAccess_token());
        JSONObject accessInfo = JSONUtil.parseObj(jwt.getPayload().toString());
        body.setUserCode(accessInfo.getStr("sub"));
        return body;
    }
	
	public String checkToken(String token) throws Exception {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add("Authorization", "Bearer " + token);
        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(new LinkedMultiValueMap<>(), headers);
        ResponseEntity<String> response = null;
        try {
            response = restTemplate.postForEntity(url + "api/user/token/check", request, String.class);
        } catch (Exception e){
            throw new CustomException("",new Object[]{e.getMessage()});
        }
        Map<String,Object> result = JSONUtil.parseObj(response.getBody());
        return MapUtils.getString(result,"data");
    }
	
}

