package com.erp.util;

import org.junit.jupiter.api.Test;

import java.math.BigDecimal;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

class DecimalUtilsTest {

    // ── parse ──────────────────────────────────────────────────────────────

    @Test
    void parse_null_returnsZero() {
        assertEquals(BigDecimal.ZERO, DecimalUtils.parse(null));
    }

    @Test
    void parse_emptyString_returnsZero() {
        assertEquals(BigDecimal.ZERO, DecimalUtils.parse("  "));
    }

    @Test
    void parse_validString() {
        assertEquals(new BigDecimal("123.45"), DecimalUtils.parse("123.45"));
    }

    // ── toBigDecimal ───────────────────────────────────────────────────────

    @Test
    void toBigDecimal_fromString() {
        assertEquals(new BigDecimal("123.45"), DecimalUtils.toBigDecimal("123.45"));
    }

    @Test
    void toBigDecimal_fromNull_returnsZero() {
        assertEquals(BigDecimal.ZERO, DecimalUtils.toBigDecimal(null));
    }

    @Test
    void toBigDecimal_fromInteger() {
        assertEquals(new BigDecimal("100"), DecimalUtils.toBigDecimal(100));
    }

    // ── scale2 ────────────────────────────────────────────────────────────

    @Test
    void scale2_roundsHalfUp() {
        assertEquals(new BigDecimal("1.24"), DecimalUtils.scale2(new BigDecimal("1.235")));
    }

    // ── multiply ──────────────────────────────────────────────────────────

    @Test
    void multiply_100_and_01_returns_10_0000() {
        // float/double: 100 * 0.1 = 10.000000000000002 (부동소수점 오차)
        // BigDecimal: 정확히 10.0000
        assertEquals(new BigDecimal("10.0000"), DecimalUtils.multiply("100", "0.1"));
    }

    @Test
    void multiply_stringOverload_scale4() {
        assertEquals(new BigDecimal("35.0000"), DecimalUtils.multiply("10", "3.5"));
    }

    // ── add / subtract ────────────────────────────────────────────────────

    @Test
    void add_floatingPoint_precision() {
        // float/double: 0.1 + 0.2 = 0.30000000000000004
        // BigDecimal: 정확히 0.3
        BigDecimal result = DecimalUtils.add("0.1", "0.2");
        assertEquals(0, result.compareTo(new BigDecimal("0.3")));
    }

    @Test
    void add_correctResult() {
        assertEquals(new BigDecimal("15.0"), DecimalUtils.add("10.5", "4.5"));
    }

    @Test
    void subtract_correctResult() {
        assertEquals(new BigDecimal("12.5"), DecimalUtils.subtract("20", "7.5"));
    }

    // ── addTax ────────────────────────────────────────────────────────────

    @Test
    void addTax_10percent() {
        // 1000 + 10% = 1100.00
        assertEquals(new BigDecimal("1100.00"), DecimalUtils.addTax("1000", "10"));
    }

    @Test
    void addTax_vat() {
        // 100 + 10% = 110.00
        assertEquals(new BigDecimal("110.00"), DecimalUtils.addTax("100", "10"));
    }

    // ── divide ────────────────────────────────────────────────────────────

    @Test
    void divide_scale2() {
        assertEquals(new BigDecimal("3.33"), DecimalUtils.divide("10", "3", 2));
    }

    @Test
    void divide_scale4() {
        assertEquals(new BigDecimal("0.3333"), DecimalUtils.divide("1", "3", 4));
    }

    // ── sum ───────────────────────────────────────────────────────────────

    @Test
    void sum_list() {
        List<String> values = List.of("100", "200.5", "50.25");
        assertEquals(0, DecimalUtils.sum(values).compareTo(new BigDecimal("350.75")));
    }

    @Test
    void sum_null_returnsZero() {
        assertEquals(BigDecimal.ZERO, DecimalUtils.sum(null));
    }

    @Test
    void sum_emptyList_returnsZero() {
        assertEquals(BigDecimal.ZERO, DecimalUtils.sum(List.of()));
    }
}
