package com.ruoyi.web.modules.video.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.doThrow;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

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.circulation.mapper.BizTradeMarketMapper;
import com.ruoyi.web.modules.industrypolicy.support.PastureRules;
import com.ruoyi.web.modules.industryservice.domain.BizPasture;
import com.ruoyi.web.modules.industryservice.mapper.BizPastureMapper;
import com.ruoyi.web.modules.video.LivestockMonitorTestSamples;
import com.ruoyi.web.modules.video.domain.BizLivestockMonitor;
import com.ruoyi.web.modules.video.mapper.BizLivestockMonitorMapper;
import com.ruoyi.web.modules.video.support.LivestockMonitorOwnerResolver;
import com.ruoyi.web.modules.video.support.LivestockMonitorRules;

@ExtendWith(MockitoExtension.class)
@DisplayName("BizLivestockMonitorServiceImpl")
class BizLivestockMonitorServiceImplTest
{
    @Mock
    private BizLivestockMonitorMapper monitorMapper;

    @Mock
    private LivestockMonitorOwnerResolver ownerResolver;

    @Mock
    private BizPastureMapper pastureMapper;

    @Mock
    private BizTradeMarketMapper tradeMarketMapper;

    @InjectMocks
    private BizLivestockMonitorServiceImpl service;

    @Test
    @DisplayName("新增仅监控名称")
    void insertMinimal()
    {
        BizLivestockMonitor row = LivestockMonitorTestSamples.sampleMinimal();
        when(monitorMapper.insertBizLivestockMonitor(any())).thenReturn(1);
        service.insertBizLivestockMonitor(row);
        verify(ownerResolver, never()).applyOwnerToRow(any());
        verify(monitorMapper).insertBizLivestockMonitor(any());
    }

    @Test
    @DisplayName("新增落库")
    void insert()
    {
        BizLivestockMonitor row = LivestockMonitorTestSamples.samplePastureMonitor();
        when(monitorMapper.insertBizLivestockMonitor(any())).thenReturn(1);
        service.insertBizLivestockMonitor(row);
        verify(ownerResolver).applyOwnerToRow(row);
        verify(monitorMapper).insertBizLivestockMonitor(any());
    }

    @Test
    @DisplayName("已删不可改")
    void updateDeleted()
    {
        when(monitorMapper.selectBizLivestockMonitorById(9L)).thenReturn(null);
        BizLivestockMonitor row = LivestockMonitorTestSamples.sampleWithId(9L);
        assertThrows(ServiceException.class, () -> service.updateBizLivestockMonitor(row));
    }

    @Test
    @DisplayName("逻辑删除")
    void remove()
    {
        BizLivestockMonitor db = LivestockMonitorTestSamples.sampleWithId(5L);
        when(monitorMapper.selectBizLivestockMonitorByIdAny(5L)).thenReturn(db);
        when(monitorMapper.logicDeleteBizLivestockMonitorByIds(any(), eq("admin"))).thenReturn(1);
        int n = service.deleteBizLivestockMonitorByIds(new Long[] { 5L }, "admin");
        assertEquals(1, n);
    }

    @Test
    @DisplayName("ownerOptions 仅正常主体")
    void ownerOptions()
    {
        BizPasture pasture = new BizPasture();
        pasture.setId(LivestockMonitorTestSamples.PASTURE_OWNER_ID);
        pasture.setPastureName("巴青牧场");
        pasture.setDelFlag(PastureRules.DEL_FLAG_NORMAL);
        when(pastureMapper.selectBizPastureList(any())).thenReturn(Collections.singletonList(pasture));
        when(tradeMarketMapper.selectBizTradeMarketList(any())).thenReturn(Collections.emptyList());
        assertEquals(1, service.selectOwnerOptions(null).size());
    }

    @Test
    @DisplayName("列表填充类型名")
    void listEnrich()
    {
        BizLivestockMonitor row = LivestockMonitorTestSamples.sampleWithId(1L);
        when(monitorMapper.selectBizLivestockMonitorList(any())).thenReturn(Collections.singletonList(row));
        BizLivestockMonitor listed = service.selectBizLivestockMonitorList(new BizLivestockMonitor()).get(0);
        assertEquals("养殖主体", listed.getOwnerTypeName());
    }

    @Test
    @DisplayName("停业牧场校验由 resolver 抛出")
    void ownerResolverPastureStopped()
    {
        doThrow(new ServiceException("owner not found or stopped"))
                .when(ownerResolver).applyOwnerToRow(any());
        assertThrows(ServiceException.class,
                () -> service.insertBizLivestockMonitor(LivestockMonitorTestSamples.samplePastureMonitor()));
        verify(monitorMapper, never()).insertBizLivestockMonitor(any());
    }
}
