package com.eactive.ext.kjb.ums;

import com.eactive.apim.portal.template.entity.MessageCode;
import com.eactive.apim.portal.template.entity.MessageRequest;
import com.eactive.apim.portal.template.repository.MessageRequestRepository;
import com.eactive.ext.kjb.common.KjbEaiBatchException;
import com.eactive.ext.kjb.common.KjbProperty;
import com.eactive.ext.kjb.common.KjbPropertyHolder;
import com.eactive.ext.kjb.utils.ValidationUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.CompletableFuture;
import java.util.function.BiConsumer;

@Slf4j
public class KjbEmailSendModule {
    public final static int[] ALLOW_CHANNELS = { MessageCode.Channels.EMAIL.getValue() };

    private static volatile KjbEmailSendModule instance;
    private MessageRequestRepository repo;

    private KjbEmailSendModule() {
        // 싱글톤
    }

    public static KjbEmailSendModule getInstance() {
        if (instance == null) {
            synchronized (KjbEmailSendModule.class) {
                if (instance == null) {
                    instance = new KjbEmailSendModule();
                }
            }
        }
        return instance;
    }

    /**
     * MessageRequestRepository 설정 (eapim-admin 초기화 시 호출)
     */
    public void setRepository(MessageRequestRepository repository) {
        this.repo = repository;
    }

    private static KjbProperty getProperty() {
        return KjbPropertyHolder.get();
    }

    public static boolean isAllowChannel(MessageRequest message) {
        for (int channel : ALLOW_CHANNELS) {
            if ((message.getMessageCode().getChannels() & channel) == channel) {
                return true;
            }
        }
        return false;
    }


    public static void environmentCheck() {
        KjbProperty prop = getProperty();

        if (StringUtils.isEmpty(prop.getEaiBatchUrl())) {
            log.warn("EAI_BATCH_URL 가 설정되지 않음. 실제 EAI 배치 연동 없이 동작함");
        }

        log.info("EAI Batch URL: {}", prop.getEaiBatchUrl());
        log.info("EAI Batch Send Dir: {}", prop.getUmsEaiBatchSendDir());


        // 디렉토리 검사(쓰기 권한 포함)
        Path sendDirPath = Paths.get(prop.getUmsEaiBatchSendDir());
        if (!sendDirPath.toFile().exists()) {
            // 생성 시도
            boolean created = sendDirPath.toFile().mkdirs();
            if (!created) {
                log.error("EAI_BATCH_SEND_DIR 디렉토리를 생성할 수 없음: {}", prop.getUmsEaiBatchSendDir());
                throw new IllegalStateException("EAI_BATCH_SEND_DIR 디렉토리를 생성할 수 없음: " + prop.getUmsEaiBatchSendDir());
            }
        }

        if (!sendDirPath.toFile().isDirectory()) {
            log.error("EAI_BATCH_SEND_DIR 가 디렉토리가 아님: {}", prop.getUmsEaiBatchSendDir());
            throw new IllegalStateException("EAI_BATCH_SEND_DIR 가 디렉토리가 아님: " + prop.getUmsEaiBatchSendDir());
        }

        if (!sendDirPath.toFile().canWrite()) {
            log.error("EAI_BATCH_SEND_DIR 에 쓰기 권한이 없음: {}", prop.getUmsEaiBatchSendDir());
            throw new IllegalStateException("EAI_BATCH_SEND_DIR 에 쓰기 권한이 없음: " + prop.getUmsEaiBatchSendDir());
        }


        // 백업 디렉토리
        Path backupDirPath = Paths.get(prop.getUmsEaiBatchBackupDir());
        if (!backupDirPath.toFile().exists()) {
            // 생성 시도
            boolean created = backupDirPath.toFile().mkdirs();
            if (!created) {
                log.error("EAI_BATCH_BACKUP_DIR 디렉토리를 생성할 수 없음: {}", prop.getUmsEaiBatchBackupDir());
                throw new IllegalStateException("EAI_BATCH_BACKUP_DIR 디렉토리를 생성할 수 없음: " + prop.getUmsEaiBatchBackupDir());
            }
        }

        if (!backupDirPath.toFile().isDirectory()) {
            log.error("EAI_BATCH_BACKUP_DIR 가 디렉토리가 아님: {}", prop.getUmsEaiBatchBackupDir());
            throw new IllegalStateException("EAI_BATCH_BACKUP_DIR 가 디렉토리가 아님: " + prop.getUmsEaiBatchBackupDir());
        }

        if (!backupDirPath.toFile().canWrite()) {
            log.error("EAI_BATCH_BACKUP_DIR 에 쓰기 권한이 없음: {}", prop.getUmsEaiBatchBackupDir());
            throw new IllegalStateException("EAI_BATCH_BACKUP_DIR 에 쓰기 권한이 없음: " + prop.getUmsEaiBatchBackupDir());
        }

        log.info("KjbEmailSendModule - Environment check passed.");
    }

    public void sendEmail(MessageRequest messageRequest) throws KjbEaiBatchException {
        String serviceId = "UNKNOWN";

        if (StringUtils.isEmpty(messageRequest.getServiceId())) {
            serviceId = messageRequest.getMessageCode().getServiceId();
            messageRequest.setServiceId(serviceId);
        }

        if (StringUtils.isEmpty(serviceId)) {
            throw new IllegalArgumentException("MessageRequest MessageCode serviceId is required");
        }

        if (MessageCode.Channels.EMAIL.getValue() != (messageRequest.getMessageCode().getChannels() & MessageCode.Channels.EMAIL.getValue())) {
            log.error("지원하지 않는 발송 채널 - {}", messageRequest.getMessageCode());
            throw new IllegalArgumentException("지원하지 않는 발송 채널 - " + messageRequest.getMessageCode());
        }

        if (repo != null) {
            repo.save(messageRequest);
        }

        EmailJob job = EmailJob.create(getProperty(), messageRequest, repo);
        job.sendEmail();

        log.debug("JSON : {}", job.generateJSON(true));
    }
}
