package org.springblade.openinterface.elevator.util;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springblade.openinterface.elevator.bean.ElevatorApiResultBean;
import org.springblade.openinterface.elevator.bean.ElevatorInfoResultBean;
import org.springblade.openinterface.elevator.conf.ElevatorConfig;
import org.springblade.openinterface.elevator.contants.ElevatorConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.net.URI;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@Component
//@AllArgsConstructor
public class ElevatorUtil {

	@Autowired
	private ElevatorConfig elevatorConfig;
	@Autowired
	private RedisTemplate<String,String> redisTemplate;


	/**
	 * 获取电梯注册码列表
	 * @return
	 */
	public ElevatorApiResultBean getLiftRegCodes(){
		RestTemplate restTemplate = new RestTemplate();

		String token = this.getEffectiveToken();
		String url = elevatorConfig.getUrl() + ElevatorConstants.GET_LIFT_REGCODES + token;
		HttpHeaders headers = createHttpHeaders();
		HttpEntity<String> requestEntity = new HttpEntity<>("", headers);
		URI uri = URI.create(url);
		ParameterizedTypeReference<ElevatorApiResultBean> reference = new ParameterizedTypeReference<ElevatorApiResultBean>() {};
		ResponseEntity<ElevatorApiResultBean> response = restTemplate.exchange(uri, HttpMethod.POST, requestEntity, reference);

		return response.getBody();
	}

	/**
	 * 获取电梯基本信息
	 * @return
	 */
	public ElevatorInfoResultBean getLiftInfo(List<String> registerCodes){
		RestTemplate restTemplate = new RestTemplate();

		String token = this.getEffectiveToken();
		String url = elevatorConfig.getUrl() + ElevatorConstants.GET_LIFT_INFO + token;
		HttpHeaders headers = createHttpHeaders();

		Map<String, Object> params = new HashMap<>();
		params.put("registerCodes", registerCodes);

		HttpEntity<String> requestEntity = new HttpEntity<>(JSONUtil.toJsonStr(params), headers);
		URI uri = URI.create(url);
		ParameterizedTypeReference<ElevatorInfoResultBean> reference = new ParameterizedTypeReference<ElevatorInfoResultBean>() {};
		ResponseEntity<ElevatorInfoResultBean> response = restTemplate.exchange(uri, HttpMethod.POST, requestEntity, reference);

		return response.getBody();
	}

	/**
	 * 获取相机信息
	 * @return
	 */
	public ElevatorApiResultBean getCameraInfo(List<String> registerCodes){
		RestTemplate restTemplate = new RestTemplate();

		String token = this.getEffectiveToken();
		String url = elevatorConfig.getUrl() + ElevatorConstants.GET_CAMERA_INFO + token;
		HttpHeaders headers = createHttpHeaders();

		Map<String, Object> params = new HashMap<>();
		params.put("registerCodes", registerCodes);

		HttpEntity<String> requestEntity = new HttpEntity<>(JSONUtil.toJsonStr(params), headers);
		URI uri = URI.create(url);
		ParameterizedTypeReference<ElevatorApiResultBean> reference = new ParameterizedTypeReference<ElevatorApiResultBean>() {};
		ResponseEntity<ElevatorApiResultBean> response = restTemplate.exchange(uri, HttpMethod.POST, requestEntity, reference);

		return response.getBody();
	}

	/**
	 * 获取电梯历史报警（7天内的电梯历史告警）
	 * @return
	 */
	public ElevatorApiResultBean getLiftHisAlarm(Map<String, Object> params){

		Long endTime = 0L, beginTime = 0L;
		if (params.get("beginTime") == null && params.get("endTime") == null){
			endTime = System.currentTimeMillis() / 1000;
			beginTime = endTime - (7 * 24 * 3600);
		}else{
			if (params.get("beginTime") == null && params.get("endTime") != null){
				endTime = Long.parseLong(params.get("endTime").toString());
				beginTime = endTime - (7 * 24 * 3600);
			}
			if (params.get("endTime") == null && params.get("beginTime") != null){
				beginTime = Long.parseLong(params.get("beginTime").toString());
				endTime = beginTime + (7 * 24 * 3600);
			}
		}
		params.put("beginTime", beginTime.toString());
		params.put("endTime", endTime.toString());
		if (params.get("PageIndex") == null){
			params.put("PageIndex", 1);
		}
		if (params.get("PageSize") == null){
			params.put("PageSize", 100);
		}

		RestTemplate restTemplate = new RestTemplate();

		String token = this.getEffectiveToken();
		String url = elevatorConfig.getUrl() + ElevatorConstants.GET_LIFT_HIS_ALARM + token;
		HttpHeaders headers = createHttpHeaders();

		HttpEntity<String> requestEntity = new HttpEntity<>(JSONUtil.toJsonStr(params), headers);
		URI uri = URI.create(url);
		ParameterizedTypeReference<ElevatorApiResultBean> reference = new ParameterizedTypeReference<ElevatorApiResultBean>() {};
		ResponseEntity<ElevatorApiResultBean> response = restTemplate.exchange(uri, HttpMethod.POST, requestEntity, reference);

		return response.getBody();
	}

	/**
	 * 请求实时视频授权
	 * @return
	 * @param params
	 */
	public ElevatorApiResultBean getRealvideoAuthorization(Map<String, String> params){
		RestTemplate restTemplate = new RestTemplate();
		String token = this.getEffectiveToken();
		String url = elevatorConfig.getUrl() + ElevatorConstants.GET_REAL_VIDEO_AUTHORIZATION + token;
		HttpHeaders headers = createHttpHeaders();
		HttpEntity<String> requestEntity = new HttpEntity<>(JSONUtil.toJsonStr(params), headers);
		URI uri = URI.create(url);
		ParameterizedTypeReference<ElevatorApiResultBean> reference = new ParameterizedTypeReference<ElevatorApiResultBean>() {};
		ResponseEntity<ElevatorApiResultBean> response = restTemplate.exchange(uri, HttpMethod.POST, requestEntity, reference);
		return response.getBody();
	}

	/**
	 * 请求历史告警视频授权
	 * @return
	 * @param params
	 */
	public ElevatorApiResultBean getAlarmVideoAuthorization(Map<String, String> params){
		params.put("authType", "token");
		RestTemplate restTemplate = new RestTemplate();
		String token = this.getEffectiveToken();
		String url = elevatorConfig.getUrl() + ElevatorConstants.GET_ALARM_VIDEO + token;
		HttpHeaders headers = createHttpHeaders();
		HttpEntity<String> requestEntity = new HttpEntity<>(JSONUtil.toJsonStr(params), headers);
		URI uri = URI.create(url);
		ParameterizedTypeReference<ElevatorApiResultBean> reference = new ParameterizedTypeReference<ElevatorApiResultBean>() {};
		ResponseEntity<ElevatorApiResultBean> response = restTemplate.exchange(uri, HttpMethod.POST, requestEntity, reference);
		return response.getBody();
	}

	/**
	 * 获取电梯当前状态
	 * @return
	 */
	public ElevatorApiResultBean getLiftStatus(String registerCode){
		RestTemplate restTemplate = new RestTemplate();

		String token = this.getEffectiveToken();
		String url = elevatorConfig.getUrl() + ElevatorConstants.GET_LIFT_STATUS + token;
		HttpHeaders headers = createHttpHeaders();

		Map<String, Object> params = new HashMap<>();
		params.put("registerCode", registerCode);

		HttpEntity<String> requestEntity = new HttpEntity<>(JSONUtil.toJsonStr(params), headers);
		URI uri = URI.create(url);
		ParameterizedTypeReference<ElevatorApiResultBean> reference = new ParameterizedTypeReference<ElevatorApiResultBean>() {};
		ResponseEntity<ElevatorApiResultBean> response = restTemplate.exchange(uri, HttpMethod.POST, requestEntity, reference);

		return response.getBody();
	}

	/**
	 * 获取电梯环境监测数据
	 * @return
	 */
	public ElevatorApiResultBean getLiftPointData(String registerCode){
		RestTemplate restTemplate = new RestTemplate();

		String token = this.getEffectiveToken();
		String url = elevatorConfig.getUrl() + ElevatorConstants.GET_LIFT_POINT_DATA + token;
		HttpHeaders headers = createHttpHeaders();

		Map<String, Object> params = new HashMap<>();
		params.put("registerCode", registerCode);

		HttpEntity<String> requestEntity = new HttpEntity<>(JSONUtil.toJsonStr(params), headers);
		URI uri = URI.create(url);
		ParameterizedTypeReference<ElevatorApiResultBean> reference = new ParameterizedTypeReference<ElevatorApiResultBean>() {};
		ResponseEntity<ElevatorApiResultBean> response = restTemplate.exchange(uri, HttpMethod.POST, requestEntity, reference);

		return response.getBody();
	}



















	/**
	 * 从接口获取token
	 * @return
	 */
	public Map<String, Object> getToken(){
		HttpHeaders headers = createHttpHeaders();
		RestTemplate restTemplate = new RestTemplate();
		String url = elevatorConfig.getUrl() + ElevatorConstants.GET_TOKEN;

		Map<String, String> map = new HashMap<>();
		map.put("appKey", elevatorConfig.getAppKey());
		map.put("appSecret", elevatorConfig.getAppSecret());

		String params = JSONUtil.toJsonStr(map);
		log.warn("getOpenDoorLogs body >>>>>>>>>> " + params);

		HttpEntity<String> requestEntity = new HttpEntity<>(params, headers);
		URI uri = URI.create(url);
		ParameterizedTypeReference<ElevatorApiResultBean> reference = new ParameterizedTypeReference<ElevatorApiResultBean>() {};
		ResponseEntity<ElevatorApiResultBean> response = null;
		response = restTemplate.exchange(uri, HttpMethod.POST, requestEntity, reference);

		ElevatorApiResultBean responseBody = response.getBody();
		if (responseBody != null && responseBody.getCode().equals(0)){
			 Map<String, Object> data = (Map<String, Object>) responseBody.getData();
			 return data;
		}

		return null;
	}

	/**
	 * 获取有效的token（优先拿缓存）
	 * @return
	 * @throws ParseException
	 */
	public String getEffectiveToken() {
		String accessToken = null;
//		redisTemplate.opsForValue().get();
//		redisTemplate.opsForValue().set();

		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		simpleDateFormat.setTimeZone(TimeZone.getTimeZone("Etc/GMT-8"));

		if (redisTemplate.hasKey(ElevatorConstants.TOKEN_KEY)){
			// 有缓存
			String tokenObjStr = redisTemplate.opsForValue().get(ElevatorConstants.TOKEN_KEY);
			JSONObject jsonObject = JSONUtil.parseObj(tokenObjStr);
			accessToken = jsonObject.get("accessToken").toString();
			String expiresTimeStr = jsonObject.get("expiresTime").toString();

			try {
				Date expiresTime = simpleDateFormat.parse(expiresTimeStr);
				Date now = new Date();
				if (now.before(expiresTime)){
					// 未失效
				}else{
					// 已失效
					accessToken = this.getAndSet2Redis(simpleDateFormat);
				}

			}catch (ParseException e){
				log.error( "时间转换错误！" + e.getMessage());
			}
		}else{
			// 无缓存
			accessToken = this.getAndSet2Redis(simpleDateFormat);
		}

		return accessToken;
	}

	/**
	 * 获取token并存储到redis
	 * @param simpleDateFormat
	 * @return
	 */
	public String getAndSet2Redis(SimpleDateFormat simpleDateFormat){
		String accessToken = null;
		Map<String, Object> tokenObj = this.getToken();
		Integer expiresTime;
		if (tokenObj != null){
			accessToken = tokenObj.get("accessToken").toString();

			expiresTime = (Integer) tokenObj.get("expiresTime");
			// 把失效时间提前两个小时
			String format = simpleDateFormat.format(new Date((expiresTime - 2 * 3600L) * 1000L));
			tokenObj.replace("expiresTime", format);
			redisTemplate.opsForValue().set(ElevatorConstants.TOKEN_KEY, JSONUtil.toJsonStr(tokenObj));
		}
		return accessToken;
	}

	private HttpHeaders createHttpHeaders(){
		HttpHeaders httpHeaders = new HttpHeaders();
		httpHeaders.add(HttpHeaders.CONTENT_TYPE, "application/json");
//		httpHeaders.add("appKey", elevatorConfig.getAppKey());
//		httpHeaders.add("appSecret", elevatorConfig.getAppSecret());
		return httpHeaders;
	}


}
