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

import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.UUID;

/**
 * 이벤트 ID 생성기
 *
 * 비즈니스 친화적인 eventId를 생성합니다.
 * 형식: EVT-{storeId}-{yyyyMMddHHmmss}-{random8}
 * 예시: EVT-store123-20251029143025-a1b2c3d4
 *
 * VARCHAR(50) 길이 제약사항을 고려하여 설계되었습니다.
 */
@Component
public class EventIdGenerator {

    private static final String PREFIX = "EVT";
    private static final DateTimeFormatter TIMESTAMP_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
    private static final int RANDOM_LENGTH = 8;

    /**
     * 이벤트 ID 생성
     *
     * @param storeId 상점 ID (최대 15자 권장)
     * @return 생성된 이벤트 ID
     * @throws IllegalArgumentException storeId가 null이거나 비어있는 경우
     */
    public String generate(String storeId) {
        if (storeId == null || storeId.isBlank()) {
            throw new IllegalArgumentException("storeId는 필수입니다");
        }

        // storeId 길이 검증 (전체 길이 50자 제한)
        // TODO: 프로덕션에서는 storeId 길이 제한 필요
        // if (storeId.length() > 15) {
        //     throw new IllegalArgumentException("storeId는 15자 이하여야 합니다");
        // }

        String timestamp = LocalDateTime.now().format(TIMESTAMP_FORMATTER);
        String randomPart = generateRandomPart();

        // 형식: EVT-{storeId}-{timestamp}-{random}
        // 예상 길이: 3 + 1 + 15 + 1 + 14 + 1 + 8 = 43자 (최대)
        String eventId = String.format("%s-%s-%s-%s", PREFIX, storeId, timestamp, randomPart);

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

        return eventId;
    }

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

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

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

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

        // 형식 검증: EVT-{storeId}-{14자리숫자}-{8자리영숫자}
        String[] parts = eventId.split("-");
        if (parts.length != 4) {
            return false;
        }

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

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

        return true;
    }
}
