package com.style24.core.biz.thirdparty;

import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import com.style24.persistence.domain.Erp;

import lombok.extern.slf4j.Slf4j;

import com.gagaframework.web.parameter.GagaMap;
import com.gagaframework.web.util.GagaStringUtil;

/**
 * 한세MK와 한세드림 ERP
 * 
 * @author gagamel
 * @since 2021. 6. 7
 */
@Component
@Slf4j
public class HansaeErp {

	// 상품 URL
	private String goodsUrl = "http://erp.hansaemk.com:96/api/#{erpGb}/Shop/GoodsInfo";

	// 재고 URL
	private String stockUrl = "http://erp.hansaemk.com:96/api/#{erpGb}/Shop/StockCheck";

	// RT URL
	private String stockRtUrl = "http://erp.hansaemk.com:96/api/#{erpGb}/Shop/StockRTConfirm";

	// 매출반영 URL
	private String salesUrl = "http://erp.hansaemk.com:96/api/#{erpGb}/Shop/SaleIF";

	@Autowired
	private RestTemplate restTemplate;

	@PostConstruct
	public void init() {
		log.info("\n\n---- HansaeErp initialization started ----");
		log.info("goodsUrl: [{}]", goodsUrl);
		log.info("stockUrl: [{}]", stockUrl);
		log.info("salesUrl: [{}]", salesUrl);
		log.info("\n--- HansaeErp initialization completed ----\n");
	}

	// ERP구분
	public enum ErpGb {
		HANSAE_MK("hsmk"),	// 한세MK
		HANSAE_DR("hsdr");	// 한세드림

		private String value;

		ErpGb(String value) {
			this.value = value;
		}

		public String value() {
			return value;
		}
	}

	/**	
	 * ERP 상품별 매장재고 목록
	 * @param erpGb - ERP구분(hsmk:한세MK, hsdr:한세드림)
	 * @return 
	 * @author moon
	 * @since  2021. 03. 28
	 */
	public Collection<Erp> getErpGoodsStockList(String erpGb) {
		Collection<Erp> stockList = new ArrayList<>();

		try {
			String requestUrl = GagaStringUtil.replace(goodsUrl, "#{erpGb}", erpGb);
			log.info("requestUrl: {}", requestUrl);

			URI url = URI.create(requestUrl);

			// GET 방식으로 호출
			ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);
			log.info("responseEntity.getStatusCode(): {} ", responseEntity.getStatusCode());

			String jsonResult = responseEntity.getBody();
			log.info("responseEntity.getBody(): {}", jsonResult);

			Gson gson = new Gson();
			GagaMap resultMap = gson.fromJson(jsonResult, GagaMap.class);

			if (resultMap.containsKey("GoodsInfo")) {
				// 상품별 매장재고 정보
				String goodsInfo = resultMap.get("GoodsInfo").toString();
				log.info("goodsInfo: {}", goodsInfo);

				if (StringUtils.isNotBlank(goodsInfo)) {
					List<Map<String, Object>> dataList = gson.fromJson(goodsInfo, new TypeToken<List<Map<String, Object>>>() {
					}.getType());

					for (int i = 0; i < dataList.size(); i++) {
						Map<String, Object> data = dataList.get(i);
						Erp stock = new Erp();
						stock.setCD_STYLE(data.get("CD_STYLE").toString());
						stock.setCD_COLOR(data.get("CD_COLOR").toString());
						stock.setCD_SIZE(data.get("CD_SIZE").toString());
						stock.setCD_SHOP(data.get("CD_SHOP").toString());
						stock.setQT_STOCK((int)Double.parseDouble(data.get("QT_STOCK").toString()));
						stockList.add(stock);
					}
				}
			}
		} catch (Exception e) {
			log.error("{}", e.getMessage().toString());
		}

		return stockList;
	}

	/**
	 * ERP 매장 실재고 목록
	 * @param erpGb - ERP구분(hsmk:한세MK, hsdr:한세드림)
	 * @param styleCd - 스타일코드
	 * @param colorCd - 색상코드
	 * @param sizeCd - 사이즈코드
	 * @return
	 * @author moon
	 * @since 2021. 03. 29
	 */
	public Collection<Erp> getErpRealStockList(String erpGb, String styleCd, String colorCd, String sizeCd) {
		Collection<Erp> stockList = new ArrayList<>();

		try {
			String requestUrl = GagaStringUtil.replace(stockUrl, "#{erpGb}", erpGb) + "?CD_STYLE=" + styleCd + "&CD_COLOR=" + colorCd + "&CD_SIZE=" + sizeCd;
			log.info("requestUrl: {}", requestUrl);

			URI url = URI.create(requestUrl);

			// GET 방식으로 호출
			ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);
			log.info("responseEntity.getStatusCode(): {} ", responseEntity.getStatusCode());

			String jsonResult = responseEntity.getBody();
			log.info("responseEntity.getBody(): {}", jsonResult);

			Gson gson = new Gson();
			GagaMap resultMap = gson.fromJson(jsonResult, GagaMap.class);

			if (resultMap.containsKey("StockCheck")) {
				// 재고 정보
				String stockCheck = resultMap.get("StockCheck").toString();
				log.info("stockCheck: {}", stockCheck);

				if (StringUtils.isNotBlank(stockCheck)) {
					List<Map<String, Object>> dataList = gson.fromJson(stockCheck, new TypeToken<List<Map<String, Object>>>() {
					}.getType());

					for (int i = 0; i < dataList.size(); i++) {
						Map<String, Object> data = dataList.get(i);
						Erp stock = new Erp();
						stock.setStockLoc(data.get("CD_SHOP").toString());
						stock.setLocQty((int)Double.parseDouble(data.get("QT_STOCK").toString()));
						stockList.add(stock);
					}
				}
			}
		} catch (Exception e) {
			log.error("{}", e.getMessage().toString());
		}

		return stockList;
	}

	/**
	 * ERP 매출반영
	 * @param erpGb - ERP구분(hsmk:한세MK, hsdr:한세드림)
	 * @param salesList - 매출 목록
	 * @return 매출반영 결과
	 * 		사용예)
	 * 			GagaMap salesMap = HansaeErp.uploadErpSales(HansaeErp.ErpGb.HANSAE_MK.value(), salesList);
	 * 			Collection<Map<String, Object>> succList = (Collection<Map<String, Object>>) salesMap.get("succList");
	 * 			if (succList != null && !succList.isEmpty()) {
	 * 				...
	 * 			}
	 * 			Collection<Map<String, Object>> failList = (Collection<Map<String, Object>>) salesMap.get("failList");
	 * 			if (failList != null && !failList.isEmpty()) {
	 * 				...
	 * 			}
	 * @author gagamel
	 * @since 2021. 6. 8
	 */
	@SuppressWarnings("unchecked")
	public GagaMap uploadErpSales(String erpGb, Collection<GagaMap> salesList) {
		GagaMap salesMap = new GagaMap();

		try {
			if (salesList == null || salesList.isEmpty()) {
				return salesMap;
			}

			HttpHeaders headers = new HttpHeaders();
			headers.setContentType(MediaType.APPLICATION_JSON);

			// Parameter
			String requestData = (new Gson()).toJson(salesList, new TypeToken<Collection<GagaMap>>() {
			}.getType());
			log.info("requestData: {}", requestData);
			HttpEntity<String> request = new HttpEntity<>(requestData, headers);

			String requestUrl = GagaStringUtil.replace(salesUrl, "#{erpGb}", erpGb);
			log.info("requestUrl: {}", requestUrl);
			URI url = URI.create(requestUrl);

			// POST방식으로 호출
			ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, request, String.class);
			log.info("responseEntity.getStatusCode(): {}", responseEntity.getStatusCode());

			String jsonResult = responseEntity.getBody();
			log.info("responseEntity.getBody(): {}", jsonResult);

			Gson gson = new Gson();
			JsonObject jsonObject = gson.fromJson(jsonResult, JsonObject.class);

			if (jsonObject.get("Message") != null && StringUtils.isNotBlank(jsonObject.get("Message").getAsString())) { // 전체에 대한 실패 메시지가 있으면
				log.error("Message: {}", jsonObject.get("Message").getAsString());
			} else {
				// 성공 데이터가 있으면
				salesMap.set("succList", new ArrayList<Map<String, Object>>());
				if (jsonObject.get("SuccessCount") != null && jsonObject.get("SuccessCount").getAsInt() > 0) {
					JsonArray jsonArr = jsonObject.getAsJsonArray("Success");
					ArrayList<Map<String, Object>> succList = gson.fromJson(jsonArr, ArrayList.class);
					salesMap.set("succList", succList);
				}

				// 실패 데이터가 있으면
				salesMap.set("failList", new ArrayList<Map<String, Object>>());
				if (jsonObject.get("FailureCount") != null && jsonObject.get("FailureCount").getAsInt() > 0) {
					JsonArray jsonArr = jsonObject.getAsJsonArray("Failure");
					ArrayList<Map<String, Object>> failList = gson.fromJson(jsonArr, ArrayList.class);
					salesMap.set("failList", failList);
				}
			}
		} catch (Exception e) {
			log.error("{}", e.getMessage().toString());
		}

		return salesMap;
	}

	/**
	 * ERP RT
	 * @param erpGb - ERP구분(hsmk:한세MK, hsdr:한세드림)
	 * @param Collection<Erp> - 재고이동 정보  
	 * @return
	 * @author moon
	 * @since 2021. 06. 21
	 */
	public String erpStockRt(String erpGb, Collection<Erp> rtList) {
		String rtn = "S";

		try {
			HttpHeaders headers = new HttpHeaders();
			headers.setContentType(MediaType.APPLICATION_JSON);

			// Parameter
			String requestData = (new Gson()).toJson(rtList, new TypeToken<Collection<Erp>>() {
			}.getType());
			log.info("requestData: {}", requestData);
			HttpEntity<String> request = new HttpEntity<>(requestData, headers);
//			MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
//			params.add("DATA", requestData);
//			log.info("params: {}", params);

			String requestUrl = GagaStringUtil.replace(stockRtUrl, "#{erpGb}", erpGb);
			log.info("requestUrl: {}", requestUrl);
			URI url = URI.create(requestUrl);

			// POST방식으로 호출
			ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, request, String.class);
			log.info("responseEntity.getStatusCode(): {} ", responseEntity.getStatusCode());

			String jsonResult = responseEntity.getBody();
			log.info("responseEntity.getBody(): {}", jsonResult);

			Gson gson = new Gson();
			GagaMap resultMap = gson.fromJson(jsonResult, GagaMap.class);

			if (resultMap.containsKey("Message")) { // 실패 메시지
				log.error("Message: {}", resultMap.get("Message").toString());
				rtn = "F";
			}
		} catch (Exception e) {
			log.error("{}", e.getMessage().toString());
		}

		return rtn;
	}

}
