package com.ga.common.util;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;

/**
 * 금액 계산 유틸. 모든 금액은 BigDecimal, 반올림은 HALF_UP, 소수점 2자리.
 */
public final class MoneyUtil {

    private MoneyUtil() {}

    public static final int     SCALE = 2;
    public static final BigDecimal HUNDRED = BigDecimal.valueOf(100);
    public static final BigDecimal DEFAULT_TAX_RATE = new BigDecimal("3.3");

    private static final DecimalFormat FMT      = new DecimalFormat("#,##0");
    private static final DecimalFormat FMT_DEC  = new DecimalFormat("#,##0.00");
    private static final DecimalFormat FMT_SIGN = new DecimalFormat("+#,##0;-#,##0");

    public static BigDecimal zero(BigDecimal v) {
        return v == null ? BigDecimal.ZERO : v;
    }

    public static BigDecimal add(BigDecimal a, BigDecimal b) {
        return zero(a).add(zero(b));
    }

    public static BigDecimal sub(BigDecimal a, BigDecimal b) {
        return zero(a).subtract(zero(b));
    }

    public static BigDecimal mul(BigDecimal a, BigDecimal b) {
        return zero(a).multiply(zero(b)).setScale(SCALE, RoundingMode.HALF_UP);
    }

    public static BigDecimal div(BigDecimal a, BigDecimal b) {
        if (b == null || b.signum() == 0) return BigDecimal.ZERO;
        return zero(a).divide(b, SCALE, RoundingMode.HALF_UP);
    }

    /** amount × rate / 100 (HALF_UP, 2자리) */
    public static BigDecimal pct(BigDecimal amount, BigDecimal ratePct) {
        if (amount == null || ratePct == null) return BigDecimal.ZERO;
        return amount.multiply(ratePct).divide(HUNDRED, SCALE, RoundingMode.HALF_UP);
    }

    /** 세액 계산 (기본 3.3%) */
    public static BigDecimal tax(BigDecimal amount) {
        return pct(amount, DEFAULT_TAX_RATE);
    }

    public static BigDecimal tax(BigDecimal amount, BigDecimal ratePct) {
        return pct(amount, ratePct);
    }

    public static String fmt(BigDecimal v) {
        return v == null ? "" : FMT.format(v);
    }

    public static String fmtDec(BigDecimal v) {
        return v == null ? "" : FMT_DEC.format(v);
    }

    public static String fmtSign(BigDecimal v) {
        return v == null ? "" : FMT_SIGN.format(v);
    }

    public static boolean isZero(BigDecimal v)     { return v == null || v.signum() == 0; }
    public static boolean isPositive(BigDecimal v) { return v != null && v.signum() > 0;  }
    public static boolean isNegative(BigDecimal v) { return v != null && v.signum() < 0;  }
}
