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

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import com.ruoyi.web.modules.industryservice.domain.dto.BreedingIndustryYakSnapshot;
import com.ruoyi.web.modules.industryservice.support.BreedingIndustryRules;
import com.ruoyi.web.modules.screen.domain.dto.HomeScreenAppointmentStatDto;
import com.ruoyi.web.modules.screen.domain.dto.HomeScreenMonthCountDto;
import com.ruoyi.web.modules.screen.domain.vo.HomeScreenAgriClassroomVo;
import com.ruoyi.web.modules.screen.domain.vo.HomeScreenAppointmentVo;
import com.ruoyi.web.modules.screen.domain.vo.HomeScreenInventoryMonthVo;
import com.ruoyi.web.modules.screen.domain.vo.HomeScreenOutboundMonthVo;
import com.ruoyi.web.modules.screen.domain.vo.HomeScreenSubsidyVo;
import com.ruoyi.web.modules.screen.domain.vo.HomeScreenTrainingTrendVo;

/**
 * DP-SY-UT-003～018
 */
@DisplayName("HomeScreenSupport")
class HomeScreenSupportTest
{

    @Test
    @DisplayName("DP-SY-UT-004 历史年 statDate 为 12-31")
    void ut004_historicalStatDate()
    {
        assertEquals(LocalDate.of(2024, 12, 31), HomeScreenSupport.resolveStatDate(2024));
    }

    @Test
    @DisplayName("DP-SY-UT-005 公母牛趋势 12 月补零")
    void ut005_bullCowMonthlyTwelve()
    {
        BreedingIndustryYakSnapshot bull = yak(1L, BreedingIndustryRules.ASSET_STATUS_NORMAL, "公", null);
        List<HomeScreenInventoryMonthVo> trend = HomeScreenSupport.buildBullCowMonthlyTrend(
                Collections.singletonList(bull), LocalDate.of(2024, 12, 31));
        assertEquals(12, trend.size());
        assertTrue(trend.get(11).getBullCount() >= 1);
    }

    @Test
    @DisplayName("DP-SY-UT-007 出栏按月缺月补零")
    void ut007_outboundMonthly()
    {
        HomeScreenMonthCountDto m3 = monthCount(3, 1);
        HomeScreenMonthCountDto m8 = monthCount(8, 2);
        List<HomeScreenOutboundMonthVo> list = HomeScreenSupport.buildOutboundMonthly(
                Arrays.asList(m3, m8), LocalDate.of(2024, 12, 31));
        assertEquals(12, list.size());
        assertEquals(1, list.get(2).getOutboundCount());
        assertEquals(0, list.get(0).getOutboundCount());
    }

    @Test
    @DisplayName("DP-SY-UT-011 预约排除拒绝取消")
    void ut011_appointmentAnnualMapping()
    {
        HomeScreenAppointmentStatDto vet = appt(null, 1, 2);
        HomeScreenAppointmentStatDto expert = appt(null, 3, 1);
        HomeScreenAppointmentVo vo = HomeScreenSupport.buildAppointment(
                Arrays.asList(vet, expert), Collections.emptyList(), LocalDate.of(2026, 5, 20));
        assertEquals(2, vo.getAnnualVetCount());
        assertEquals(1, vo.getAnnualExpertCount());
        assertEquals(12, vo.getMonthlyStacked().size());
    }

    @Test
    @DisplayName("DP-SY-UT-013 补贴万元换算")
    void ut013_subsidyWan()
    {
        assertEquals(new BigDecimal("1.00"), HomeScreenSupport.toAmountWan(new BigDecimal("10000")));
    }

    @Test
    @DisplayName("DP-SY-UT-014 无补贴 hasSubsidyData=false")
    void ut014_noSubsidy()
    {
        HomeScreenSubsidyVo vo = HomeScreenSupport.buildSubsidy(Collections.emptyList(), false);
        assertFalse(vo.isHasSubsidyData());
        assertEquals(3, vo.getTypeStats().size());
        assertEquals(new BigDecimal("0.00"), vo.getTypeStats().get(0).getAmountWan());
    }

    @Test
    @DisplayName("DP-SY-UT-015 农技课堂合计")
    void ut015_agriTotal()
    {
        HomeScreenAgriClassroomVo vo = HomeScreenSupport.buildAgriClassroom(2, 1);
        assertEquals(3, vo.getTrainingContentTotal());
        assertTrue(vo.isHasAgriData());
    }

    @Test
    @DisplayName("DP-SY-UT-016 农技双零")
    void ut016_agriEmpty()
    {
        HomeScreenAgriClassroomVo vo = HomeScreenSupport.buildAgriClassroom(0, 0);
        assertFalse(vo.isHasAgriData());
    }

    @Test
    @DisplayName("DP-SY-UT-018 无培训空态")
    void ut018_noTraining()
    {
        HomeScreenTrainingTrendVo vo = HomeScreenSupport.buildTrainingTrend(
                Collections.emptyList(), false, LocalDate.of(2026, 5, 20));
        assertFalse(vo.isHasTrainingData());
        assertEquals(12, vo.getMonthly().size());
    }

    @Test
    @DisplayName("DP-SY-UT-019 标准分类解析")
    void ut019_categoryParse()
    {
        assertEquals(HomeScreenStandardCategory.FEEDING, HomeScreenStandardCategory.parse("FEEDING"));
    }

    private static BreedingIndustryYakSnapshot yak(Long pastureId, int status, String gender, Integer ageMonths)
    {
        BreedingIndustryYakSnapshot s = new BreedingIndustryYakSnapshot();
        s.setPastureId(pastureId);
        s.setAssetStatus(status);
        s.setGender(gender);
        s.setAgeMonths(ageMonths);
        return s;
    }

    private static HomeScreenMonthCountDto monthCount(int month, int count)
    {
        HomeScreenMonthCountDto dto = new HomeScreenMonthCountDto();
        dto.setMonth(month);
        dto.setCount(count);
        return dto;
    }

    private static HomeScreenAppointmentStatDto appt(Integer month, int providerType, int count)
    {
        HomeScreenAppointmentStatDto dto = new HomeScreenAppointmentStatDto();
        dto.setMonth(month);
        dto.setProviderType(providerType);
        dto.setCount(count);
        return dto;
    }

}
