package com.eactive.eai.rms.onl.dashboard.modern.mapper;

import com.eactive.eai.rms.onl.dashboard.modern.dto.SmsNotificationDto;
import com.eactive.eai.rms.onl.vo.SmsVO;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * SMS 장애 통보 정보를 DTO로 변환하는 매퍼 클래스
 */
@Component
public class SmsNotificationMapper {

    private static final Pattern DATE_TIME_PATTERN = Pattern.compile("(\\d{4}) (\\d{2}:\\d{2}:\\d{2}\\.\\d{3})");
    private static final Pattern COUNT_PATTERN = Pattern.compile("\\[(\\d+)\\]");
    
    // Sysout --> logger
    private static final Logger logger = Logger.getLogger(SmsNotificationMapper.class);

    /**
     * SmsVO 목록을 SmsNotificationDto 목록으로 변환합니다.
     *
     * @param smsList SmsVO 목록
     * @return SmsNotificationDto 목록
     */
    public List<SmsNotificationDto> mapToSmsNotificationDtoList(List<SmsVO> smsList) {
        List<SmsNotificationDto> dtoList = new ArrayList<>();

        if (smsList == null || smsList.isEmpty()) {
            return dtoList;
        }

        for (SmsVO smsVO : smsList) {
            List<String> messages = smsVO.getMessage();

            if (messages != null && !messages.isEmpty()) {
                for (String msg : messages) {
                    SmsNotificationDto dto = parseMessage(msg);
                    if (dto != null) {
                        dto.setServiceType(smsVO.getService());  // SmsVO의 service 값을 serviceType으로 매핑
                        dtoList.add(dto);
                    }
                }
            }
        }

        return dtoList;
    }

    /**
     * 메시지를 파싱하여 SmsNotificationDto 객체를 생성합니다.
     *
     * @param message 메시지 문자열
     * @return SmsNotificationDto 객체
     */
    private SmsNotificationDto parseMessage(String message) {
        if (message == null || message.trim().isEmpty()) {
            return null;
        }

        try {
            String[] parts = message.split("\\|");

            // Determine message type based on number of delimiters
            boolean isAdapterError = parts.length == 3;
            boolean isInterfaceError = parts.length == 2;

            if (!isAdapterError && !isInterfaceError) {
                return null;
            }

            SmsNotificationDto dto = new SmsNotificationDto();

            // Parse the first part (common for both types)
            String mainPart = parts[0];

            // Extract date and time
            Matcher dateTimeMatcher = DATE_TIME_PATTERN.matcher(mainPart);
            if (dateTimeMatcher.find()) {
                String mmdd = dateTimeMatcher.group(1);
                String time = dateTimeMatcher.group(2);
                String year = String.valueOf(LocalDate.now().getYear());
                String dateTimeStr = year + mmdd + " " + time; // Assuming current year
                LocalDateTime dateTime = LocalDateTime.parse(dateTimeStr,
                        DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss.SSS"));
                dto.setDateTime(dateTime);
            }

            // 당일 데이터가 아닌건은 skip
            if( !LocalDate.now().equals(dto.getDateTime().toLocalDate()) ){
                return null;
            }

            // Extract count
            Matcher countMatcher = COUNT_PATTERN.matcher(mainPart);
            if (countMatcher.find()) {
                dto.setCount(Integer.parseInt(countMatcher.group(1)));
            }

            // Extract instance name (between [] and first space after it)
            int instanceStart = mainPart.indexOf("]") + 1;
            int errorStart = mainPart.indexOf(" ", instanceStart);
            if (instanceStart > 0 && errorStart > instanceStart) {
                dto.setInstanceName(mainPart.substring(instanceStart, errorStart));
            }

            // Extract error content
            if (errorStart > 0) {
                dto.setErrorContent(mainPart.substring(errorStart).trim());
            }

            if (isAdapterError) {
                // Adapter error specific fields
                dto.setAdapterDesc(parts[1].trim());
                dto.setAdapterId(parts[2].trim());
                dto.setErrorType("ADAPTER");
            } else {
                // Interface error specific fields
                dto.setInterfaceId(parts[1].trim());
                dto.setErrorType("INTERFACE");
            }

            return dto;

        } catch (Exception e) {
            // Log error if needed
            return null;
        }
    }

    public static void main(String[] args) {
        SmsNotificationMapper mapper = new SmsNotificationMapper();
        SmsVO smsVO = new SmsVO();

        // 테스트할 메시지들
        List<String> messages = Arrays.asList(
                "0311 09:59:16.537[1]fep11 가용소켓연결없음|BASICTEST101S1",
                "0311 10:05:39.779[49]fep11 Client커넥션오류|싱글어댑터 Prim|_TST_OU_NET_AsC{ALL}",
                "0311 10:05:39.780[48]fep11 Client커넥션오류|비동기 표준 아|_TST_OU_NET_AsC{JSON_ALL}",
                "0311 17:33:04.182[1]fep11 추적관리필드추출에러|BASICTEST101S1"
        );

        smsVO.setMessage(messages);
        List<SmsNotificationDto> results = mapper.mapToSmsNotificationDtoList(Arrays.asList(smsVO));

//        System.out.println("=== SMS 메시지 파싱 결과 ===");
        logger.debug("=== SMS 메시지 파싱 결과 ===");
        for (SmsNotificationDto dto : results) {
//            System.out.println("\n[메시지 정보]");
//            System.out.println("시간: " + dto.getDateTime());
//            System.out.println("건수: " + dto.getCount());
//            System.out.println("인스턴스: " + dto.getInstanceName());
//            System.out.println("에러내용: " + dto.getErrorContent());
//            System.out.println("에러유형: " + dto.getErrorType());

            logger.debug("\n[메시지 정보]");
            logger.debug("시간: " + dto.getDateTime());
            logger.debug("건수: " + dto.getCount());
            logger.debug("인스턴스: " + dto.getInstanceName());
            logger.debug("에러내용: " + dto.getErrorContent());
            logger.debug("에러유형: " + dto.getErrorType());

            if ("ADAPTER".equals(dto.getErrorType())) {
//                System.out.println("어댑터설명: " + dto.getAdapterDesc());
//                System.out.println("어댑터ID: " + dto.getAdapterId());

                logger.debug("어댑터설명: " + dto.getAdapterDesc());
                logger.debug("어댑터ID: " + dto.getAdapterId());
            } else {
//                System.out.println("인터페이스ID: " + dto.getInterfaceId());

                logger.debug("인터페이스ID: " + dto.getInterfaceId());
            }
//            System.out.println("------------------------");

            logger.debug("------------------------");
        }
    }
}