package com.kt.event.eventservice.application.service;

import com.kt.event.eventservice.domain.enums.JobType;
import org.springframework.stereotype.Component;

import java.util.UUID;

/**
 * Job ID 생성기
 *
 * 비즈니스 친화적인 jobId를 생성합니다.
 * 형식: JOB-{jobType}-{timestamp}-{random8}
 * 예시: JOB-AI-20251029143025-a1b2c3d4
 *
 * VARCHAR(50) 길이 제약사항을 고려하여 설계되었습니다.
 */
@Component
public class JobIdGenerator {

    private static final String PREFIX = "JOB";
    private static final int RANDOM_LENGTH = 8;

    /**
     * Job ID 생성
     *
     * @param jobType Job 타입
     * @return 생성된 Job ID
     * @throws IllegalArgumentException jobType이 null인 경우
     */
    public String generate(JobType jobType) {
        if (jobType == null) {
            throw new IllegalArgumentException("jobType은 필수입니다");
        }

        String typeCode = getTypeCode(jobType);
        String timestamp = String.valueOf(System.currentTimeMillis());
        String randomPart = generateRandomPart();

        // 형식: JOB-{type}-{timestamp}-{random}
        // 예상 길이: 3 + 1 + 5 + 1 + 13 + 1 + 8 = 32자 (최대)
        String jobId = String.format("%s-%s-%s-%s", PREFIX, typeCode, timestamp, randomPart);

        // 길이 검증
        if (jobId.length() > 50) {
            throw new IllegalStateException(
                String.format("생성된 jobId 길이(%d)가 50자를 초과했습니다: %s",
                    jobId.length(), jobId)
            );
        }

        return jobId;
    }

    /**
     * JobType을 짧은 코드로 변환
     *
     * @param jobType Job 타입
     * @return 타입 코드
     */
    private String getTypeCode(JobType jobType) {
        switch (jobType) {
            case AI_RECOMMENDATION:
                return "AI";
            case IMAGE_GENERATION:
                return "IMG";
            default:
                return jobType.name().substring(0, Math.min(5, jobType.name().length()));
        }
    }

    /**
     * UUID 기반 랜덤 문자열 생성
     *
     * @return 8자리 랜덤 문자열 (소문자 영숫자)
     */
    private String generateRandomPart() {
        return UUID.randomUUID()
            .toString()
            .replace("-", "")
            .substring(0, RANDOM_LENGTH)
            .toLowerCase();
    }

    /**
     * jobId 형식 검증
     *
     * @param jobId 검증할 Job ID
     * @return 유효하면 true, 아니면 false
     */
    public boolean isValid(String jobId) {
        if (jobId == null || jobId.isBlank()) {
            return false;
        }

        // JOB-로 시작하는지 확인
        if (!jobId.startsWith(PREFIX + "-")) {
            return false;
        }

        // 길이 검증
        if (jobId.length() > 50) {
            return false;
        }

        // 형식 검증: JOB-{type}-{timestamp}-{8자리영숫자}
        String[] parts = jobId.split("-");
        if (parts.length != 4) {
            return false;
        }

        // timestamp 부분이 숫자인지 확인
        if (!parts[2].matches("\\d+")) {
            return false;
        }

        // random 부분이 8자리 영숫자인지 확인
        if (parts[3].length() != 8 || !parts[3].matches("[a-z0-9]{8}")) {
            return false;
        }

        return true;
    }
}
