package cokr.xit.ens.modules.example.api;

import cokr.xit.ens.core.exception.EnsException;
import cokr.xit.ens.core.exception.code.EnsErrCd;
import cokr.xit.ens.core.utils.CmmnUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@RestController
public class ClientController {

	@Value("${contract.kakao.pay.mydoc.access-token}")
	private String ACCESS_TOKEN;
	private String HOST = "http://localhost:18090" ;
	
	@PostMapping("/example/client/ok")
	private ResponseEntity<String> ok(@RequestBody Map<String, Object> reqDTO ) throws Exception {
		if(reqDTO ==null)
			reqDTO = createParam();
		
		log.info(String.format("called %s.%s", getClass().getName(), new Object() {}.getClass().getEnclosingMethod().getName()));
		log.info(String.format("request parameters... %s", CmmnUtil.toJsonString(reqDTO)));
		
		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
		ResponseEntity<String> resp = this.sendData(HttpMethod.POST, "/example/server/ok", CmmnUtil.toJsonString(reqDTO), headers);

		String body = resp.getBody();
		log.info(String.format("body:::%s", body));
		return resp;
	}
	@PostMapping("/example/client/err400")
	private ResponseEntity<String> err400(@RequestBody Map<String, Object> reqDTO ) throws Exception {
		
		log.info(String.format("called %s.%s", getClass().getName(), new Object() {}.getClass().getEnclosingMethod().getName()));
		log.info(String.format("request parameters... \n%s", CmmnUtil.toJsonString(reqDTO)));
		
		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
		ResponseEntity<String> resp = this.sendData(HttpMethod.POST, "/example/server/err400", CmmnUtil.toJsonString(reqDTO), headers);

		return resp;
		
	}
	@PostMapping("/example/client/err500")
	private ResponseEntity<String> err500(@RequestBody Map<String, Object> reqDTO ) throws Exception {
		
		log.info(String.format("called %s.%s", getClass().getName(), new Object() {}.getClass().getEnclosingMethod().getName()));
		log.info(String.format("request parameters... %s", CmmnUtil.toJsonString(reqDTO)));
		
		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
		ResponseEntity<String> resp = this.sendData(HttpMethod.POST, "/example/server/err500", CmmnUtil.toJsonString(reqDTO), headers);
		
		return resp;
		
	}
	
	private Map<String, Object> createParam() {

		Map<String, Object> data = new HashMap<>();
		data.put("param1", 123);
		data.put("param2", "abc");
		data.put("param3", 10L);

		return data;
	}
	
	/**
	 * 데이터 전송
	 * @param method
	 * @param uri
	 * @param param
	 * @param headers
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings({ "unchecked" })
	protected ResponseEntity<String> sendData(HttpMethod method, String uri, String param, HttpHeaders headers) throws Exception{
        if((this.ACCESS_TOKEN == null || this.ACCESS_TOKEN.length() < 5) && !uri.endsWith("ping"))	//ping 확인 서비스를 제외한 서비스에 대해 엑세스토큰이 없을 경우.. 
            throw new IOException("AccessToken is null!");
		

        if(headers==null)
        	headers = new HttpHeaders();
        headers.set("Authorization", String.format("Bearer %s", this.ACCESS_TOKEN));	//access token 설정
		

		Map<String, Object> resp = CmmnUtil.callApi(method, this.HOST+uri, param, headers);	
		

		
		if(!"OK".equals(resp.get("resCd")))
			throw new EnsException(EnsErrCd.valueOf((String) resp.get("resCd")), String.format("API 호출 실패. %s", resp.get("resMsg")));
		
		return (ResponseEntity<String>) resp.get("responseEntity");
	}
}
