package com.zt.plat.module.qms;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

import java.math.BigDecimal;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import com.zt.plat.module.qms.core.qlexpress.cmp.AllowanceCalculatorComponent;
import com.zt.plat.module.qms.core.qlexpress.config.QlExpressRuleEngineConfig;

import jakarta.annotation.Resource;

@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = { AllowanceCalculatorComponent.class, QlExpressRuleEngineConfig.class })
@DisplayName("允差计算器 AllowanceCalculatorComponent 测试")
public class AllowanceCalculatorComponentTest {

	@Resource
	private AllowanceCalculatorComponent calculator;

	private final int SCALE = 4;

	@BeforeEach
	void setUp() {
		// 可在此模拟依赖或初始化数据
	}

	@Test
	@DisplayName("应正确计算线性允差值")
	void shouldCalculateLinearAllowanceCorrectly() {

	    BigDecimal minValue = new BigDecimal("0");
	    BigDecimal maxValue = new BigDecimal("100");
	    BigDecimal minYc = new BigDecimal("0.1");
	    BigDecimal maxYc = new BigDecimal("0.5");
	    BigDecimal c = new BigDecimal("0.02");
	    BigDecimal ran = new BigDecimal("60");
	    Integer isUseFormula = 0;

	    BigDecimal result = calculator.calculateAllowableValue(
	            minValue, maxValue, minYc, maxYc, c, ran, isUseFormula, null, SCALE);

	    // Assert
	    assertEquals(new BigDecimal("0.3600"), result);
	    
	}

	@Test
	@DisplayName("应正确执行自定义表达式")
	void shouldEvaluateCustomFormulaCorrectly() {
		// Arrange
		BigDecimal minValue = BigDecimal.ZERO;
		BigDecimal maxValue = new BigDecimal("100");
		BigDecimal minYc = new BigDecimal("0.1");
		BigDecimal maxYc = new BigDecimal("0.5");
		BigDecimal c = BigDecimal.ZERO;
		BigDecimal ran = new BigDecimal("70");
		Integer isUseFormula = 1;
		String formula = "X > 50 ? 0.8 : 0.3";

		// Act
		BigDecimal result = calculator.calculateAllowableValue(minValue, maxValue, minYc, maxYc, c, ran, isUseFormula,
				formula, SCALE);

		// Assert
		assertEquals(new BigDecimal("0.8000"), result);
	}
	
	// ——————————————————————————————————————
    // 测试：异常情况
    // ——————————————————————————————————————

    @Test
    @DisplayName("启用自定义公式但 formula 为空应抛出异常")
    void shouldThrowExceptionWhenFormulaIsNullAndUseFormulaIsTrue() {
        assertThrows(IllegalArgumentException.class, () -> {
            calculator.calculateAllowableValue(
                    BigDecimal.ONE, BigDecimal.TEN, BigDecimal.ONE, BigDecimal.TEN,
                    BigDecimal.ZERO, BigDecimal.ONE, 1, null, SCALE);
        });
    }

    @Test
    @DisplayName("表达式语法错误应抛出异常")
    void shouldThrowExceptionWhenFormulaSyntaxError() {
        assertThrows(RuntimeException.class, () -> {
            calculator.calculateAllowableValue(
                    BigDecimal.ONE, BigDecimal.TEN, BigDecimal.ONE, BigDecimal.TEN,
                    BigDecimal.ZERO, BigDecimal.ONE, 1, "X + + 1", SCALE);
        });
    }

    @Test
    @DisplayName("参数为 null 应抛出异常")
    void shouldThrowExceptionWhenNullParameter() {
        assertThrows(IllegalArgumentException.class, () -> {
            calculator.calculateAllowableValue(
                    null, BigDecimal.TEN, BigDecimal.ONE, BigDecimal.TEN,
                    BigDecimal.ZERO, BigDecimal.ONE, 0, null, SCALE);
        });
    }
}
