package com.ruoyi.web.modules.industryservice.service.impl;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;

import java.math.BigDecimal;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.web.modules.industryservice.domain.BizGrassland;
import com.ruoyi.web.modules.industryservice.domain.dto.GrassLivestockBalanceCalculateRequest;
import com.ruoyi.web.modules.industryservice.domain.vo.GrassLivestockBalanceResultVo;
import com.ruoyi.web.modules.industryservice.mapper.BizGrasslandMapper;
import com.ruoyi.web.modules.industryservice.support.GrassLivestockBalanceRules;
import com.ruoyi.web.modules.industryservice.support.GrasslandRules;

@ExtendWith(MockitoExtension.class)
@DisplayName("GrassLivestockBalanceServiceImpl")
class GrassLivestockBalanceServiceImplTest
{
    @Mock
    private BizGrasslandMapper bizGrasslandMapper;

    @Mock
    private ISysConfigService sysConfigService;

    @InjectMocks
    private GrassLivestockBalanceServiceImpl service;

    @Test
    @DisplayName("ZCZX-CXPH-API-001 计算成功")
    void calculateSuccess()
    {
        when(bizGrasslandMapper.selectBizGrasslandById(1L)).thenReturn(activeGrassland());
        GrassLivestockBalanceResultVo result = service.calculate(sampleRequest());
        assertEquals(new BigDecimal("22750.00"), result.getAvailableForageKg());
        assertEquals("示范草场", result.getGrasslandName());
    }

    @Test
    @DisplayName("ZCZX-CXPH-API-011 草场无效")
    void calculateInvalidGrassland()
    {
        when(bizGrasslandMapper.selectBizGrasslandById(99L)).thenReturn(null);
        GrassLivestockBalanceCalculateRequest req = sampleRequest();
        req.setGrasslandId(99L);
        assertThrows(ServiceException.class, () -> service.calculate(req));
    }

    @Test
    @DisplayName("ZCZX-CXPH-API-014 默认值")
    void defaultsFromConfig()
    {
        when(sysConfigService.selectConfigByKey(GrassLivestockBalanceRules.CONFIG_SHEEP_UNIT_ANNUAL_FORAGE_KG))
                .thenReturn("180");
        when(sysConfigService.selectConfigByKey(GrassLivestockBalanceRules.CONFIG_SHEEP_UNIT_CONVERT_COEFF))
                .thenReturn("5");
        assertEquals(new BigDecimal("180"), service.getDefaults().getSheepUnitAnnualForageKg());
        assertEquals(new BigDecimal("5"), service.getDefaults().getSheepUnitConvertCoeff());
    }

    @Test
    @DisplayName("默认值回退")
    void defaultsFallback()
    {
        when(sysConfigService.selectConfigByKey(any())).thenReturn("");
        assertEquals(GrassLivestockBalanceRules.DEFAULT_SHEEP_UNIT_ANNUAL_FORAGE_KG,
                service.getDefaults().getSheepUnitAnnualForageKg());
    }

    private static BizGrassland activeGrassland()
    {
        BizGrassland g = new BizGrassland();
        g.setId(1L);
        g.setGrasslandName("示范草场");
        g.setDelFlag(GrasslandRules.DEL_FLAG_NORMAL);
        return g;
    }

    private static GrassLivestockBalanceCalculateRequest sampleRequest()
    {
        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(100);
        return req;
    }
}
