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

import java.math.BigDecimal;
import java.sql.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.BizGrassland;
import com.ruoyi.web.modules.industryservice.mapper.BizGrasslandMapper;
import com.ruoyi.web.modules.industryservice.support.GrasslandRules;

@ExtendWith(MockitoExtension.class)
@DisplayName("BizGrasslandServiceImpl")
class BizGrasslandServiceImplTest
{
    @Mock
    private BizGrasslandMapper mapper;

    @InjectMocks
    private BizGrasslandServiceImpl service;

    @Test
    @DisplayName("ZCZX-CCGL-UT-010 新增落库")
    void ut010_insert()
    {
        when(mapper.insertBizGrassland(any())).thenReturn(1);
        assertEquals(1, service.insertBizGrassland(sampleRow()));
        verify(mapper).insertBizGrassland(argThat(r -> GrasslandRules.DEL_FLAG_NORMAL.equals(r.getDelFlag())));
    }

    @Test
    @DisplayName("ZCZX-CCGL-UT-011 修改全字段")
    void ut011_update()
    {
        BizGrassland db = sampleRow();
        db.setId(2L);
        when(mapper.selectBizGrasslandById(2L)).thenReturn(db);
        when(mapper.updateBizGrassland(any())).thenReturn(1);
        BizGrassland in = sampleRow();
        in.setId(2L);
        in.setGrasslandName("新草场");
        in.setAreaMu(new BigDecimal("200"));
        assertEquals(1, service.updateBizGrassland(in));
        verify(mapper).updateBizGrassland(any());
    }

    @Test
    @DisplayName("ZCZX-CCGL-UT-012 利用类型互改")
    void ut012_utilizationTypeChange()
    {
        BizGrassland db = sampleRow();
        db.setId(3L);
        db.setUtilizationType(GrasslandRules.UTILIZATION_BAN);
        when(mapper.selectBizGrasslandById(3L)).thenReturn(db);
        when(mapper.updateBizGrassland(any())).thenReturn(1);
        BizGrassland in = sampleRow();
        in.setId(3L);
        in.setUtilizationType(GrasslandRules.UTILIZATION_YEAR_ROUND);
        assertEquals(1, service.updateBizGrassland(in));
        verify(mapper).updateBizGrassland(argThat(r -> r.getUtilizationType() == GrasslandRules.UTILIZATION_YEAR_ROUND));
    }

    @Test
    @DisplayName("ZCZX-CCGL-UT-013 修改不存在")
    void ut013_updateMissing()
    {
        when(mapper.selectBizGrasslandById(99L)).thenReturn(null);
        BizGrassland in = sampleRow();
        in.setId(99L);
        assertThrows(ServiceException.class, () -> service.updateBizGrassland(in));
        verify(mapper, never()).updateBizGrassland(any());
    }

    @Test
    @DisplayName("ZCZX-CCGL-UT-014 逻辑删除")
    void ut014_logicDelete()
    {
        when(mapper.logicDeleteBizGrasslandByIds(any(), eq("tester"))).thenReturn(1);
        assertEquals(1, service.deleteBizGrasslandByIds(new Long[] { 5L }, "tester"));
        verify(mapper).logicDeleteBizGrasslandByIds(any(), eq("tester"));
    }

    @Test
    @DisplayName("ZCZX-CCGL-UT-015 删除空 id 数组")
    void ut015_deleteEmpty()
    {
        assertEquals(0, service.deleteBizGrasslandByIds(new Long[] {}, "u"));
        assertEquals(0, service.deleteBizGrasslandByIds(null, "u"));
        verify(mapper, never()).logicDeleteBizGrasslandByIds(any(), any());
    }

    @Test
    @DisplayName("新增校验失败不落库")
    void insertValidationFails()
    {
        BizGrassland row = sampleRow();
        row.setGrasslandName("");
        assertThrows(ServiceException.class, () -> service.insertBizGrassland(row));
        verify(mapper, never()).insertBizGrassland(any());
    }

    private static BizGrassland sampleRow()
    {
        BizGrassland r = new BizGrassland();
        r.setGrasslandName("示范草场");
        r.setAreaMu(new BigDecimal("100.5"));
        r.setDegradationLevel(GrasslandRules.DEGRADATION_NONE);
        r.setUtilizationType(GrasslandRules.UTILIZATION_ROTATION);
        r.setGrassYieldPerMu(new BigDecimal("350"));
        r.setUtilizationRate(new BigDecimal("0.65"));
        r.setGrazingBanStartDate(Date.valueOf("2025-01-01"));
        r.setGrazingBanEndDate(Date.valueOf("2025-03-31"));
        r.setRotationPlotCount(4);
        r.setRotationGrazingDays(7);
        r.setRotationCycleDays(28);
        return r;
    }
}
