package com.style24.core.biz.thirdparty;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.gagaframework.web.parameter.GagaMap;
import com.gagaframework.web.util.GagaStringUtil;
import com.style24.core.biz.dao.FingerPushDao;
import com.style24.core.biz.dao.TscAnswerPhaseDao;
import com.style24.core.support.env.TscConstants;
import com.style24.persistence.domain.AnswerPhase;
import com.style24.persistence.domain.FingerPush;

import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
public class FingerPushSender {

	private String appKey;
	private String appSecret;
	private String customerKey;

	// 발신자전화번호
	private String callbackTelNo;

	private String active;

	@Autowired
	private Environment env;

	@Autowired
	private TscAnswerPhaseDao ansPhaseDao;

	@Autowired
	private FingerPushDao fingerPushDao;

	public enum FingerPushSq {
		GOODS_UNPURCHASED(1027),					// 미구매 상품 확인안내
		SHOPPING_BAG_DISCOUNT(1028),				// 쇼핑백 할인혜택 안내
		WISHLIST_DISCOUNT(1029);					// 위시리스트 할인혜택 안내

		private Integer value;

		FingerPushSq(Integer value) { this.value = value; }

		public Integer value(){ return value;}

	}

	@PostConstruct
	public void init() {
		appKey = env.getProperty("fingerPush.appKey");
		appSecret = env.getProperty("fingerPush.appSecret");
		customerKey =  env.getProperty("fingerPush.customerKey");
		active = env.getProperty("spring.profiles.active");
		callbackTelNo = TscConstants.CALLCENTER_TEL_NO;
	}


	/**
	 * 카카오알림톡 발송
	 * @param ansSq - 답변일련번호
	 * @param fingerPush - 메시지 정보
	 * @param replaceInfo - 메시지내용 중 대체할 정보
	 * @author gagamel
	 * @since 2020. 11. 9
	 */
	@Transactional("shopTxnManager")
	public void send(Integer ansSq, FingerPush fingerPush ,GagaMap replaceInfo) {
		// 답변문구 조회
		AnswerPhase ansPhase = this.getAnswerPhase(ansSq, replaceInfo);

		fingerPush.setAppkey(appKey);
		fingerPush.setAppsecret(appSecret);
		fingerPush.setMsgtitle(ansPhase.getAnsTitle());
		fingerPush.setMsgcontents(ansPhase.getAnsContent());
		fingerPush.setCallback(callbackTelNo);
		fingerPush.setKkoFailedSubject(ansPhase.getAnsTitle());
		fingerPush.setKkoFailedMsg(ansPhase.getAnsContent());
		fingerPush.setPmode("STOS");

		// 앱푸시(핑거푸시) 발송
		if ("style".equals(active) || "locp".equals(active) || "stage".equals(active) || "brdg".equals(active)) {
			fingerPushDao.createAgpushQueue(fingerPush);
		} else {
			fingerPushDao.createAgpushQueueDev(fingerPush);
		}

	}

	/**
	 * 답변문구 조회
	 * 		어드민의 "운영관리 > 사이트설정 > 답변문구관리" 화면에서 등록/수정 시 answerPhase 캐시를 삭제
	 * @param ansSq - 답변일련번호
	 * @param replaceInfo - 메시지내용 중 대체할 정보
	 * @return
	 * @author gagamel
	 * @since 2020. 11. 9
	 */
	@Cacheable(value = "answerPhase", key = "#ansSq")
	public AnswerPhase getAnswerPhase(Integer ansSq, GagaMap replaceInfo) {
		AnswerPhase ansPhase = ansPhaseDao.getAnswerPhase(ansSq);
		ansPhase.setAnsContent(GagaStringUtil.replace(this.mergeData(ansPhase.getAnsContent(), replaceInfo), "&gt;", ">"));
		return ansPhase;
	}

	/**
	 * 메시지 문자열 중에 '#{'로 시작하고 '}'로 끝나는 부분을 대체할 정보(replaceInfo)로 대체해 반환한다.
	 * @param message - 메시지 문자열
	 * @param replaceInfo - 알림톡 메시지 중 대체할 정보
	 * @return
	 * @author gagamel
	 * @date 2018. 1. 21.
	 */
	private String mergeData(String message, GagaMap replaceInfo) {
		List<String> keyList = getKeyList(message, "#{", "}");

		String key = "";
		String value = "";

		if (!keyList.isEmpty()) {
			for (int i = 0; i < keyList.size(); i++) {
				key = keyList.get(i);
				value = replaceInfo.getString(key);
				message = message.replace("#{" + key + "}", value);
			}
		}

		return message;
	}

	/**
	 * 입력 문자열로부터 시작 태그와 종료 태그 안의 key 목록을 반환한다.
	 * @param inputStr - 입력 문자열
	 * @param startTag - 시작 태그
	 * @param endTag - 종료 태그
	 * @return
	 * @author gagamel
	 * @date 2018. 1. 21.
	 */
	private List<String> getKeyList(String inputStr, String startTag, String endTag) {
		List<String> keyList = new ArrayList<>();

		String targetStr = inputStr;

		while (targetStr.indexOf(startTag) > -1) {
			int startPos = targetStr.indexOf(startTag) + startTag.length();
			int endPos = targetStr.indexOf(endTag, startPos);

			keyList.add(targetStr.substring(startPos, endPos));
			targetStr = targetStr.substring(endPos + endTag.length());
		}

		return keyList;
	}
}
