package com.ruoyi.web.modules.epidemic.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.argThat;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
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.web.modules.epidemic.LabDetectionTestSamples;
import com.ruoyi.web.modules.epidemic.domain.BizLabDetection;
import com.ruoyi.web.modules.epidemic.mapper.BizLabDetectionMapper;
import com.ruoyi.web.modules.epidemic.support.LabDetectionQuarantineStationSupport;

/**
 * SYJC-UT-010～012、015
 */
@ExtendWith(MockitoExtension.class)
@DisplayName("BizLabDetectionServiceImpl")
class BizLabDetectionServiceImplTest
{

    @Mock
    private BizLabDetectionMapper labDetectionMapper;

    @Mock
    private LabDetectionQuarantineStationSupport quarantineStationSupport;

    @InjectMocks
    private BizLabDetectionServiceImpl service;

    private void stubNormalStation()
    {
        org.mockito.Mockito.doNothing().when(quarantineStationSupport)
                .validateQuarantineStationId(org.mockito.ArgumentMatchers.any());
    }

    @Test
    @DisplayName("SYJC-UT-010 新增忽略客户端检出率")
    void ut010_insertIgnoresClientRate()
    {
        stubNormalStation();
        when(labDetectionMapper.insertBizLabDetection(any())).thenReturn(1);
        BizLabDetection row = LabDetectionTestSamples.sampleWithRate(new BigDecimal("0.9900"));
        row.setTestQuantity(10);
        row.setPositiveCount(1);
        assertEquals(1, service.insertBizLabDetection(row));
        verify(labDetectionMapper).insertBizLabDetection(argThat(r ->
                r.getDetectionRate() != null
                        && r.getDetectionRate().compareTo(new BigDecimal("0.1000")) == 0));
    }

    @Test
    @DisplayName("SYJC-UT-011 修改重算检出率")
    void ut011_updateRecalcRate()
    {
        stubNormalStation();
        BizLabDetection db = LabDetectionTestSamples.sample();
        db.setId(1L);
        db.setTestQuantity(10);
        db.setPositiveCount(2);
        db.setDetectionRate(new BigDecimal("0.2000"));
        when(labDetectionMapper.selectBizLabDetectionById(1L)).thenReturn(db);
        when(labDetectionMapper.updateBizLabDetection(any())).thenReturn(1);
        BizLabDetection in = LabDetectionTestSamples.sample();
        in.setId(1L);
        in.setTestQuantity(20);
        in.setPositiveCount(4);
        assertEquals(1, service.updateBizLabDetection(in));
        verify(labDetectionMapper).updateBizLabDetection(argThat(r ->
                r.getDetectionRate().compareTo(new BigDecimal("0.2000")) == 0));
    }

    @Test
    @DisplayName("SYJC-UT-012 修改无状态限制")
    void ut012_updateSampleSource()
    {
        stubNormalStation();
        BizLabDetection db = LabDetectionTestSamples.sample();
        db.setId(1L);
        when(labDetectionMapper.selectBizLabDetectionById(1L)).thenReturn(db);
        when(labDetectionMapper.updateBizLabDetection(any())).thenReturn(1);
        BizLabDetection in = LabDetectionTestSamples.sample();
        in.setId(1L);
        in.setSampleSource(3);
        assertEquals(1, service.updateBizLabDetection(in));
        verify(labDetectionMapper).updateBizLabDetection(argThat(r -> r.getSampleSource() == 3));
    }

    @Test
    @DisplayName("SYJC-UT-015 删除无状态限制")
    void ut015_delete()
    {
        when(labDetectionMapper.deleteBizLabDetectionByIds(any())).thenReturn(1);
        assertEquals(1, service.deleteBizLabDetectionByIds(new Long[] { 9L }));
        verify(labDetectionMapper).deleteBizLabDetectionByIds(any());
    }

    @Test
    @DisplayName("修改记录不存在")
    void updateNotFound()
    {
        when(labDetectionMapper.selectBizLabDetectionById(99L)).thenReturn(null);
        BizLabDetection in = LabDetectionTestSamples.sample();
        in.setId(99L);
        assertThrows(ServiceException.class, () -> service.updateBizLabDetection(in));
        verify(labDetectionMapper, never()).updateBizLabDetection(any());
    }
}
