package com.ruoyi.web.modules.industryservice.support;

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

import java.math.BigDecimal;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import com.ruoyi.web.modules.industryservice.domain.dto.GrassLivestockBalanceCalculateRequest;
import com.ruoyi.web.modules.industryservice.domain.vo.GrassLivestockBalanceResultVo;

@DisplayName("GrassLivestockBalanceCalculator")
class GrassLivestockBalanceCalculatorTest
{
    @Test
    @DisplayName("ZCZX-CXPH-UT-001～005 标准样本")
    void ut001_standardSample()
    {
        GrassLivestockBalanceResultVo result = GrassLivestockBalanceCalculator.calculate(sampleRequest(100), "示范草场");
        assertEquals(new BigDecimal("22750.00"), result.getAvailableForageKg());
        assertEquals(new BigDecimal("142.19"), result.getTheoreticalCarryingSu());
        assertEquals(new BigDecimal("400.00"), result.getActualCarryingSu());
        assertEquals(new BigDecimal("2.81"), result.getBalanceIndex());
        assertEquals(new BigDecimal("181.32"), result.getOverloadRate());
        assertEquals(GrassLivestockBalanceRules.BALANCE_LEVEL_SEVERE, result.getBalanceLevel());
        assertEquals(new BigDecimal("64000.00"), result.getAnnualForageDemandKg());
        assertEquals(new BigDecimal("41250.00"), result.getForageGapKg());
        assertEquals(new BigDecimal("35.55"), result.getTheoreticalSuitableHeads());
        assertEquals(64, result.getActualOverloadHeads());
    }

    @Test
    @DisplayName("ZCZX-CXPH-UT-006 等级边界")
    void ut006_levelBoundaries()
    {
        assertEquals(GrassLivestockBalanceRules.BALANCE_LEVEL_NOT_OVERLOAD,
                GrassLivestockBalanceCalculator.resolveBalanceLevel(new BigDecimal("0")));
        assertEquals(GrassLivestockBalanceRules.BALANCE_LEVEL_BASIC,
                GrassLivestockBalanceCalculator.resolveBalanceLevel(new BigDecimal("0.10")));
        assertEquals(GrassLivestockBalanceRules.BALANCE_LEVEL_BASIC,
                GrassLivestockBalanceCalculator.resolveBalanceLevel(new BigDecimal("0.15")));
        assertEquals(GrassLivestockBalanceRules.BALANCE_LEVEL_OVERLOAD,
                GrassLivestockBalanceCalculator.resolveBalanceLevel(new BigDecimal("0.1501")));
        assertEquals(GrassLivestockBalanceRules.BALANCE_LEVEL_OVERLOAD,
                GrassLivestockBalanceCalculator.resolveBalanceLevel(new BigDecimal("0.50")));
        assertEquals(GrassLivestockBalanceRules.BALANCE_LEVEL_SEVERE,
                GrassLivestockBalanceCalculator.resolveBalanceLevel(new BigDecimal("0.5001")));
    }

    @Test
    @DisplayName("ZCZX-CXPH-UT-007 未超载（指数<1）")
    void ut007_notOverload()
    {
        GrassLivestockBalanceCalculateRequest req = sampleRequest(35);
        req.setBreedingHeadCount(35);
        GrassLivestockBalanceResultVo result = GrassLivestockBalanceCalculator.calculate(req, "草场");
        assertEquals(GrassLivestockBalanceRules.BALANCE_LEVEL_NOT_OVERLOAD, result.getBalanceLevel());
        assertEquals(0, result.getActualOverloadHeads());
    }

    @Test
    @DisplayName("ZCZX-CXPH-UT-012 存栏为0")
    void ut012_zeroBreeding()
    {
        GrassLivestockBalanceCalculateRequest req = sampleRequest(0);
        req.setBreedingHeadCount(0);
        GrassLivestockBalanceResultVo result = GrassLivestockBalanceCalculator.calculate(req, "草场");
        assertEquals(new BigDecimal("0.00"), result.getActualCarryingSu());
        assertEquals(new BigDecimal("0.00"), result.getAnnualForageDemandKg());
        assertEquals(new BigDecimal("0.00"), result.getBalanceIndex());
        assertEquals(new BigDecimal("-100.00"), result.getOverloadRate());
        assertEquals(GrassLivestockBalanceRules.BALANCE_LEVEL_NOT_OVERLOAD, result.getBalanceLevel());
        assertEquals(0, result.getActualOverloadHeads());
    }

    @Test
    @DisplayName("ZCZX-CXPH-UT-013 理论载畜量为0且有存栏")
    void ut013_zeroTheoreticalWithHeads()
    {
        GrassLivestockBalanceCalculateRequest req = sampleRequest(100);
        req.setGrassYieldPerMu(BigDecimal.ZERO);
        GrassLivestockBalanceResultVo result = GrassLivestockBalanceCalculator.calculate(req, "草场");
        assertNull(result.getBalanceIndex());
        assertNull(result.getOverloadRate());
        assertEquals(GrassLivestockBalanceRules.BALANCE_LEVEL_SEVERE, result.getBalanceLevel());
        assertEquals("无饲草供给", result.getWarning());
    }

    @Test
    @DisplayName("ZCZX-CXPH-UT-014 理论为0且存栏0")
    void ut014_zeroTheoreticalZeroHeads()
    {
        GrassLivestockBalanceCalculateRequest req = sampleRequest(0);
        req.setGrassYieldPerMu(BigDecimal.ZERO);
        req.setBreedingHeadCount(0);
        GrassLivestockBalanceResultVo result = GrassLivestockBalanceCalculator.calculate(req, "草场");
        assertEquals(new BigDecimal("0.00"), result.getBalanceIndex());
        assertEquals(GrassLivestockBalanceRules.BALANCE_LEVEL_NOT_OVERLOAD, result.getBalanceLevel());
    }

    private static GrassLivestockBalanceCalculateRequest sampleRequest(int breedingHeadCount)
    {
        GrassLivestockBalanceCalculateRequest req = new GrassLivestockBalanceCalculateRequest();
        req.setGrasslandId(1L);
        req.setAreaMu(new BigDecimal("100"));
        req.setGrassYieldPerMu(new BigDecimal("350"));
        req.setUtilizationRate(new BigDecimal("0.65"));
        req.setSheepUnitAnnualForageKg(new BigDecimal("160"));
        req.setSheepUnitConvertCoeff(new BigDecimal("4"));
        req.setBreedingHeadCount(breedingHeadCount);
        return req;
    }
}
