package itn.com.cmm.util;

import java.io.UnsupportedEncodingException;

import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;

import itn.let.mail.service.StatusResponse;
import itn.let.mjo.msg.service.MjonMsgVO;
import itn.let.mjo.msgdata.service.ReplacementListsVO;
import lombok.extern.slf4j.Slf4j;

/**
 * 
 * @author 		: 이호영
 * @fileName 	: MsgSendUtils.java 
 * @date 		: 2024.09.23
 * @description : 메세지발송 데이터 다루는 유틸
 * =========================================================== 
 * DATE          AUTHOR   NOTE 
 * ----------------------------------------------------------- *
 * 2024.09.23    이호영          최초 생성
 * 
 * 
 * 
 */
@Slf4j
public final class MsgSendUtils {

	
	/** 
	 * @methodName	: getSmsTxtBytes 
	 * @author		: 이호영
	 * @date		: 2024.09.23 
	 * @description	: sms 텍스트 바이트 계산 후 return;
	 * @param smsTxt
	 * @return
	 * @throws UnsupportedEncodingException 
	 */
	public static int getSmsTxtBytes(String smsTxt) throws UnsupportedEncodingException {        	//문자열 길이 체크 해주기
		int smsBytes = 0;
		//문자 바이트 계산에 필요한 캐릭터 셋 : 한글 2Byte로 계산
		String charset = "euc-kr"; 						
		if(StringUtils.isNotEmpty(smsTxt)) {
			String smsCont = smsTxt.replace("\r\n", "\n");
			smsBytes = smsCont.getBytes(charset).length;
		}
		return smsBytes;
	}

	/** 
	 * @methodName	: getMsgType 
	 * @author		: 이호영
	 * @date		: 2024.09.23 
	 * @description	: msgType 재정의
	 * @param mjonMsgVO
	 * @param smsTxtByte
	 * @return 
	 */
	public static String getMsgType(MjonMsgVO mjonMsgVO, int smsTxtByte) {
	    String msgType = mjonMsgVO.getMsgType();

	    // 내문자저장함에 저장 후 문자를 발송하는 경우 문자 타입이 숫자가 아닌 문자로 넘어와서 변경 처리함
	    if ("P".equals(msgType) || "L".equals(msgType)) {
	        msgType = "6";
	    } else if ("S".equals(msgType)) {
	        msgType = "4";
	    }

	    // 그림 이미지가 첨부된 경우 장문으로 설정
	    if (mjonMsgVO.getFileName1() != null || (mjonMsgVO.getImgFilePath() != null && mjonMsgVO.getImgFilePath().length > 0)) {
	        msgType = "6";
	    } else if (smsTxtByte > 2000) {
	        // 2000 Byte를 초과할 경우 에러 처리 (이 부분은 호출부에서 검사하도록 유지할 수도 있음)
	        return "INVALID";  // 이 값은 호출부에서 에러 처리를 하도록 활용할 수 있습니다.
	    } else if (smsTxtByte > 90) {
	        // 90Byte 초과 시 장문으로 설정
	        msgType = "6";
	    } else {
	        // 그 외 단문으로 설정
	        msgType = "4";
	    }

	    return msgType;
	}

	public static float getValidPrice(Float personalPrice, Float defaultPrice) {
	    return (personalPrice != null && personalPrice > 0) ? personalPrice : defaultPrice;
	}

	
	/** 
	* @methodName	: determinePriceByMsgType 
	* @author		: 이호영
	* @date		: 2024.09.24 
	* @description	: 문자 메시지 타입에 따라 단가를 결정하는 메서드
	* @param mjonMsgVO
	* @param shortPrice
	* @param longPrice
	* @param picturePrice
	* @param picture2Price
	* @param picture3Price
	* @return 
	*/
	public static float determinePriceByMsgType(MjonMsgVO mjonMsgVO, float shortPrice, float longPrice, 
	                                      float picturePrice, float picture2Price, float picture3Price) {
	    float price = 0;
	    String msgType = mjonMsgVO.getMsgType();

	    if ("4".equals(msgType)) {
	        price = shortPrice;
	    } else if ("6".equals(msgType)) {
	        // 파일 첨부 여부에 따라 장문 단가 설정
	        if (mjonMsgVO.getFileName3() != null) {
	            price = picture3Price;
	        } else if (mjonMsgVO.getFileName2() != null) {
	            price = picture2Price;
	        } else if (mjonMsgVO.getFileName1() != null) {
	            price = picturePrice;
	        } else {
	            price = longPrice;
	        }
	    }
	    return price;
	}

	public static boolean isReplacementRequired(MjonMsgVO mjonMsgVO) {
	    return "Y".equals(mjonMsgVO.getTxtReplYn());
	}

	public static boolean isReplacementDataValid(MjonMsgVO mjonMsgVO) {
		String[] nameList = mjonMsgVO.getNameList();
		String[] rep1 = mjonMsgVO.getRep1List();
		String[] rep2 = mjonMsgVO.getRep2List();
		String[] rep3 = mjonMsgVO.getRep3List();
		String[] rep4 = mjonMsgVO.getRep4List();


		
		// 치환 문자 리스트가 유효한지 확인
		return !(isEmpty(nameList) 
				&& isEmpty(rep1) 
				&& isEmpty(rep2) 
				&& isEmpty(rep3) 
				&& isEmpty(rep4));
	}

	// 배열이 비어있는지 확인하는 메서드
	public static boolean isEmpty(String[] array) {
		return array == null || array.length == 0;
	}

	public static ReplacementListsVO createReplacementLists(MjonMsgVO mjonMsgVO) throws UnsupportedEncodingException {
		ReplacementListsVO lists = new ReplacementListsVO();
		lists.initializeLists(mjonMsgVO); // 배열을 초기화합니다.
		return lists;
//		return populateReplacementLists(mjonMsgVO, lists); // 데이터를 배열에 채웁니다.
	}

	/** 
	 * @methodName	: populateReplacementLists 
	 * @author		: 이호영
	 * @date		: 2024.09.26 
	 * @description	: 배열에 데이터를 채우는 메서드 
	 * @param mjonMsgVO
	 * @param lists
	 * @param statusResponse
	 * @return
	 * @throws UnsupportedEncodingException 
	 */
	public static void populateReplacementLists(MjonMsgVO mjonMsgVO, ReplacementListsVO lists, StatusResponse statusResponse){
		
		
	    String[] nameList = mjonMsgVO.getNameList();
	    String[] phone = mjonMsgVO.getCallToList();
	    String[] rep1 = mjonMsgVO.getRep1List();
	    String[] rep2 = mjonMsgVO.getRep2List();
	    String[] rep3 = mjonMsgVO.getRep3List();
	    String[] rep4 = mjonMsgVO.getRep4List();
	    String smsTxt = mjonMsgVO.getSmsTxt();
	    int fileCount = Integer.parseInt(mjonMsgVO.getFileCnt());

        // 이름 치환
		int shortCnt = 0;
		int longCnt = 0;
		int imgCnt = 0;
	    for (int i = 0; i < phone.length; i++) {
	    	
	        smsTxt = smsTxt.replaceAll(String.valueOf((char) 13), "");
	        if (smsTxt.contains("[*이름*]")) {
	            if (nameList.length > i && StringUtil.isNotEmpty(nameList[i])) {
	                smsTxt = smsTxt.replaceAll("\\[\\*이름\\*\\]", StringUtil.getString(nameList[i].replaceAll("§", ",")));
	            } else {
	                smsTxt = smsTxt.replaceAll("\\[\\*이름\\*\\]", "");
	            }
	        }

	        // 문자 1 치환
	        if (smsTxt.contains("[*1*]")) {
	            if (rep1.length > i && StringUtil.isNotEmpty(rep1[i])) {
	                smsTxt = smsTxt.replaceAll("\\[\\*1\\*\\]", StringUtil.getString(rep1[i].replaceAll("§", ",")));
	            } else {
	                smsTxt = smsTxt.replaceAll("\\[\\*1\\*\\]", "");
	            }
	        }

	        // 문자 2 치환
	        if (smsTxt.contains("[*2*]")) {
	            if (rep2.length > i && StringUtil.isNotEmpty(rep2[i])) {
	                smsTxt = smsTxt.replaceAll("\\[\\*2\\*\\]", StringUtil.getString(rep2[i].replaceAll("§", ",")));
	            } else {
	                smsTxt = smsTxt.replaceAll("\\[\\*2\\*\\]", "");
	            }
	        }

	        // 문자 3 치환
	        if (smsTxt.contains("[*3*]")) {
	            if (rep3.length > i && StringUtil.isNotEmpty(rep3[i])) {
	                smsTxt = smsTxt.replaceAll("\\[\\*3\\*\\]", StringUtil.getString(rep3[i].replaceAll("§", ",")));
	            } else {
	                smsTxt = smsTxt.replaceAll("\\[\\*3\\*\\]", "");
	            }
	        } 

	        // 문자 4 치환
	        if (smsTxt.contains("[*4*]")) {
	            if (rep4.length > i && StringUtil.isNotEmpty(rep4[i])) {
	                smsTxt = smsTxt.replaceAll("\\[\\*4\\*\\]", StringUtil.getString(rep4[i].replaceAll("§", ",")));
	            } else {
	                smsTxt = smsTxt.replaceAll("\\[\\*4\\*\\]", "");
	            }
	        }

			try {
				int bytes = getSmsTxtBytes(smsTxt);
	        
				if(bytes < 2000) {
					if(fileCount > 0) {
					    populateImgLists(lists, nameList, phone, rep1, rep2, rep3, rep4, smsTxt, i);
					    imgCnt++;
					    
					}else if(bytes > 90) {//장문문자 리스트 만들기
					    populateLongLists(lists, nameList, phone, rep1, rep2, rep3, rep4, smsTxt, i);
					    longCnt++;
	    			} else {//단문문자 리스트 만들기
	    			    populateShortLists(lists, nameList, phone, rep1, rep2, rep3, rep4, smsTxt, i);
	    			    shortCnt++;
	    			}
				}else {
					statusResponseSet(statusResponse, HttpStatus.BAD_REQUEST, "문자 치환 후 전송 문자 길이를 초과하였습니다.");
				}
				
			} catch (UnsupportedEncodingException e) {
				statusResponseSet(statusResponse, HttpStatus.BAD_REQUEST, "전송 중 오류가 발생하였습니다.");
				e.printStackTrace();
			}
	    }
	    
		lists.setShortCnt(shortCnt);
		lists.setLongCnt(longCnt);
		lists.setImgCnt(imgCnt);

	}

	private static void populateShortLists(ReplacementListsVO lists, String[] nameList, String[] phone, String[] rep1,
			String[] rep2, String[] rep3, String[] rep4, String smsTxt, int i) {
        // 이름 치환
        if (smsTxt.contains("[*이름*]")) {
            if (nameList.length > i && StringUtil.isNotEmpty(nameList[i])) {
                lists.getShortNameList()[i] = StringUtil.getString(nameList[i].replaceAll("§", ","));
            } else {
                lists.getShortNameList()[i] = " ";
            }
        } else {
            lists.getShortNameList()[i] = getSafeValue(nameList, i);
        }

        lists.getShortPhone()[i] = getSafeValue(phone, i);

        // 문자 1 치환
        if (smsTxt.contains("[*1*]")) {
            lists.getShortRep1()[i] = getReplacementValue(rep1, i, "[*1*]");
        } else {
            lists.getShortRep1()[i] = getSafeValue(rep1, i);
        }

        // 문자 2 치환
        if (smsTxt.contains("[*2*]")) {
            lists.getShortRep2()[i] = getReplacementValue(rep2, i, "[*2*]");
        } else {
            lists.getShortRep2()[i] = getSafeValue(rep2, i);
        }

        // 문자 3 치환
        if (smsTxt.contains("[*3*]")) {
            lists.getShortRep3()[i] = getReplacementValue(rep3, i, "[*3*]");
        } else {
            lists.getShortRep3()[i] = getSafeValue(rep3, i);
        }

        // 문자 4 치환
        if (smsTxt.contains("[*4*]")) {
            lists.getShortRep4()[i] = getReplacementValue(rep4, i, "[*4*]");
        } else {
            lists.getShortRep4()[i] = getSafeValue(rep4, i);
        }
	}

	// 장문 리스트에 데이터를 채우는 메서드
	private static void populateLongLists(ReplacementListsVO lists, String[] nameList, String[] phone, String[] rep1, String[] rep2, String[] rep3, String[] rep4, String smsTxt, int i) {
        // 이름 치환
        if (smsTxt.contains("[*이름*]")) {
            if (nameList.length > i && StringUtil.isNotEmpty(nameList[i])) {
                lists.getLongNameList()[i] = StringUtil.getString(nameList[i].replaceAll("§", ","));
            } else {
                lists.getLongNameList()[i] = " ";
            }
        } else {
            lists.getLongNameList()[i] = getSafeValue(nameList, i);
        }

        lists.getLongPhone()[i] = getSafeValue(phone, i);

        // 문자 1 치환
        if (smsTxt.contains("[*1*]")) {
            lists.getLongRep1()[i] = getReplacementValue(rep1, i, "[*1*]");
        } else {
            lists.getLongRep1()[i] = getSafeValue(rep1, i);
        }

        // 문자 2 치환
        if (smsTxt.contains("[*2*]")) {
            lists.getLongRep2()[i] = getReplacementValue(rep2, i, "[*2*]");
        } else {
            lists.getLongRep2()[i] = getSafeValue(rep2, i);
        }

        // 문자 3 치환
        if (smsTxt.contains("[*3*]")) {
            lists.getLongRep3()[i] = getReplacementValue(rep3, i, "[*3*]");
        } else {
            lists.getLongRep3()[i] = getSafeValue(rep3, i);
        }

        // 문자 4 치환
        if (smsTxt.contains("[*4*]")) {
            lists.getLongRep4()[i] = getReplacementValue(rep4, i, "[*4*]");
        } else {
            lists.getLongRep4()[i] = getSafeValue(rep4, i);
        }
	}

	// 그림 문자 리스트에 데이터를 채우는 메서드
	private static void populateImgLists(ReplacementListsVO lists, String[] nameList, String[] phone, String[] rep1, String[] rep2, String[] rep3, String[] rep4, String smsTxt, int i) {
		
		// 이름 치환
		if (smsTxt.contains("[*이름*]")) {
		    if (nameList.length > i && StringUtil.isNotEmpty(nameList[i])) {
		        lists.getImgNameList()[i] = StringUtil.getString(nameList[i].replaceAll("§", ","));
		    } else {
		        lists.getImgNameList()[i] = " ";
		    }
		} else {
		    lists.getImgNameList()[i] = getSafeValue(nameList, i);
		}
		
		lists.getImgPhone()[i] = getSafeValue(phone, i);
		
		// 문자 1 치환
		if (smsTxt.contains("[*1*]")) {
		    lists.getImgRep1()[i] = getReplacementValue(rep1, i, "[*1*]");
		} else {
		    lists.getImgRep1()[i] = getSafeValue(rep1, i);
		}
		
		// 문자 2 치환
		if (smsTxt.contains("[*2*]")) {
		    lists.getImgRep2()[i] = getReplacementValue(rep2, i, "[*2*]");
		} else {
		    lists.getImgRep2()[i] = getSafeValue(rep2, i);
		}
		
		// 문자 3 치환
		if (smsTxt.contains("[*3*]")) {
		    lists.getImgRep3()[i] = getReplacementValue(rep3, i, "[*3*]");
		} else {
		    lists.getImgRep3()[i] = getSafeValue(rep3, i);
		}
		
		// 문자 4 치환
		if (smsTxt.contains("[*4*]")) {
		    lists.getImgRep4()[i] = getReplacementValue(rep4, i, "[*4*]");
		} else {
		    lists.getImgRep4()[i] = getSafeValue(rep4, i);
		}
		
	}

	// 배열 인덱스를 안전하게 접근하는 메서드
	private static String getSafeValue(String[] array, int index) {
	    return (array != null && array.length > index) ? array[index] : " ";
	}

	// 치환 처리에 특수문자 제거 로직이 포함된 메서드
	private static String getReplacementValue(String[] array, int index, String placeholder) {
	    if (array != null && array.length > index && StringUtil.isNotEmpty(array[index])) {
	        return StringUtil.getString(array[index].replaceAll("§", ","));
	    } else {
	        return " ";
	    }
	}
	

	/** 
	 * @methodName	: checkReplacementDataValidity 
	 * @author		: 이호영
	 * @date		: 2024.09.25
	 * @description	: 치환문자가 사용될 때 데이터가 올바른지 확인하는 메서드
	 * @param mjonMsgVO
	 * @param modelAndView
	 * @return boolean
	 */
	public static boolean checkReplacementDataValidity(MjonMsgVO mjonMsgVO, StatusResponse statusResponse) {
		String[] nameList = mjonMsgVO.getNameList();
		String[] phone = mjonMsgVO.getCallToList();
		String[] rep1 = mjonMsgVO.getRep1List();
		String[] rep2 = mjonMsgVO.getRep2List();
		String[] rep3 = mjonMsgVO.getRep3List();
		String[] rep4 = mjonMsgVO.getRep4List();

		boolean isRepCountOk = true;

		// 치환 문자 전체 필수 체크
		if (mjonMsgVO.getSmsTxt().contains("[*이름*]") && nameList.length != phone.length) {
			isRepCountOk = false;
		}
		if (mjonMsgVO.getSmsTxt().contains("[*1*]") && rep1.length != phone.length) {
			isRepCountOk = false;
		}
		if (mjonMsgVO.getSmsTxt().contains("[*2*]") && rep2.length != phone.length) {
			isRepCountOk = false;
		}
		if (mjonMsgVO.getSmsTxt().contains("[*3*]") && rep3.length != phone.length) {
			isRepCountOk = false;
		}
		if (mjonMsgVO.getSmsTxt().contains("[*4*]") && rep4.length != phone.length) {
			isRepCountOk = false;
		}

		// 검증 결과가 false인 경우 에러 메시지 반환
		if (!isRepCountOk) {

			statusResponseSet(statusResponse, HttpStatus.BAD_REQUEST, "특정문구 일괄변환 치환문자 데이터가 없습니다.");
			return false;
		}

		return true;
	}
	

	private static void statusResponseSet (StatusResponse statusResponse, HttpStatus httpStatus, String msg ) {
		statusResponse.setStatus(httpStatus);
		statusResponse.setMessage(msg);
		
	}

	
}
