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.ArgumentMatchers.anyList;
import static org.mockito.Mockito.when;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collections;
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.web.modules.industryservice.BreedingIndustryTestSamples;
import com.ruoyi.web.modules.industryservice.domain.vo.BreedingIndustryDashboardVo;
import com.ruoyi.web.modules.industryservice.mapper.BreedingIndustryStatsMapper;
import com.ruoyi.web.modules.industryservice.support.BreedingIndustryPastureScope;
import com.ruoyi.web.modules.industryservice.support.BreedingIndustryRules;

@ExtendWith(MockitoExtension.class)
@DisplayName("BreedingIndustryDashboardServiceImpl")
class BreedingIndustryDashboardServiceImplTest
{
    @Mock
    private BreedingIndustryStatsMapper breedingIndustryStatsMapper;

    @Mock
    private BreedingIndustryPastureScope breedingIndustryPastureScope;

    @InjectMocks
    private BreedingIndustryDashboardServiceImpl service;

    @Test
    @DisplayName("ZCZX-YZCYSJ-UT-002 可见牧场为空")
    void ut002_emptyScope()
    {
        stubGrassland();
        when(breedingIndustryPastureScope.resolveAllowedPastureIds()).thenReturn(Collections.emptyList());
        BreedingIndustryDashboardVo vo = service.loadDashboard(false);
        assertEquals(0, vo.getOverview().getInventoryTotal());
        assertEquals(0, vo.getOverview().getPastureCount());
        assertEquals(3, vo.getOverview().getGrasslandCount());
        assertEquals(0, vo.getInventoryChange().getMonthlyTrend().size());
    }

    @Test
    @DisplayName("ZCZX-YZCYSJ-UT-009 公母未标=总量")
    void ut009_genderSum()
    {
        stubGrassland();
        when(breedingIndustryPastureScope.resolveAllowedPastureIds())
                .thenReturn(Collections.singletonList(BreedingIndustryTestSamples.PASTURE_P1));
        when(breedingIndustryStatsMapper.countPastureInScope(anyList())).thenReturn(1);
        when(breedingIndustryStatsMapper.countInventory(anyList())).thenReturn(3);
        when(breedingIndustryStatsMapper.countAnnualOutbound(anyList(), any(), any())).thenReturn(0);
        when(breedingIndustryStatsMapper.countWarningYak(anyList(), any(), any())).thenReturn(0);
        when(breedingIndustryStatsMapper.selectYakSnapshotsInScope(anyList())).thenReturn(Arrays.asList(
                BreedingIndustryTestSamples.normalBull(),
                BreedingIndustryTestSamples.normalCow(),
                BreedingIndustryTestSamples.unknownGender()));
        BreedingIndustryDashboardVo vo = service.loadDashboard(false);
        assertEquals(3, vo.getOverview().getInventoryTotal());
        assertEquals(1, vo.getInventoryChange().getBullCount());
        assertEquals(1, vo.getInventoryChange().getCowCount());
        assertEquals(1, vo.getInventoryChange().getUnknownGenderCount());
    }

    @Test
    @DisplayName("ZCZX-YZCYSJ-API-019 聚合异常")
    void api019_loadFailed()
    {
        when(breedingIndustryPastureScope.resolveAllowedPastureIds())
                .thenThrow(new RuntimeException("db"));
        ServiceException ex = assertThrows(ServiceException.class, () -> service.loadDashboard(false));
        assertEquals(BreedingIndustryRules.MSG_LOAD_FAILED, ex.getMessage());
    }

    private void stubGrassland()
    {
        when(breedingIndustryStatsMapper.countGrassland()).thenReturn(3);
        when(breedingIndustryStatsMapper.sumGrasslandAreaMu()).thenReturn(new BigDecimal("100.00"));
        when(breedingIndustryStatsMapper.countAvailableGrassland()).thenReturn(2);
        when(breedingIndustryStatsMapper.countInUseGrassland(any())).thenReturn(1);
        when(breedingIndustryStatsMapper.selectDegradationGroupCounts()).thenReturn(Collections.emptyList());
    }
}
