package org.security.singleSignOn.service.impl;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.security.config.AuthorizeConfig;
import org.security.desk.esb.request.EsbRequest;
import org.security.singleSignOn.entity.SingleSignOnResponse;
import org.security.singleSignOn.service.SingleSignOnService;
import org.springblade.core.tool.utils.Func;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;

/**
 * @author ：wzf
 * @apiNote ：单点登录
 * @since ：Created in 2022/11/25 15:07
 */
@Service
@Slf4j
@AllArgsConstructor
public class SingleSignOnServiceImpl implements SingleSignOnService {

	private final AuthorizeConfig authorizeConfig;

	@Override
	public String getCode() {
		Random random = new Random();
		int state = random.nextInt(900) + 100;
		StringBuilder builder = new StringBuilder();
		builder.append("redirect:")
			.append(authorizeConfig.getAuthUrl())
			.append("?")
			.append("&redirect_uri=")
			.append(authorizeConfig.getRedirectUri())
			.append("&client_id=")
			.append(authorizeConfig.getClientId())
			.append("&response_type=")
			.append(authorizeConfig.getResponseType())
			.append("&state=")
			.append(state);
		return builder.toString();
	}

	@Override
	public String getAimToken(String code, String state) {
		if (Func.isBlank(code) || Func.isBlank(state)) {
			return null;
		}
		log.info("获取授权的code值：[{}],state值：[{}]",code,state);
		JSONObject reqBody = new JSONObject();
		reqBody.put("ConsumerSeqNo", authorizeConfig.getClientId());
		reqBody.put("ChkNo", authorizeConfig.getClientSecret());
		reqBody.put("SndTp", "authorization_code");
		reqBody.put("TxnCd", code);
		reqBody.put("Sts", state);
		// SingleSignOnDTO signOnDTO = new SingleSignOnDTO();
		// signOnDTO.setConsumerSeqNo(authorizeConfig.getClientId());
		// signOnDTO.setChkNo(authorizeConfig.getClientSecret());
		// signOnDTO.setSndTp("authorization_code");
		// signOnDTO.setTxnCd(code);
		// signOnDTO.setSts(state);
		//查询授权信息(从esb获取用户工号信息)
		log.info("------------------上esb获取用户授权信息开始------------------");
		HttpRequest post = HttpUtil.createPost(authorizeConfig.getAuthResUrl());
		String bodyStr = JSONUtil.toJsonStr(EsbRequest.creatEsbRequest(authorizeConfig.getScvcd(), "01", authorizeConfig.getChnlTp(), reqBody));
		log.info("------------------request body:");
		log.info(bodyStr);
		post.body(bodyStr);
		HttpResponse httpResponse = post.execute();
		log.info("上esb获取用户授权信息返回结果：[{}]",httpResponse);
		log.info("------------------上esb获取用户授权信息开始------------------");
		SingleSignOnResponse signOnResponse = JSONUtil.toBean(httpResponse.body(), SingleSignOnResponse.class);
		log.info("单点登录授权返回：[{}]，用户工号为:[{}]", signOnResponse,signOnResponse.getBODY().getUsrNo());
		SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
		factory.setReadTimeout(10000);
		factory.setConnectTimeout(10000);
		RestTemplate template = new RestTemplate(factory);

		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
		headers.add("Accept", MediaType.APPLICATION_JSON.toString());
		headers.add("Authorization", "Basic c2FiZXI6c2FiZXJfc2VjcmV0");
		headers.add("Tenant-Id", "000000");
		MultiValueMap<String, String> userMap = new LinkedMultiValueMap<>();
		userMap.add("tenantId", "000000");
		userMap.add("username", signOnResponse.getBODY().getUsrNo());
		// userMap.add("username", "admin");
		userMap.add("grant_type", "singleSignOn");
		userMap.add("scope", "all");
		userMap.add("type", "account");
		HttpEntity<MultiValueMap<String, String>> userHttpEntity = new HttpEntity<>(userMap, headers);
		log.info(">>>>>> userHttpEntity：");
		log.info(JSONObject.toJSONString(userHttpEntity));
		ParameterizedTypeReference<Map<String, String>> userTypeRef =
			new ParameterizedTypeReference<Map<String, String>>() {
			};
		Map<String, String> userResponse = new HashMap<>();
		log.info(">>>>>> 获取token url：" + authorizeConfig.getUserUrl());
		try {
			userResponse = template.exchange(authorizeConfig.getUserUrl(), HttpMethod.POST, userHttpEntity, userTypeRef).getBody();
		} catch (ResourceAccessException e) {
			userResponse.put("failed", e.getMessage());
		}
		log.info(userResponse.toString());
		List<String> stringList = new ArrayList<String>();
		try {
			for (Map.Entry entry : userResponse.entrySet()) {
				if (null != entry.getValue()) {
					stringList.add(entry.getKey() + "=" + URLEncoder.encode((String) entry.getValue(), "UTF-8"));
				}

			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			userResponse.put("failed", e.getMessage());
		}
		String res = StringUtils.join(stringList, '&');
		//重定向
		return "redirect:" + authorizeConfig.getIndexUrl() + "?" + res;
	}
}
