package kr.or.bok.rtgs.common

import java.time.LocalDate
import java.time.format.DateTimeFormatter
import java.util.concurrent.atomic.AtomicLong

/**
 * 거래고유식별자(BMI, Business Message Identifier) 생성기 — 총 22자리.
 * 구성: 영업일(8, YYYYMMDD) + 기관코드(4) + 일련번호(10).
 * BMI는 접수 센터에서 거래마다 유일하게 부여되며, 이후 저널을 통해 타 센터로 전파되어
 * 멱등성(idempotency) 중복체크의 키가 된다(같은 거래는 두 번 반영되지 않음).
 */
class BmiGenerator(private val orgCode: String) {
    private val serial = AtomicLong(0)

    init {
        require(orgCode.length <= 4) { "orgCode must be <= 4 chars: $orgCode" }
    }

    fun next(businessDate: LocalDate = LocalDate.now()): String {
        val date = businessDate.format(DATE_FMT)                 // 8
        val org = orgCode.padStart(4, '0')                       // 4
        val seq = serial.incrementAndGet().toString().padStart(10, '0') // 10
        return (date + org + seq).let {
            require(it.length == 22) { "BMI length != 22: $it (${it.length})" }
            it
        }
    }

    companion object {
        private val DATE_FMT: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd")

        /** BMI 구성요소 파싱(검증/조회용). */
        fun businessDateOf(bmi: String): String = bmi.substring(0, 8)
        fun orgCodeOf(bmi: String): String = bmi.substring(8, 12)
    }
}
