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

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.sql.Date;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.web.modules.industryservice.domain.BizGrasslandUsageRecord;

/**
 * ZCZX-CCSYJL-UT-001～009、016
 */
@DisplayName("GrasslandUsageValidation")
class GrasslandUsageValidationTest
{
    @Test
    @DisplayName("ZCZX-CCSYJL-UT-001 使用面积")
    void ut001_usageArea()
    {
        BigDecimal total = new BigDecimal("100");
        assertDoesNotThrow(() -> GrasslandUsageValidation.validateUsageAreaMu(new BigDecimal("50"), total));
        assertThrows(ServiceException.class, () -> GrasslandUsageValidation.validateUsageAreaMu(BigDecimal.ZERO, total));
        assertThrows(ServiceException.class, () -> GrasslandUsageValidation.validateUsageAreaMu(new BigDecimal("101"), total));
        assertThrows(ServiceException.class, () -> GrasslandUsageValidation.validateUsageAreaMu(null, total));
    }

    @Test
    @DisplayName("ZCZX-CCSYJL-UT-002 使用日期区间")
    void ut002_useDates()
    {
        Date start = Date.valueOf("2025-06-01");
        Date end = Date.valueOf("2025-06-03");
        assertDoesNotThrow(() -> GrasslandUsageValidation.validateUseDates(start, end));
        assertDoesNotThrow(() -> GrasslandUsageValidation.validateUseDates(Date.valueOf("2025-06-01"), Date.valueOf("2025-06-01")));
        assertThrows(ServiceException.class,
                () -> GrasslandUsageValidation.validateUseDates(Date.valueOf("2025-06-04"), end));
        assertThrows(ServiceException.class, () -> GrasslandUsageValidation.validateUseDates(start, null));
    }

    @Test
    @DisplayName("ZCZX-CCSYJL-UT-003 实际使用天数")
    void ut003_actualUseDays()
    {
        assertEquals(1, GrasslandUsageValidation.resolveActualUseDays(
                Date.valueOf("2025-06-01"), Date.valueOf("2025-06-01")));
        assertEquals(3, GrasslandUsageValidation.resolveActualUseDays(
                Date.valueOf("2025-06-01"), Date.valueOf("2025-06-03")));
    }

    @Test
    @DisplayName("ZCZX-CCSYJL-UT-004 放牧数量")
    void ut004_grazingHeadCount()
    {
        assertDoesNotThrow(() -> GrasslandUsageValidation.validateGrazingHeadCount(1));
        assertDoesNotThrow(() -> GrasslandUsageValidation.validateGrazingHeadCount(100));
        assertThrows(ServiceException.class, () -> GrasslandUsageValidation.validateGrazingHeadCount(0));
        assertThrows(ServiceException.class, () -> GrasslandUsageValidation.validateGrazingHeadCount(-1));
    }

    @Test
    @DisplayName("ZCZX-CCSYJL-UT-005 放牧方式枚举")
    void ut005_grazingMethod()
    {
        assertDoesNotThrow(() -> GrasslandUsageValidation.validateGrazingMethod(GrasslandUsageRules.GRAZING_ROTATION));
        assertDoesNotThrow(() -> GrasslandUsageValidation.validateGrazingMethod(GrasslandUsageRules.GRAZING_SEASONAL));
        assertThrows(ServiceException.class, () -> GrasslandUsageValidation.validateGrazingMethod(0));
        assertThrows(ServiceException.class, () -> GrasslandUsageValidation.validateGrazingMethod(4));
        assertThrows(ServiceException.class, () -> GrasslandUsageValidation.validateGrazingMethod(null));
    }

    @Test
    @DisplayName("ZCZX-CCSYJL-UT-006 主数据 id")
    void ut006_masterIds()
    {
        assertThrows(ServiceException.class, () -> GrasslandUsageValidation.validateGrasslandId(null));
        assertThrows(ServiceException.class, () -> GrasslandUsageValidation.validatePastureId(null));
    }

    @Test
    @DisplayName("ZCZX-CCSYJL-UT-007 列表创建日期区间")
    void ut007_listDateRange()
    {
        assertThrows(ServiceException.class,
                () -> GrasslandUsageValidation.validateDateRangeForList("2025-12-01", "2025-01-01"));
        assertDoesNotThrow(() -> GrasslandUsageValidation.validateDateRangeForList("2025-01-01", "2025-06-30"));
        assertDoesNotThrow(() -> GrasslandUsageValidation.validateDateRangeForList("2025-01-01", null));
        assertDoesNotThrow(() -> GrasslandUsageValidation.validateDateRangeForList(null, "2025-06-30"));
    }

    @Test
    @DisplayName("ZCZX-CCSYJL-UT-008 全量保存校验")
    void ut008_validateRowForSave()
    {
        BizGrasslandUsageRecord row = sampleRow();
        assertDoesNotThrow(() -> GrasslandUsageValidation.validateRowForSave(row, new BigDecimal("100")));
        assertEquals(3, row.getActualUseDays());
    }

    @Test
    @DisplayName("ZCZX-CCSYJL-UT-016 JOIN 与删除过滤 SQL")
    void ut016_mapperXml() throws Exception
    {
        String path = "src/main/resources/mapper/industryservice/BizGrasslandUsageRecordMapper.xml";
        String xml = new String(Files.readAllBytes(Paths.get(path)), StandardCharsets.UTF_8);
        assertTrue(xml.contains("biz_grassland"));
        assertTrue(xml.contains("biz_pasture"));
        assertTrue(xml.contains("r.create_time desc"));
        assertTrue(xml.contains("r.del_flag = '0'"));
        assertTrue(xml.contains("del_flag = '2'"));
    }

    private static BizGrasslandUsageRecord sampleRow()
    {
        BizGrasslandUsageRecord r = new BizGrasslandUsageRecord();
        r.setGrasslandId(1L);
        r.setPastureId(2L);
        r.setUsageAreaMu(new BigDecimal("50"));
        r.setUseStartDate(Date.valueOf("2025-06-01"));
        r.setUseEndDate(Date.valueOf("2025-06-03"));
        r.setGrazingHeadCount(100);
        r.setGrazingMethod(GrasslandUsageRules.GRAZING_ROTATION);
        return r;
    }
}
