package com.eactive.eai.rms.onl.common.service.ums;

import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.stereotype.Component;

import com.eactive.eai.rms.data.entity.man.monitoringProperty.service.MonitoringPropertyService;
import com.eactive.eai.transformer.util.ByteUtil;

import lombok.extern.slf4j.Slf4j;

import com.eactive.apim.portal.portaluser.entity.PortalUser;

@Slf4j
@Component
public class PrivacyNoticFactory {
	
	   private final StandardMessageTemplate template;
	   private final MonitoringPropertyService monitoringPropertyService;
	   
	   public PrivacyNoticFactory(MonitoringPropertyService monitoringPropertyService) {
		   this.monitoringPropertyService = monitoringPropertyService;
	       this.template = new StandardMessageTemplate();
	   }
	   
	   private static final String TYPE_EMAIL = "EMAIL";
	   
	   public String createMessage(PortalUser portalUser) {
		   
		   Map<String, FieldDefinition> messageTemplate = template.getCompleteTemplate(TYPE_EMAIL);
		   
		   // 기본 필드들 설정
	       setCommonFields(messageTemplate, portalUser);
	       
	       if (portalUser.getEmailAddr() == null ||  portalUser.getEmailAddr().trim().isEmpty()) {
               throw new IllegalStateException("Email is required for EMAIL type message. Request ID: " + portalUser.getId());
           }
	       
           setEmailFields(messageTemplate, portalUser);
           
           //Calculate lengths before building the final message
           calculateAndSetMessageLengths(messageTemplate);

           String message = buildMessage(messageTemplate);
           
           if (log.isDebugEnabled()) {
               StringBuilder templateDebug = new StringBuilder("\n");
               messageTemplate.forEach((key, field) -> {
                   templateDebug.append(String.format("\n%-35s | length: %-4d | value: '%s'",
                           key, field.getLength(), field.getValue()));
               });

               log.debug("Message details for request ID: {}\nUMS Message Template Structure:{}\n\nFinal assembled message:\n{}",
            		   portalUser.getId(),
                       templateDebug,
                       message);
           }		     
		   
           return message;		   
	   }
	   
	   private void setCommonFields(Map<String, FieldDefinition> template, PortalUser portalUser) {
	        String systemMode = System.getProperty("eai.systemmode");
	        LocalDateTime now = LocalDateTime.now();
	        String currentDateTime = now.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
	        String currentDate = now.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
	        String currentTime = now.format(DateTimeFormatter.ofPattern("HHmmss"));
	        String requestNumber = now.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS"))
	                + RandomStringUtils.random(13, true, true);
	        
	        String eaiIntfId = "EOCHSAPIUMS0020";
	        String serviceId = "E1API00003";

	        // 표준 헤더 설정
	        template.get("tlgrWrtnDt").setValue(currentDateTime);
	        template.get("eaiIntfId").setValue(eaiIntfId);
	        template.get("exctnModeDscd").setValue(systemMode);

	        // UMS 헤더 설정
	        template.get("CRTN_DT").setValue(currentDate);
	        template.get("CRTN_TM").setValue(currentTime);
	        template.get("ACPN_DT").setValue(currentDate);
	        template.get("ACPN_DRTM").setValue(currentTime);
	        template.get("SVC_ID").setValue(serviceId);
	        template.get("RQST_TMSG_NO").setValue(requestNumber);
	    }
	   
	    private void setEmailFields(Map<String, FieldDefinition> template, PortalUser portalUser) {
	    	
	    	String emailTtl = "개인정보 이용 및 제공 내역 통지";
	    	String emailCtt = "@s@|f|6|API Portal 개인정보 이용 및 제공 내역 통지 안내|"
	    			+portalUser.getUserName()+"|케이뱅크 API Portal 서비스를 이용해 주시는 고객님께 깊은 감사의 말씀을 드립니다."
	    			+"개인정보보호법 제20조의2(개인정보 이용 통지)에 따라 연1회 모든 고객님들께 개인정보 이용 및 제공 내역을 이메일로 안내 드리고 있습니다."
	    			+"API Portal 서비스 이용을 위해 제공하여 주신 소중한 개인정보는 안전하게 보호되고 있으며,"
	    			+"자세한 개인정보 이용 내역은 API Portal 홈페이지 개인정보 처리방침에서 언제든지 확인하실 수 있습니다."
	    			+"|개인정보처리방침 자세히 보기|agreements/terms?tab=privacy|개인정보처리방침 자세히 보기"
	    			;	    	
	    	
	        template.get("UMS_MSG_DV_CD").setValue("E");
	        template.get("SNDR_NM").setValue("케이뱅크");
	        template.get("SNDR_EMAIL_ADR").setValue("customer_center@kbanknow.com");
	        template.get("RCV_EMAIL_ADR").setValue(portalUser.getEmailAddr());
	        template.get("EMAIL_TTL").setValue(emailTtl);
	        int emailCttLen = emailCtt.getBytes(StandardCharsets.UTF_8).length;
	        FieldDefinition emailCttField = new FieldDefinition(emailCttLen, emailCtt);
	        template.put("EMAIL_CTT", emailCttField);
	        template.get("DATPT_LEN").setValue(String.format("%08d", emailCttLen));
	    }
	    
	    private String buildMessage(Map<String, FieldDefinition> template) {
	        StringBuilder message = new StringBuilder();
	        template.forEach((key, field) ->
	                message.append(padRight(field.getValue(), field.getLength())));
	        return message.toString();
	    }    
	    
	    private String padRight(String str, int length) {
	        if(StringUtils.isBlank(str)) {
	            StringBuilder spaces = new StringBuilder();
	            for (int i = 0; i < length; i++) {
	                spaces.append(" ");
	            }
	            return spaces.toString();
	        }
	        byte[] bytes = str.getBytes(StandardCharsets.UTF_8);

	        String padStr = new String(ByteUtil.paddingright(bytes, length, (byte)0x20), StandardCharsets.UTF_8);
	        return padStr;
	    }
	    
	    private void calculateAndSetMessageLengths(Map<String, FieldDefinition> template) {
	        // Calculate TMSG_LEN (UMS message length)
	        int umsLength = calculateUmsMessageLength(template);
	        template.get("TMSG_LEN").setValue(String.format("%08d", umsLength));

	        // Calculate tlgrLen (total message length)
	        int totalLength = calculateTotalMessageLength(template);
	        template.get("tlgrLen").setValue(String.format("%08d", totalLength));
	    }

	    private int calculateUmsMessageLength(Map<String, FieldDefinition> template) {
	        // Start calculating from UMS header (STR_DV_CD부터)
	        boolean startCounting = false;
	        int length = 0;

	        for (Map.Entry<String, FieldDefinition> entry : template.entrySet()) {
	            // STR_DV_CD부터 계산 시작
	            if (entry.getKey().equals("STR_DV_CD")) {
	                startCounting = true;
	            }

	            if (startCounting) {
	                length += entry.getValue().getLength();
	            }
	        }

	        return length;
	    }

	    private int calculateTotalMessageLength(Map<String, FieldDefinition> template) {
	        int length = 0;
	        // tlgrLen 필드를 제외한 모든 필드의 길이를 합산
	        for (Map.Entry<String, FieldDefinition> entry : template.entrySet()) {
	            if (!entry.getKey().equals("tlgrLen")) {
	                length += entry.getValue().getLength();
	            }
	        }
	        return length;
	    }

}
