package kr.co.uplus.ez.common.components;

import java.util.Date;
import java.util.function.Consumer;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.reactive.function.client.WebClient;

@Service
public class WebClientRequestService {

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

	@Autowired
	private WebClient webClient;

	public Object callBySyncGet(String uri) {
		Date startTime = new Date();
		Object result = webClient.get().uri(uri).retrieve().bodyToMono(Object.class).block();
		log.debug("callBySyncGet duration Time : {}", (new Date().getTime() - startTime.getTime()) / 1000f);
		return result;
	}

	public Object callBySyncPost(String uri, Object param) {
		Date startTime = new Date();
		Object result = webClient.post().uri(uri).bodyValue(param).retrieve().bodyToMono(Object.class).block();
		log.debug("callBySyncPost duration Time : {}", (new Date().getTime() - startTime.getTime()) / 1000f);
		return result;
	}

	public Object callBySyncPut(String uri, Object param) {
		Date startTime = new Date();
		Object result = webClient.put().uri(uri).bodyValue(param).retrieve().bodyToMono(Object.class).block();
		log.debug("callBySyncPut duration Time : {}", (new Date().getTime() - startTime.getTime()) / 1000f);
		return result;
	}

	public Object callBySyncPostWithToken(String uri, String applicationId, String token, Object param) {
		LinkedMultiValueMap<Object, Object> reqHearderMap = new LinkedMultiValueMap<Object, Object>();
		reqHearderMap.add("ApplicationId", applicationId);
		reqHearderMap.add("AuthToken", token);
		Date startTime = new Date();
		log.info(param.toString());
		Object result = webClient.mutate().defaultHeaders(this.setHttpHeader(reqHearderMap)).build().post().uri(uri)
				.contentType(MediaType.APPLICATION_JSON)
				.bodyValue(param).retrieve()
				.bodyToMono(Object.class).block();
		log.info("callBySyncPostWithToken duration Time : {}", (new Date().getTime() - startTime.getTime()) / 1000f);
		return result;
	}

	public Object callBySyncPostWithTokenMultipart(String uri, String applicationId, String token, Object param) {
		LinkedMultiValueMap<Object, Object> reqHearderMap = new LinkedMultiValueMap<Object, Object>();
		reqHearderMap.add("ApplicationId", applicationId);
		reqHearderMap.add("AuthToken", token);
		Date startTime = new Date();
		log.info(param.toString());
		Object result = webClient.mutate().defaultHeaders(this.setHttpHeader(reqHearderMap)).build().post().uri(uri)
				.contentType(MediaType.MULTIPART_FORM_DATA)
				.bodyValue(param).retrieve()
				.bodyToMono(Object.class).block();
		log.info("callBySyncPostWithToken duration Time : {}", (new Date().getTime() - startTime.getTime()) / 1000f);
		return result;
	}


	/**
	 * 헤더 추가.
	 *
	 * @param headerMap
	 * @return Consumer<HttpHeaders>
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public Consumer<HttpHeaders> setHttpHeader(LinkedMultiValueMap headerMap){
		Consumer<HttpHeaders> consumer = it -> it.addAll(headerMap);
		webClient.get().headers(consumer);
		return consumer;
	}
}
