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

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.math.BigDecimal;
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.ArgumentCaptor;
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.BizYakWeighingRecord;
import com.ruoyi.web.modules.industryservice.domain.dto.OpenWeighingDto;
import com.ruoyi.web.modules.industryservice.mapper.BizFarmEnclosureMapper;
import com.ruoyi.web.modules.industryservice.mapper.BizPastureMapper;
import com.ruoyi.web.modules.industryservice.mapper.BizYakAssetMapper;
import com.ruoyi.web.modules.industryservice.mapper.BizYakWeighingRecordMapper;

@ExtendWith(MockitoExtension.class)
@DisplayName("YakWeighingSyncTxService")
class YakWeighingSyncTxServiceTest
{
    @Mock
    private BizYakWeighingRecordMapper weighingRecordMapper;

    @Mock
    private BizPastureMapper pastureMapper;

    @Mock
    private BizFarmEnclosureMapper enclosureMapper;

    @Mock
    private BizYakAssetMapper yakAssetMapper;

    @InjectMocks
    private YakWeighingSyncTxService service;

    @Test
    @DisplayName("新增称重记录")
    void persistWeighing_insert()
    {
        when(weighingRecordMapper.selectByExternalId(3001L)).thenReturn(null);
        when(weighingRecordMapper.insertBizYakWeighingRecord(any())).thenReturn(1);

        OpenWeighingDto dto = sampleDto();
        assertEquals(true, service.persistWeighing(dto, new Date()));

        ArgumentCaptor<BizYakWeighingRecord> captor = ArgumentCaptor.forClass(BizYakWeighingRecord.class);
        verify(weighingRecordMapper).insertBizYakWeighingRecord(captor.capture());
        BizYakWeighingRecord row = captor.getValue();
        assertEquals(3001L, row.getExternalId());
        assertEquals("YAK20250001", row.getEarTagNumber());
        assertEquals("YAK20250001", row.getYakNo());
        assertEquals(0, row.getWeightKg().compareTo(new BigDecimal("385.50")));
    }

    @Test
    @DisplayName("更新已有称重记录")
    void persistWeighing_update()
    {
        BizYakWeighingRecord existing = new BizYakWeighingRecord();
        existing.setId(10L);
        existing.setCreateTime(new Date(1_000L));
        when(weighingRecordMapper.selectByExternalId(3001L)).thenReturn(existing);

        assertFalse(service.persistWeighing(sampleDto(), new Date()));
        verify(weighingRecordMapper).updateBizYakWeighingRecordFromSync(any());
    }

    @Test
    @DisplayName("缺少 external id 拒绝")
    void persistWeighing_missingId()
    {
        OpenWeighingDto dto = sampleDto();
        dto.setId(null);
        assertThrows(ServiceException.class, () -> service.persistWeighing(dto, new Date()));
    }

    private static OpenWeighingDto sampleDto()
    {
        OpenWeighingDto dto = new OpenWeighingDto();
        dto.setId(3001L);
        dto.setCattleId(4001L);
        dto.setCattleNo("YAK20250001");
        dto.setEarTagNumber("YAK20250001");
        dto.setWeight("385.50");
        dto.setWeighingTime("2026-05-20 08:30:00");
        return dto;
    }
}
