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

import java.util.Collections;
import java.util.List;
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.domain.BizYakAsset;
import com.ruoyi.web.modules.industryservice.domain.BizYakGrowthRecord;
import com.ruoyi.web.modules.industryservice.domain.vo.YakAssetDetailVo;
import com.ruoyi.web.modules.industryservice.domain.vo.YakAssetGrowthChartVo;
import com.ruoyi.web.modules.industryservice.mapper.BizYakAssetMapper;
import com.ruoyi.web.modules.industryservice.mapper.BizYakFeedingRecordMapper;
import com.ruoyi.web.modules.industryservice.mapper.BizYakReproductionRecordMapper;
import com.ruoyi.web.modules.industryservice.service.YakAssetGrowthLiveService;
import com.ruoyi.web.modules.industryservice.service.YakAssetPhysioLiveService;

@ExtendWith(MockitoExtension.class)
@DisplayName("BizYakAssetServiceImpl")
class BizYakAssetServiceImplTest
{
    @Mock
    private BizYakAssetMapper bizYakAssetMapper;

    @Mock
    private YakAssetPhysioLiveService yakAssetPhysioLiveService;

    @Mock
    private YakAssetGrowthLiveService yakAssetGrowthLiveService;

    @Mock
    private BizYakReproductionRecordMapper reproductionRecordMapper;

    @Mock
    private BizYakFeedingRecordMapper feedingRecordMapper;

    @InjectMocks
    private BizYakAssetServiceImpl service;

    @Test
    @DisplayName("ZCZX-MYNZDA-UT-013 详情组装")
    void ut013_detail()
    {
        BizYakAsset asset = sampleAsset(1L);
        when(bizYakAssetMapper.selectBizYakAssetById(1L)).thenReturn(asset);
        when(yakAssetGrowthLiveService.fetchGrowthRecords(asset)).thenReturn(Collections.emptyList());
        when(reproductionRecordMapper.selectByYakAssetId(1L)).thenReturn(Collections.emptyList());
        when(feedingRecordMapper.selectByYakAssetId(1L)).thenReturn(Collections.emptyList());
        YakAssetDetailVo vo = service.selectDetailById(1L);
        assertEquals("YAK20250001", vo.getAsset().getYakNo());
        verify(yakAssetPhysioLiveService).enrichRealtimePhysio(asset);
    }

    @Test
    @DisplayName("ZCZX-MYNZDA-UT-014 已删不可查")
    void ut014_notFound()
    {
        when(bizYakAssetMapper.selectBizYakAssetById(99L)).thenReturn(null);
        assertThrows(ServiceException.class, () -> service.selectDetailById(99L));
    }

    @Test
    @DisplayName("ZCZX-MYNZDA-UT-012 生长曲线分组")
    void ut012_growthChart()
    {
        BizYakAsset asset = sampleAsset(2L);
        when(bizYakAssetMapper.selectBizYakAssetById(2L)).thenReturn(asset);
        YakAssetGrowthChartVo chartVo = new YakAssetGrowthChartVo();
        chartVo.getActual().add(new com.ruoyi.web.modules.industryservice.domain.vo.YakAssetGrowthChartPointVo());
        when(yakAssetGrowthLiveService.fetchGrowthChart(asset, "weight")).thenReturn(chartVo);
        YakAssetGrowthChartVo chart = service.selectGrowthChart(2L, "weight");
        assertEquals(1, chart.getActual().size());
        assertEquals(0, chart.getForecast().size());
    }

    @Test
    @DisplayName("ZCZX-MYNZDA-UT-015 byNo")
    void ut015_byNo()
    {
        BizYakAsset asset = sampleAsset(3L);
        when(bizYakAssetMapper.selectBizYakAssetByYakNo("YAK20250001")).thenReturn(asset);
        when(yakAssetGrowthLiveService.fetchGrowthRecords(asset)).thenReturn(Collections.emptyList());
        when(reproductionRecordMapper.selectByYakAssetId(3L)).thenReturn(Collections.emptyList());
        when(feedingRecordMapper.selectByYakAssetId(3L)).thenReturn(Collections.emptyList());
        YakAssetDetailVo vo = service.selectDetailByYakNo("YAK20250001");
        assertEquals(3L, vo.getAsset().getId());
    }

    @Test
    @DisplayName("列表非法状态")
    void listInvalidStatus()
    {
        BizYakAsset query = new BizYakAsset();
        query.setAssetStatus(99);
        assertThrows(ServiceException.class, () -> service.selectBizYakAssetList(query));
    }

    @Test
    @DisplayName("ZCZX-MYNZDA-UT-011 生理曲线")
    void ut011_physioChart()
    {
        BizYakAsset asset = sampleAsset(4L);
        when(bizYakAssetMapper.selectBizYakAssetById(4L)).thenReturn(asset);
        when(yakAssetPhysioLiveService.fetchPhysioChart(asset, 30)).thenReturn(Collections.emptyList());
        List<?> chart = service.selectPhysioChart(4L, null);
        assertEquals(0, chart.size());
        verify(yakAssetPhysioLiveService).fetchPhysioChart(eq(asset), eq(30));
    }

    private static BizYakAsset sampleAsset(Long id)
    {
        BizYakAsset a = new BizYakAsset();
        a.setId(id);
        a.setYakNo("YAK20250001");
        a.setAssetStatus(2);
        return a;
    }
}
