package itn.let.mjo.mjocommon;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.springframework.stereotype.Component;

import com.ibm.icu.text.SimpleDateFormat;

import itn.let.mjo.msgholiday.service.MsgAlarmSetVO;
import itn.let.mjo.msgholiday.service.MsgHolidayVO;

@Component
public class MjonHolidayApi {

	public List<MsgHolidayVO> getYearHolidayApiData(MsgHolidayVO msgHolidayVO) throws Exception{
		
		try {
			
			String sendUrl = "http://apis.data.go.kr/B090041/openapi/service/SpcdeInfoService/getHoliDeInfo?";
			String numOfRows = "100";
			String serviceKey = "J8QXC%2BtOGvxwmH8blG7nmqIq%2B0MrkNrxTo1PCmFMRdtSldlGN8vWDW2NpZ2om8k9LctZT6oubfFt5dMmbEDeoA%3D%3D";
			String solYear = msgHolidayVO.getSearchHoliYear();
			String frstRegisterId = msgHolidayVO.getFrstRegisterId();
			
			
			String strUrl = sendUrl + "&solYear=" + solYear + "&numOfRows=" + numOfRows + "&serviceKey=" + serviceKey;
			
			HttpClient httpClient = HttpClientBuilder.create().build(); 
			HttpGet httpGet = new HttpGet(strUrl); 
			httpGet.addHeader("Content-type", "application/json"); 
			httpGet.addHeader("Accept", "application/json");
			
			HttpResponse response = httpClient.execute(httpGet);

			String result = "";
			String statusCode = Integer.toString(response.getStatusLine().getStatusCode());
			
			if(statusCode.equals("200")) {
				
				result = EntityUtils.toString(response.getEntity()); 
				
				result = new String(result.getBytes("iso-8859-1"));//한글 깨짐 현상이 있어서 변환 해줌.
				//System.out.println(result);
				JSONParser parser = new JSONParser();
				Object obj = parser.parse(result);
				JSONObject object = (JSONObject) obj;
				
				Object objResp = parser.parse(object.get("response").toString());
				JSONObject objectResp = (JSONObject) objResp;
				
				Object objBody = parser.parse(objectResp.get("body").toString());
				JSONObject objectBody = (JSONObject) objBody;

				Object objItems = parser.parse(objectBody.get("items").toString());
				JSONObject objectItems = (JSONObject) objItems;
				
				JSONArray objItemArr = (JSONArray) objectItems.get("item");
				
				List<MsgHolidayVO> msgHolidayVoList = new ArrayList<MsgHolidayVO>();
				
				for(Object tmpObj : objItemArr) {
					
					JSONObject tmpObject = (JSONObject) tmpObj;
					MsgHolidayVO tmpMsgHolidayVO = new MsgHolidayVO();
					
					String isHoli = tmpObject.get("isHoliday").toString();
					String holiNm = tmpObject.get("dateName").toString();
					String holiDate = tmpObject.get("locdate").toString();
					
					
					if(isHoli.equals("Y")) {
						
						tmpMsgHolidayVO.setHolidayNm(holiNm);
						tmpMsgHolidayVO.setHolidayDate(holiDate);
						tmpMsgHolidayVO.setHolidayType("1");
						tmpMsgHolidayVO.setApiType("Y");
						tmpMsgHolidayVO.setFrstRegisterId(frstRegisterId);
						tmpMsgHolidayVO.setLastUpdusrId(frstRegisterId);
						
						msgHolidayVoList.add(tmpMsgHolidayVO);
						
					}
					
					
				}
				
				return msgHolidayVoList;
				
			}else {
				return null;
			}
			
		} catch (Exception e) {
			System.out.println("+++++++++++++++++++++++++++++++++ getYearHolidayApiData Method Error!!!!" + e);
			return null;
		}
		
	}
	
	
	public boolean getHolidaySmishingPassStatus(List<MsgAlarmSetVO> resultAlarmList, List<MsgHolidayVO> resultHolidayList) throws Exception{
			
		boolean holiCompareSts = false; //공휴일 일치 날자가 있는지 여부
		boolean smishingAlarmPassSts = false; //스미싱 알람 Pass 시킬건지 여부
		
		//현재 날짜의 요일 구하기
		Date currentDate = new Date();        
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
		 
		Calendar calendar = Calendar.getInstance(); 
		int year = calendar.get(Calendar.YEAR);
		int month = calendar.get(Calendar.MONTH);
		int day = calendar.get(Calendar.DATE);
		 
		calendar.setTime(currentDate);    
		
		 // 3. 텍스트 요일 구하기 (숫자)        
		 int dayOfWeekNumber = calendar.get(Calendar.DAY_OF_WEEK);         
		 // 4. 요일 출력        - 1은 일요일, 7은 토요일
		 //System.out.println(dayOfWeekNumber);  // 7
		 

		 //월에 대한 자릿수 처리 : 10미만은 앞에 0을 추가해주어 자릿수 맞춰준다.
		 String strMonth = "";
		 if((month +1) < 10) {
			 strMonth = "0" + Integer.toString(month +1);
		 }else {
			 strMonth = Integer.toString(month + 1);
		 }
		 
		 String strNowDate = year + "-" + strMonth + "-" + day;
		 
		 for(MsgHolidayVO holiVO : resultHolidayList) {
			 
			 String holiDate = holiVO.getHolidayDate();
			 
			 if(strNowDate.equals(holiDate)) {
				 
				 //System.out.println("공휴일이 동일한 날이 있습니다.");
				 holiCompareSts = true;
				 break;
			 }
			 
		 }
		 
		 
		 for(MsgAlarmSetVO alarmVO : resultAlarmList) {
			 
			String alarmType = alarmVO.getAlarmType();
			String startTime = alarmVO.getAlarmStart();
			String sDate = strNowDate + " " + startTime;
			
			String endTime = alarmVO.getAlarmEnd();
			String eDate = strNowDate + " " + endTime;
			 
			Date nowDate = currentDate;
	        Date startDate = sdf.parse(sDate);
	        Date endDate = sdf.parse(eDate);
			 
			 //평일인 경우 비교
			 if(dayOfWeekNumber > 1 && dayOfWeekNumber < 7 ) {
				 
				 if(alarmType.equals("W")) {
					 
					 int copStart = nowDate.compareTo(startDate);
					 int copEnd = nowDate.compareTo(endDate);
					 
					 if(copStart > 0 && copEnd < 0) {
						 
						 //System.out.println("평일 알림 일정 해당시간에 포함됩니다.");
						 smishingAlarmPassSts = true;
						 break;
						 
					 }
					 
				 }
				 
			 }else {
				 
				//주말인 경우 비교
				 if(alarmType.equals("E")) {
					 
					 int copStart = nowDate.compareTo(startDate);
					 int copEnd = nowDate.compareTo(endDate);
					 
					 if(copStart > 0 && copEnd < 0) {
						 
						 //System.out.println("주말 알림 일정 해당시간에 포함됩니다.");
						 smishingAlarmPassSts = true;
						 break;
						 
					 }
					 
				 }
				 
			 }

			 //공휴일인 경우 비교
			 if(alarmType.equals("H")) {
				 
				 if(holiCompareSts) {//오늘 날짜가 공휴일이면 실행
					 
					 int copStart = nowDate.compareTo(startDate);
					 int copEnd = nowDate.compareTo(endDate);
					 
					 if(copStart > 0 && copEnd < 0) {
						 
						 //System.out.println("공휴일 알림 일정 해당시간에 포함됩니다.");
						 smishingAlarmPassSts = true;
						 break;
						 
					 }
					 
				 }
				 
			 }
			 
		 }
		 
		return smishingAlarmPassSts;
	}
	
	/**
	 * @methodName	: getHolidaySmishingPassStatus_advc
	 * @author		: 이호영
	 * @date		: 2025. 3. 19.
	 * @description	: getHolidaySmishingPassStatus 개선 버전
	 * @return : boolean
	 * @param resultAlarmList
	 * @param resultHolidayList
	 * @return
	 * @throws Exception
	 * 
	 */
	public boolean getHolidaySmishingPassStatus_advc(List<MsgAlarmSetVO> alarmList, List<MsgHolidayVO> holidayList) throws Exception{
		
		Date now = new Date(); // 현재 시스템 시간
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); // 날짜-시간 포맷 (예: 2025-03-18 14:30)
		
		// 현재 날짜와 요일 계산
		Calendar cal = Calendar.getInstance();
		cal.setTime(now);
		int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK); // 1(일요일) ~ 7(토요일)
		// 오늘 날짜를 "yyyy-MM-dd" 형식으로 포맷팅 (mj_holiday.HOLIDAY_DATE와 비교용)
		String today = String.format("%d-%02d-%02d", 
		    cal.get(Calendar.YEAR), 
		    cal.get(Calendar.MONTH) + 1, // Calendar.MONTH는 0부터 시작하므로 +1
		    cal.get(Calendar.DATE));
	
		// 공휴일 여부 확인
		// mj_holiday 테이블의 HOLIDAY_DATE와 오늘 날짜가 일치하는지 체크
		// HOLIDAY_DATE는 'yyyy-MM-dd' 형식으로 저장됨 (예: '2025-01-01')
		boolean isHoliday = holidayList.stream()
				.anyMatch(holiday -> today.equals(holiday.getHolidayDate()));
	
		// 알람 설정 순회
		// alarmList는 MsgAlarmSetVO 객체의 리스트로, 알람 타입과 시작/종료 시간을 포함
		for (MsgAlarmSetVO alarm : alarmList) {
			String alarmType = alarm.getAlarmType(); // 알람 유형: 'W'(평일), 'E'(주말), 'H'(공휴일)
			// 오늘 날짜에 알람 시작/종료 시간을 붙여 Date 객체로 변환
			Date start = sdf.parse(today + " " + alarm.getAlarmStart()); // 예: "2025-03-18 09:00"
			Date end = sdf.parse(today + " " + alarm.getAlarmEnd());     // 예: "2025-03-18 18:00"
		
			// 현재 시간이 알람 시작~종료 시간 범위 내에 있는지 확인
			boolean isWithinTime = now.after(start) && now.before(end);
			if (!isWithinTime) continue; // 시간 범위 밖이면 다음 알람으로
		
			// 평일 체크 (월~금: dayOfWeek 2~6)
			// alarmType 'W'는 평일에만 적용
			if (dayOfWeek > 1 && dayOfWeek < 7 && alarmType.equals("W")) {
				return true; // 평일이고, 시간이 맞고, 타입이 'W'면 스미싱 알람 통과
			}
			// 주말 체크 (일:1, 토:7)
			// alarmType 'E'는 주말에만 적용
			else if ((dayOfWeek == 1 || dayOfWeek == 7) && alarmType.equals("E")) {
				return true; // 주말이고, 시간이 맞고, 타입이 'E'면 스미싱 알람 통과
			}
			// 공휴일 체크
			// alarmType 'H'는 mj_holiday에 등록된 공휴일에 적용
			// HOLIDAY_TYPE(1:법정, 2:임시, 3:기타)과 관계없이 날짜만 확인
			else if (isHoliday && alarmType.equals("H")) {
				return true; // 공휴일이고, 시간이 맞고, 타입이 'H'면 스미싱 알람 통과
			}
		}
		
		// 모든 조건에 부합하지 않으면 false 반환 (스미싱 알람 비활성화)
		return false;
	}
	
}
