package com.madeu.service.web.webkakao.impl;

import com.google.gson.*;
import com.madeu.constants.Constants;
import com.madeu.dao.web.webauthmenurelation.WebAuthMenuRelationSqlMapDAO;
import com.madeu.dao.web.webkakaotemplate.WebKakaoTemplateSqlMapDAO;
import com.madeu.dao.web.webmember.WebMemberSqlMapDAO;
import com.madeu.dao.web.webkakao.WebKakaoSqlMapDAO;
import com.madeu.service.web.webkakao.WebKakaoService;
import com.madeu.util.ValidationCheckUtil;
import com.popbill.api.KakaoService;
import com.popbill.api.PopbillException;
import com.popbill.api.TaxinvoiceService;
import com.popbill.api.kakao.KakaoButton;
import com.popbill.api.kakao.KakaoReceiver;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@Service("WebKakaoService")
public class WebKakaoServiceImpl implements WebKakaoService {

    @Value("${popbill.corp-num}")
	String corpNum;

    @Value("${popbill.user-id}")
	String userId;

    @Value("${popbill.sender-nm}")
	String senderName;

    @Value("${popbill.sender-phone-num}")
	String senderPhoneNumber;

	@Autowired
	private WebKakaoSqlMapDAO webKakaoSqlMapDAO;

	@Autowired
	private WebKakaoTemplateSqlMapDAO webKakaoTemplateSqlMapDAO;
	
	@Autowired
	private WebMemberSqlMapDAO webMemberSqlMapDAO;
	
	@Autowired
	private WebAuthMenuRelationSqlMapDAO webAuthMenuRelationSqlMapDAO;

	@Autowired
	private KakaoService kakaoService;

	@Autowired
	private TaxinvoiceService taxinvoiceService;

	/**
	 * 알림톡 리스트 조회
	 *
	 *
	 * @param paramMap
	 * @return
	 * @throws Exception
	 */
	@Override
	public HashMap<String, Object> selectListKakao(
			HashMap<String, Object> paramMap) throws Exception {
		log.debug("WebKakaoServiceImpl selectListKakao START");

		HashMap<String, Object> map = new HashMap<String, Object>();

		log.debug("loginMemberId       :"+paramMap.get("loginMemberId"));
		
		log.debug("menuClass           :"+paramMap.get("menuClass"));
		
		log.debug("kakaoSearchKeywordParam  :"+paramMap.get("kakaoSearchKeywordParam"));
		log.debug("kakaoSort                :"+paramMap.get("kakaoSort"));
		log.debug("kakaoStart               :"+paramMap.get("kakaoStart"));
		log.debug("kakaoLimit               :"+paramMap.get("kakaoLimit"));
		log.debug("kakaoSort                :"+paramMap.get("kakaoSort"));
		log.debug("kakaoDir                 :"+paramMap.get("kakaoDir"));
		log.debug("kakaoCurrentPage         :"+paramMap.get("kakaoCurrentPage"));
		
		log.debug("kakaoSearchStartDate     :"+paramMap.get("kakaoSearchStartDate"));
		log.debug("kakaoSearchEndDate       :"+paramMap.get("kakaoSearchEndDate"));
		
		List<Map<String, Object>> listMap = new ArrayList<Map<String,Object>>();

		try{
			boolean check  = true;
			
			if(true == check){
				// 사용자 확인
				List<Map<String, Object>> userListMap = webMemberSqlMapDAO.checkMember(paramMap);
				int userListMapSize = userListMap.size();
				
				if(1==userListMapSize){
					paramMap.put("menuClassAuthId", userListMap.get(0).get("muAuthId"));
				}
				else {
					check = false;
					map.put("msgCode", Constants.FAIL);
					map.put("msgDesc", "사용자 정보가 올바르지 않습니다.");
				}
			}
			
			if(true == check){
				// 정렬
				if(null==paramMap.get("kakaoDir")||("").equals(paramMap.get("kakaoDir"))){

				}
				else{
					String dir = String.valueOf(paramMap.get("kakaoDir"));
					if(("A").equals(dir)){
						paramMap.put("kakaoDir", "DESC");
					}
					else if(("B").equals(dir)){
						paramMap.put("kakaoDir", "ASC");
					}
					else {
						paramMap.put("kakaoDir", "DESC");
					}
				}

				paramMap.put("useYn", "Y");
				
				List<Map<String, Object>> totalCountListMap = webKakaoSqlMapDAO.selectTotalKakaoCount(paramMap);
				int totalCount = Integer.parseInt(String.valueOf(totalCountListMap.get(0).get("totalCount")));
				
				if(0 < totalCount) {
					// 리스트 조회
					listMap = webKakaoSqlMapDAO.selectListKakao(paramMap);
				}
				
				map.put("msgCode", Constants.OK);
				map.put("success","true");
				map.put("totalCount", totalCount);
				map.put("rows",listMap);
			}
		}
		catch(Exception e){
			e.printStackTrace();
			throw e;
		}
		log.debug("WebKakaoServiceImpl selectListKakao END");
		return map;
	}
	
	/**
	 * 알림톡 정보 등록
	 * 
	 * @param paramMap
	 * @return
	 * @throws Exception 
	 */
	@Override
	@Transactional(rollbackFor={Exception.class}, propagation = Propagation.REQUIRES_NEW)
	public HashMap<String, Object> insertKakao(
			HashMap<String, Object> paramMap) throws Exception{
		log.debug("WebKakaoServiceImpl insertKakao START");
		
		HashMap<String, Object> map = new HashMap<String, Object>();

		log.debug("loginMemberId       :"+paramMap.get("loginMemberId"));
		
		log.debug("menuClass           :"+paramMap.get("menuClass"));
		
		log.debug("templateCode        :"+paramMap.get("templateCode"));
		log.debug("userArrData         :"+paramMap.get("userArrData"));

		try{
			boolean check  = true;
			String tId = String.valueOf(System.currentTimeMillis());
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			Calendar c1 = Calendar.getInstance();
			String tDate = sdf.format(c1.getTime());

			List<Map<String, Object>> templateListMap = null;

			String templateCode    = String.valueOf(paramMap.get("templateCode"));
			String userArrData     = String.valueOf(paramMap.get("userArrData"));
			String templateContent = "";
			double remainPoint = 0;

			if(true != ValidationCheckUtil.emptyCheck(templateCode)){
				check = false;
				map.put("msgCode", Constants.FAIL);
				map.put("msgDesc","알림톡 템플릿 코드 정보가 없습니다.");
			}else{
				templateListMap = webKakaoTemplateSqlMapDAO.selectKakaoTemplate(paramMap);
				int size = templateListMap.size();
				if(0<size){
					templateContent = String.valueOf(templateListMap.get(0).get("content"));
				}else{
					check = false;
					map.put("msgCode", Constants.FAIL);
					map.put("msgDesc","알림톡 템플릿 정보가 없습니다.");
				}
			}

			if(true != ValidationCheckUtil.emptyCheck(userArrData)){
				check = false;
				map.put("msgCode", Constants.FAIL);
				map.put("msgDesc","발송대상 정보가 없습니다.");
			}

			if(true == check){
				// 사용자 확인
				List<Map<String, Object>> userListMap = webMemberSqlMapDAO.checkMember(paramMap);
				int userListMapSize = userListMap.size();
				
				if(1==userListMapSize){
					paramMap.put("menuClassAuthId", userListMap.get(0).get("muAuthId"));
				}
				else {
					check = false;
					map.put("msgCode", Constants.FAIL);
					map.put("msgDesc", "사용자 정보가 올바르지 않습니다.");
				}
			}
			
			if(true == check){
				// 권한 조회
				HashMap<String, Object> authCheckParamMap = new HashMap<String, Object>();
				authCheckParamMap.put("menuClass",paramMap.get("menuClass"));
				authCheckParamMap.put("muAuthId",paramMap.get("menuClassAuthId"));
				List<Map<String, Object>> authMenuRelationlistMap = webAuthMenuRelationSqlMapDAO.selectAuthMenuRelation(authCheckParamMap);
				int authMenuRelationlistMapSize = authMenuRelationlistMap.size();
				
				if(1==authMenuRelationlistMapSize){
					
					if(("Y").equals(authMenuRelationlistMap.get(0).get("insertUseYn"))) {
						
					}
					else {
						check = false;
						map.put("msgCode", Constants.FAIL);
						map.put("msgDesc", "등록 권한 정보가 없습니다.");
					}
				}
				else {
					check = false;
					map.put("msgCode", Constants.FAIL);
					map.put("msgDesc", "권한 정보가 없습니다.");
				}
			}

			// 포인트 조회
			if(true == check){
	            try {
	                remainPoint = taxinvoiceService.getBalance(corpNum);

	                log.debug("remainPoint : "+remainPoint);

					if(0 == remainPoint){
						check = false;
						map.put("msgCode", Constants.FAIL);
						map.put("msgDesc", "팝빌 통합 포인트가 없습니다. 충전 후 발송해 주시기 바랍니다.");
					}

	            } catch (PopbillException e) {
	            	log.debug("오류 코드   :" + e.getCode());
                    log.debug("오류 메시지 :" + e.getMessage());
	            }
			}
			
			if(true == check){
				paramMap.put("tDate", tDate);
				paramMap.put("tId", tId);

				//gson 변경 후 등록
				Gson gsonPaser = new GsonBuilder().setPrettyPrinting().create();
				String data = String.valueOf(paramMap.get("userArrData"));

				//json 변환
				JsonObject itemData = gsonPaser.fromJson(data, JsonObject.class);
				JsonArray itemArr = (JsonArray) itemData.get("itemArr");
				int itemArrSize = itemArr.size();

//				KakaoReceiver[] receivers = new KakaoReceiver[itemArrSize];

				for(int i=0; i<itemArrSize; i++) {
					String receiver = itemArr.get(i).getAsJsonObject().get("phoneNumber").getAsString();
					String userName = itemArr.get(i).getAsJsonObject().get("userName").getAsString();

					log.debug("receiver : "+receiver);
					log.debug("userName : "+userName);

					String content = kakaoContent(templateCode, templateContent, itemArr.get(i));

					HashMap<String, Object> insertDetailParamMap = new HashMap<String, Object>();
					insertDetailParamMap.put("muKakaoId", ("K").concat(String.valueOf(System.currentTimeMillis())));
					insertDetailParamMap.put("templateCode", templateCode);
					insertDetailParamMap.put("content", content);
					insertDetailParamMap.put("state", "R");
					insertDetailParamMap.put("popbillState", "0");
					insertDetailParamMap.put("sender", senderPhoneNumber);
					insertDetailParamMap.put("regId", paramMap.get("regId"));
					insertDetailParamMap.put("modId", paramMap.get("modId"));
					insertDetailParamMap.put("tId", tId);
					insertDetailParamMap.put("tDate", tDate);

					//배열 값 해쉬맵 형식으로 한번에 변환
					insertDetailParamMap.putAll(gsonPaser.fromJson(itemArr.get(i).toString(), HashMap.class));

					//등록
					webKakaoSqlMapDAO.insertKakao(insertDetailParamMap);
//					itemArr.get(i).getAsJsonObject().addProperty("muKakaoId", String.valueOf(insertDetailParamMap.get("id")));
//
//
//					// 알림톡 상태 업데이트
//					HashMap<String, Object> kakaoUpdateParamMap = new HashMap<String, Object>();
//					kakaoUpdateParamMap.put("oldState", "R");
//					kakaoUpdateParamMap.put("chgState", "G");
//					kakaoUpdateParamMap.put("modId", paramMap.get("modId"));
//					kakaoUpdateParamMap.put("muKakaoId", insertDetailParamMap.get("id"));
//					kakaoUpdateParamMap.put("sendDateYn", "N");
//					webKakaoSqlMapDAO.updateKakaoState(kakaoUpdateParamMap);


//					KakaoReceiver msg = new KakaoReceiver();
//					msg.setReceiverNum(receiver);      // 수신번호
//					msg.setReceiverName(userName);     // 수신자명
//					msg.setMessage(content);           // 알림톡 템플릿 내용
//
//					// 같은 템플릿끼리 receivers에 담겨야함
//					receivers[i] = msg;
				}

//				String receiptNum = "";
//
//				// 예약전송일시, 형태(yyyyMMddHHmmss)
//				String sndDT = "";
//
//				// 전송요청번호
//				// 파트너가 전송 건에 대해 관리번호를 구성하여 관리하는 경우 사용.
//				// 1~36자리로 구성. 영문, 숫자, 하이픈(-), 언더바(_)를 조합하여 팝빌 회원별로 중복되지 않도록 할당.
//				String requestNum = "";
//
//				// 알림톡 버튼정보를 템플릿 신청시 기재한 버튼정보와 동일하게 전송하는 경우 null 처리.
//				KakaoButton[] btns = null;
//
//				// 대체문자 전송유형, 공백-미전송, C-알림톡 내용전송, A-대체문자 내용 전송
//				String altSendType = "";
//
//				try {
//					receiptNum = kakaoService.sendATS(corpNum, templateCode, senderPhoneNumber, altSendType, receivers, sndDT,
//							userId, requestNum, btns);
//
//				} catch (PopbillException e) {
//					log.debug("오류 코드   :" + e.getCode());
//					log.debug("오류 메시지 :" + e.getMessage());
//				}
//
//				for(int i=0; i<itemArrSize; i++) {
//					log.debug("muKakaoId : "+itemArr.get(i).getAsJsonObject().get("muKakaoId").getAsString());
//
//					// 알림톡 이력 업데이트
//					HashMap<String, Object> kakaoUpdateParamMap = new HashMap<String, Object>();
//					kakaoUpdateParamMap.put("oldState", "G");
//					kakaoUpdateParamMap.put("chgState", "Y");
//					kakaoUpdateParamMap.put("modId", paramMap.get("modId"));
//					kakaoUpdateParamMap.put("muKakaoId", itemArr.get(i).getAsJsonObject().get("muKakaoId").getAsString());
//					kakaoUpdateParamMap.put("receiptNum", receiptNum);
//					kakaoUpdateParamMap.put("sendDateYn", "Y");
//					webKakaoSqlMapDAO.updateKakaoState(kakaoUpdateParamMap);
//				}

				map.put("msgCode", Constants.OK);
				map.put("msgDesc", "발송되었습니다.");
			}
		}
		catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
		log.debug("WebKakaoServiceImpl insertKakao END");
		return map;
	}

	public String kakaoContent(String templateCode, String templateContent, JsonElement itemArr){

		String content = templateContent;

		if(("024060000138").equals(templateCode)){
			// 해피콜부재
			content = content.replace("#{고객명}", itemArr.getAsJsonObject().get("userName").getAsString());

		}else if(("024060000139").equals(templateCode)){
			// 해피콜상담예약취소

		}else if(("024060000141").equals(templateCode)){
			// 상담부재문자안내
			content = content.replace("#{고객명}", itemArr.getAsJsonObject().get("userName").getAsString());

		}else if(("024060000142").equals(templateCode)){
			// 상담예약부재문자
			content = content.replace("#{고객명}", itemArr.getAsJsonObject().get("userName").getAsString());

		}else if(("024060000145").equals(templateCode)){
			// 해피콜(간호)

		}else if(("024060000146").equals(templateCode)){
			// 홈페이지당일예약 문자

		}else if(("024060000195").equals(templateCode)){
			// 리프팅주의사항

		}else if(("024060000115").equals(templateCode)){
			// 병원위치, 주차장안내

		}else if(("024060000119").equals(templateCode)){
			// 메쉬다S플러스 체험단 리뷰가이드

		}else if(("024060000120").equals(templateCode)){
			// 메이드유 계좌번호 안내

		}else if(("024060000123").equals(templateCode)){
			// 리쥬란힐러 주의사항

		}else if(("024060000125").equals(templateCode)){
			// 보톡스 주의사항

		}else if(("024060000126").equals(templateCode)){
			// 스컬트라 주의사항

		}else if(("024060000130").equals(templateCode)){
			// 실루엣소프트 주의사항

		}else if(("024060000131").equals(templateCode)){
			// 실리프팅 주의사항

		}else if(("024060000132").equals(templateCode)){
			// 필러 주의사항

		}else if(("024060000133").equals(templateCode)){
			// 필러시술후
			content = content.replace("#{고객명}", itemArr.getAsJsonObject().get("userName").getAsString());

		}else if(("024060000136").equals(templateCode)){
			// 해피콜문자(피부압출시술)

		}

		return content;
	}
}
