package com.zioinfo.kintex.settlement;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * F085 환불·취소 규정 룰셋 로더 — classpath {@code rulesets/refund-v1.0.json}을 로드해
 * 환불 구간(brackets)과 버전을 제공한다. 룰은 코드가 아닌 데이터로 버전 관리되므로(규정 개정 대응)
 * 부팅 시 1회 읽어 캐시한다. 금액 산식은 {@link RefundCalc}(순수 함수) 위임.
 *
 * <p>파싱 실패 시(파일 훼손 등) 빈 구간 + fail-safe 기본값을 유지한다(부팅은 계속). 이 경우 환불 산정은
 * "개막일 미확정"과 동일하게 자동 0% 처리되어 재무 수기 검토로 이관된다.
 */
@Component
public class RefundPolicy {

    private static final Logger log = LoggerFactory.getLogger(RefundPolicy.class);
    private static final String RESOURCE = "rulesets/refund-v1.0.json";

    private final String version;
    private final List<RefundCalc.Bracket> brackets;
    private final double afterEventRatePercent;
    private final double unknownDateRatePercent;

    public RefundPolicy(ObjectMapper objectMapper) {
        String v = "refund-v1.0";
        List<RefundCalc.Bracket> b = new ArrayList<>();
        double afterEvent = 0.0;
        double unknown = 0.0;
        try (InputStream in = new ClassPathResource(RESOURCE).getInputStream()) {
            JsonNode root = objectMapper.readTree(in);
            v = root.path("rulesetVersion").asText(v);
            JsonNode policy = root.path("policy");
            afterEvent = policy.path("afterEventRefundRatePercent").asDouble(0.0);
            unknown = policy.path("unknownDateRefundRatePercent").asDouble(0.0);
            JsonNode arr = policy.path("brackets");
            if (arr.isArray()) {
                for (JsonNode n : arr) {
                    b.add(new RefundCalc.Bracket(
                            n.path("minDaysBefore").asInt(0),
                            n.path("refundRatePercent").asDouble(0.0),
                            n.path("label").asText("")));
                }
            }
        } catch (Exception e) {
            log.error("환불 룰셋 로드 실패({}): {} — fail-safe 기본값(빈 구간·0%) 적용", RESOURCE, e.getMessage());
        }
        this.version = v;
        this.brackets = Collections.unmodifiableList(b);
        this.afterEventRatePercent = afterEvent;
        this.unknownDateRatePercent = unknown;
    }

    public String version() {
        return version;
    }

    public List<RefundCalc.Bracket> brackets() {
        return brackets;
    }

    public double afterEventRatePercent() {
        return afterEventRatePercent;
    }

    public double unknownDateRatePercent() {
        return unknownDateRatePercent;
    }
}
