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.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.core.domain.entity.SysDept;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.web.modules.industryservice.domain.BizYakHerdInventory;
import com.ruoyi.web.modules.industryservice.mapper.BizYakHerdInventoryMapper;
import com.ruoyi.web.modules.industryservice.support.TownDeptSupport;
import com.ruoyi.web.modules.industryservice.support.YakHerdInventoryYearSupport;

@ExtendWith(MockitoExtension.class)
@org.mockito.junit.jupiter.MockitoSettings(strictness = org.mockito.quality.Strictness.LENIENT)
@DisplayName("BizYakHerdInventoryServiceImpl")
class BizYakHerdInventoryServiceImplTest
{
    @Mock
    private BizYakHerdInventoryMapper mapper;

    @Mock
    private TownDeptSupport townDeptSupport;

    @InjectMocks
    private BizYakHerdInventoryServiceImpl service;

    @Test
    @DisplayName("ZCZX-MYCLTB-UT-003 缺年份")
    void ut003_missingYear()
    {
        BizYakHerdInventory row = sampleRow();
        row.setStatYear(null);
        assertThrows(ServiceException.class, () -> service.insertBizYakHerdInventory(row));
    }

    @Test
    @DisplayName("ZCZX-MYCLTB-UT-004 负数拒绝")
    void ut004_negativeYakTotal()
    {
        BizYakHerdInventory row = sampleRow();
        row.setYakTotal(-1);
        mockTown();
        assertThrows(ServiceException.class, () -> service.insertBizYakHerdInventory(row));
    }

    @Test
    @DisplayName("ZCZX-MYCLTB-UT-005 同年同月同乡镇重复")
    void ut005_duplicateYearMonthTown()
    {
        mockTown();
        when(mapper.countByYearMonthAndTownExcludeId(2026, 5, 101L, null)).thenReturn(1);
        assertThrows(ServiceException.class, () -> service.insertBizYakHerdInventory(sampleRow()));
        verify(mapper, never()).insertBizYakHerdInventory(any());
    }

    @Test
    @DisplayName("ZCZX-MYCLTB-UT-006 新增成功")
    void ut006_insertSuccess()
    {
        mockTown();
        when(mapper.countByYearMonthAndTownExcludeId(2026, 5, 101L, null)).thenReturn(0);
        when(mapper.insertBizYakHerdInventory(any())).thenReturn(1);
        assertEquals(1, service.insertBizYakHerdInventory(sampleRow()));
        verify(mapper).insertBizYakHerdInventory(any());
    }

    @Test
    @DisplayName("ZCZX-MYCLTB-UT-013 修改不存在")
    void ut013_updateMissing()
    {
        when(mapper.selectBizYakHerdInventoryById(99L)).thenReturn(null);
        BizYakHerdInventory row = sampleRow();
        row.setId(99L);
        assertThrows(ServiceException.class, () -> service.updateBizYakHerdInventory(row));
    }

    @Test
    @DisplayName("ZCZX-MYCLTB-UT-014 物理删除")
    void ut014_delete()
    {
        when(mapper.deleteBizYakHerdInventoryByIds(any())).thenReturn(1);
        assertEquals(1, service.deleteBizYakHerdInventoryByIds(new Long[] { 1L }, "tester"));
        verify(mapper).deleteBizYakHerdInventoryByIds(any());
    }

    @Test
    @DisplayName("ZCZX-MYCLTB-UT-016 village_dept_id 可空")
    void ut016_villageDeptOptional()
    {
        mockTown();
        when(mapper.countByYearMonthAndTownExcludeId(2026, 5, 101L, null)).thenReturn(0);
        when(mapper.insertBizYakHerdInventory(any())).thenReturn(1);
        BizYakHerdInventory row = sampleRow();
        row.setVillageDeptId(null);
        assertEquals(1, service.insertBizYakHerdInventory(row));
    }

    @Test
    @DisplayName("年份选项 6 个")
    void ut001_yearOptions()
    {
        assertEquals(6, YakHerdInventoryYearSupport.resolveYearOptions(2026).size());
        assertEquals(2021, YakHerdInventoryYearSupport.resolveYearOptions(2026).get(5).intValue());
    }

    private void mockTown()
    {
        SysDept town = new SysDept();
        town.setDeptId(101L);
        town.setDeptName("巴青乡");
        town.setOrderNum(13);
        town.setDelFlag("0");
        when(townDeptSupport.requireReportTown(101L)).thenReturn(town);
        when(townDeptSupport.listReportTowns()).thenReturn(Collections.singletonList(town));
    }

    private static BizYakHerdInventory sampleRow()
    {
        BizYakHerdInventory row = new BizYakHerdInventory();
        row.setStatYear(2026);
        row.setStatMonth(5);
        row.setTownDeptId(101L);
        row.setTownName("巴青乡");
        row.setYakTotal(100);
        return row;
    }
}
