package org.springblade.modules.nh.factory.goodwe.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import okhttp3.*;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springblade.core.redis.cache.BladeRedis;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.modules.nh.factory.common.EzTemplateBase;
import org.springblade.modules.nh.factory.goodwe.GoodweRet;
import org.springblade.modules.nh.factory.goodwe.dto.GoodweApiReq;
import org.springblade.modules.nh.factory.goodwe.dto.gettoken.GetTokenR;
import org.springblade.modules.nh.factory.goodwe.dto.gettoken.GetTokenReq;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.BufferingClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClientException;

import java.io.IOException;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Function;

@Service
public class GoodweApiRestTemplate extends EzTemplateBase {

	private String redisTokenKey = "GOODWE_TOKEN";

	private String redisIndexKey = "GOODWE_INDEX_KEY";

	@Autowired
	private BladeRedis redis;

	private static final Logger log = LoggerFactory.getLogger(GoodweApiRestTemplate.class);

	public GoodweApiRestTemplate() {
		super(createRestTemplate(createHttpRequestFactory()));
	}

	protected static ClientHttpRequestFactory createHttpRequestFactory() {
		return new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory());
	}

	@Override
	public <T> T postJson(int index, String url, Object data, ParameterizedTypeReference<T> responseType, Object... uriVariables) {
		try{
			redis.set(redisIndexKey,index);
			T r =  super.postJson(url, data, responseType, uriVariables);
			if(r instanceof GoodweRet){
				GoodweRet ret = (GoodweRet) r;
				if(ret.getCode()==100002){
					redis.del(redisTokenKey+"_"+index);
					return super.postJson(url, data, responseType, uriVariables);
				}
			}
			return r;
		}catch (Exception e){
			logger.error("postJson error:{}", e);
			return null;
		}
	}

	@Override
	public <T> T get(int index,String url, Map<String, ?> uriVariables, ParameterizedTypeReference<T> responseType) throws RestClientException {
		try{
			redis.set(redisIndexKey,index);
			T r =  super.get(url, uriVariables, responseType);
			if(r instanceof GoodweRet){
				GoodweRet ret = (GoodweRet) r;
				if(ret.getCode()==100002){
					redis.del(redisTokenKey+"_"+index);
					return super.get(url,uriVariables, responseType);
				}
			}
			return r;
		}catch (Exception e){
			logger.error("postJson error:{}", e);
			return null;
		}
	}

	@Override
	protected <K> void callHeaders(String url, String data, HttpHeaders headers) {
		int index = redis.get(redisIndexKey);
		headers.set("token", getAuthorization(index));
	}

	public synchronized String getAuthorization(int index) {
		String redisKey = redisTokenKey+"_"+(index);
		String authorization = redis.get(redisKey);
		if(StringUtil.isNotBlank(authorization)){
			return authorization;
		}
		GetTokenReq req = new GetTokenReq();
		switch (index){
			case 1:{
				req.setAccount("15362141430");
				req.setPwd("123456");
			};break;
			case 2:{
				req.setAccount("18115811578");
				req.setPwd("123456");
			};break;
			case 3:{
				req.setAccount("17712135319");
				req.setPwd("nh123456");
			};break;
			default:{
				req.setAccount("15362141430");
				req.setPwd("123456");
			};break;
		}
		authorization = getToken(req);
		if(StringUtil.isNotBlank(authorization)){
			redis.setEx(redisKey,authorization,600L);
		}

		return authorization;

	}

	public String getToken(GetTokenReq req) {
		String token = null;
		String authUrl = "http://openapi.sems.com.cn/api/OpenApi/GetToken";
		RequestBody body = RequestBody.create(JSON.toJSONString(req), MediaType.get("application/json; charset=utf-8"));
		Request request = new Request.Builder()
			.url(authUrl)
			.post(body)
			.build();
		OkHttpClient client = new OkHttpClient().newBuilder().build();
		Call call = client.newCall(request);
		try{
			Response response = call.execute();
			Headers headers = response.headers();
			String jsonStr = response.body().string();
			JSONObject jsonObject = JSON.parseObject(jsonStr);
			int code = jsonObject.getIntValue("code");
			if(code==0){
				token = jsonObject.getJSONObject("data").getString("token");
			}
		}catch (IOException ioException){
			logger.error("华为逆变器登录异常报错：{}",ioException);
		}
		return token;
	}
}
