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 생성 (백엔드용)
     *
     * 참고: 현재는 프론트엔드에서 eventId를 생성하므로 이 메서드는 거의 사용되지 않습니다.
     *
     * @param storeId 상점 ID
     * @return 생성된 이벤트 ID
     */
    public String generate(String storeId) {
        // 기본값 처리
        if (storeId == null || storeId.isBlank()) {
            storeId = "unknown";
        }

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

        // 형식: EVT-{storeId}-{timestamp}-{random}
        String eventId = String.format("%s-%s-%s-%s", PREFIX, storeId, timestamp, randomPart);

        return eventId;
    }

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

    /**
     * eventId 기본 검증
     *
     * 최소한의 검증만 수행합니다:
     * - null/empty 체크
     * - 길이 제한 체크 (VARCHAR(50) 제약)
     *
     * 프론트엔드에서 생성한 eventId를 신뢰하며,
     * DB의 PRIMARY KEY 제약조건으로 중복을 방지합니다.
     *
     * @param eventId 검증할 이벤트 ID
     * @return 유효하면 true, 아니면 false
     */
    public boolean isValid(String eventId) {
        if (eventId == null || eventId.isBlank()) {
            return false;
        }

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

        return true;
    }
}
