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

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

import java.util.Collections;
import java.util.Date;
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.dto.OpenQuarantineRecordDto;
import com.ruoyi.web.modules.industryservice.domain.vo.YakAssetSyncResultVo;
import com.ruoyi.web.modules.industryservice.support.ThirdPartyHealthRecordClient;
import com.ruoyi.web.modules.industryservice.support.YakDiseaseWarningRules;

@ExtendWith(MockitoExtension.class)
@DisplayName("YakDiseaseWarningSyncService")
class YakDiseaseWarningSyncServiceTest
{
    @Mock
    private ThirdPartyHealthRecordClient thirdPartyHealthRecordClient;

    @Mock
    private YakHealthSourceRecordSyncTxService healthSourceRecordSyncTxService;

    @Mock
    private YakDiseaseWarningAnalyzer warningAnalyzer;

    @InjectMocks
    private YakDiseaseWarningSyncService syncService;

    @Test
    @DisplayName("ZCZX-MYNBJY-UT-010 第三方失败不清库")
    void ut010_thirdPartyFail()
    {
        when(thirdPartyHealthRecordClient.fetchQuarantineRecords()).thenThrow(new ServiceException("超时"));
        assertThrows(ServiceException.class, () -> syncService.syncFromThirdParty());
        verify(healthSourceRecordSyncTxService, never()).persistSourceRecord(any(), any());
        verify(warningAnalyzer, never()).analyzeAndGenerate(any());
    }

    @Test
    @DisplayName("ZCZX-MYNBJY-UT-008 源记录新增计数")
    void ut008_insert()
    {
        OpenQuarantineRecordDto dto = sampleQuarantine(3001L);
        when(thirdPartyHealthRecordClient.fetchQuarantineRecords()).thenReturn(Collections.singletonList(dto));
        when(thirdPartyHealthRecordClient.fetchDiagnosisRecords()).thenReturn(Collections.emptyList());
        when(thirdPartyHealthRecordClient.fetchBreedingProcessRecords()).thenReturn(Collections.emptyList());
        when(healthSourceRecordSyncTxService.persistSourceRecord(any(), any())).thenReturn(true);
        when(warningAnalyzer.analyzeAndGenerate(any(Date.class))).thenReturn(1);
        YakAssetSyncResultVo result = syncService.syncFromThirdParty();
        assertEquals(2, result.getInsertCount());
    }

    @Test
    @DisplayName("ZCZX-MYNBJY-UT-012 处理中拒重复")
    void ut012_syncInProgress() throws Exception
    {
        OpenQuarantineRecordDto dto = sampleQuarantine(3002L);
        when(thirdPartyHealthRecordClient.fetchQuarantineRecords()).thenAnswer(inv -> {
            Thread.sleep(200);
            return Collections.singletonList(dto);
        });
        when(thirdPartyHealthRecordClient.fetchDiagnosisRecords()).thenReturn(Collections.emptyList());
        when(thirdPartyHealthRecordClient.fetchBreedingProcessRecords()).thenReturn(Collections.emptyList());
        when(healthSourceRecordSyncTxService.persistSourceRecord(any(), any())).thenReturn(true);
        when(warningAnalyzer.analyzeAndGenerate(any(Date.class))).thenReturn(0);
        Thread t1 = new Thread(() -> syncService.syncFromThirdParty());
        t1.start();
        Thread.sleep(50);
        ServiceException ex = assertThrows(ServiceException.class, () -> syncService.syncFromThirdParty());
        assertEquals(YakDiseaseWarningRules.MSG_SYNC_IN_PROGRESS, ex.getMessage());
        t1.join();
    }

    private static OpenQuarantineRecordDto sampleQuarantine(Long id)
    {
        OpenQuarantineRecordDto dto = new OpenQuarantineRecordDto();
        dto.setId(id);
        dto.setFarmId(1L);
        dto.setFarmName("示范牧场");
        dto.setFarmEnclosureId(101L);
        dto.setCattleId(5001L);
        dto.setEarTagNumber("YAK-Q-TEST");
        dto.setQuarantineTime("2026-05-19 10:00:00");
        dto.setQuarantineResult("阳性");
        return dto;
    }
}
