package com.ruoyi.web.modules.screen.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.common.core.domain.TreeSelect;
import com.ruoyi.web.modules.industryservice.domain.BizCooperativeDevelopment;
import com.ruoyi.web.modules.industryservice.domain.BizDisposableIncome;
import com.ruoyi.web.modules.industryservice.domain.BizFamilyRanch;
import com.ruoyi.web.modules.industryservice.domain.BizFarmerHousehold;
import com.ruoyi.web.modules.industryservice.domain.BizGrassLivestockImbalanceWarning;
import com.ruoyi.web.modules.industryservice.domain.BizLargeLivestockFarmer;
import com.ruoyi.web.modules.industryservice.domain.BizLivestockOwnershipHousehold;
import com.ruoyi.web.modules.industryservice.domain.BizYakHerdInventory;
import com.ruoyi.web.modules.industryservice.domain.BizYakOutboundReport;
import com.ruoyi.web.modules.industryservice.mapper.BizCooperativeDevelopmentMapper;
import com.ruoyi.web.modules.industryservice.mapper.BizDisposableIncomeMapper;
import com.ruoyi.web.modules.industryservice.mapper.BizFamilyRanchMapper;
import com.ruoyi.web.modules.industryservice.mapper.BizFarmerHouseholdMapper;
import com.ruoyi.web.modules.industryservice.mapper.BizGrassLivestockImbalanceWarningMapper;
import com.ruoyi.web.modules.industryservice.mapper.BizLargeLivestockFarmerMapper;
import com.ruoyi.web.modules.industryservice.mapper.BizLivestockOwnershipHouseholdMapper;
import com.ruoyi.web.modules.industryservice.mapper.BizYakHerdInventoryMapper;
import com.ruoyi.web.modules.industryservice.mapper.BizYakOutboundReportMapper;
import com.ruoyi.web.modules.industryservice.support.BreedingIndustryRules;
import com.ruoyi.web.modules.industryservice.support.TownDeptSupport;
import com.ruoyi.web.modules.prosperity.support.AchievementReportValidation;
import com.ruoyi.web.modules.screen.domain.dto.HomeScreenStatPeriodDto;
import com.ruoyi.web.modules.screen.domain.vo.HomeScreenCooperativeDevelopmentListItemVo;
import com.ruoyi.web.modules.screen.domain.vo.HomeScreenDashboardVo;
import com.ruoyi.web.modules.screen.domain.vo.HomeScreenFamilyRanchListItemVo;
import com.ruoyi.web.modules.screen.domain.vo.HomeScreenFarmerHouseholdListItemVo;
import com.ruoyi.web.modules.screen.domain.vo.HomeScreenImbalanceWarningListItemVo;
import com.ruoyi.web.modules.screen.domain.vo.HomeScreenIndustryOverviewVo;
import com.ruoyi.web.modules.screen.domain.vo.HomeScreenLargeLivestockFarmerListItemVo;
import com.ruoyi.web.modules.screen.domain.vo.HomeScreenLivestockOwnershipHouseholdListItemVo;
import com.ruoyi.web.modules.screen.domain.vo.HomeScreenPerCapitaIncomeListItemVo;
import com.ruoyi.web.modules.screen.domain.vo.HomeScreenStandardListItemVo;
import com.ruoyi.web.modules.screen.domain.vo.HomeScreenTownMapMarkerVo;
import com.ruoyi.web.modules.screen.domain.vo.HomeScreenTownMapVo;
import com.ruoyi.web.modules.screen.domain.vo.HomeScreenTownSubsidyItemVo;
import com.ruoyi.web.modules.screen.domain.vo.HomeScreenYakHerdInventoryListItemVo;
import com.ruoyi.web.modules.screen.domain.vo.HomeScreenBreedingEntityQuantityListItemVo;
import com.ruoyi.web.modules.screen.domain.vo.HomeScreenYakInventoryOutboundListItemVo;
import com.ruoyi.web.modules.screen.domain.vo.HomeScreenYakOutboundReportListItemVo;
import com.ruoyi.web.modules.screen.mapper.HomeScreenStandardMapper;
import com.ruoyi.web.modules.screen.mapper.HomeScreenStatsMapper;
import com.ruoyi.web.modules.screen.service.IHomeScreenService;
import com.ruoyi.web.modules.screen.support.HomeScreenStandardCategory;
import com.ruoyi.web.modules.screen.support.HomeScreenSupport;

/**
 * 大屏首页统计服务实现。
 * <p>
 * 产业总览填报类指标取所选年<strong>最大填报月</strong>合计或记录数。
 * 看板已屏蔽：惠农补贴、草场类型占比、牦牛出栏月度、牦牛存栏变动、供应商/承销商/市场、草场块数。
 * </p>
 */
@Service
public class HomeScreenServiceImpl implements IHomeScreenService
{
    @Autowired
    private HomeScreenStatsMapper homeScreenStatsMapper;

    @Autowired
    private HomeScreenStandardMapper homeScreenStandardMapper;

    @Autowired
    private BizGrassLivestockImbalanceWarningMapper grassLivestockImbalanceWarningMapper;

    @Autowired
    private BizDisposableIncomeMapper bizDisposableIncomeMapper;

    @Autowired
    private BizFarmerHouseholdMapper bizFarmerHouseholdMapper;

    @Autowired
    private BizCooperativeDevelopmentMapper bizCooperativeDevelopmentMapper;

    @Autowired
    private BizFamilyRanchMapper bizFamilyRanchMapper;

    @Autowired
    private BizLargeLivestockFarmerMapper bizLargeLivestockFarmerMapper;

    @Autowired
    private BizYakOutboundReportMapper bizYakOutboundReportMapper;

    @Autowired
    private BizYakHerdInventoryMapper bizYakHerdInventoryMapper;

    @Autowired
    private BizLivestockOwnershipHouseholdMapper bizLivestockOwnershipHouseholdMapper;

    @Autowired
    private TownDeptSupport townDeptSupport;

    @Override
    public HomeScreenDashboardVo loadDashboard(String statYear)
    {
        int year = AchievementReportValidation.parseStatYear(statYear);
        LocalDate statDate = HomeScreenSupport.resolveStatDate(year);

        HomeScreenDashboardVo vo = new HomeScreenDashboardVo();
        vo.setStatYear(year);
        vo.setStatDate(HomeScreenSupport.formatStatDate(statDate));

        // 产业总览填报类：所选年份内最大填报月，全县（各村）合计/计数
        HomeScreenIndustryOverviewVo overview = new HomeScreenIndustryOverviewVo();
        HomeScreenStatPeriodDto yearHerd = homeScreenStatsMapper.selectLatestHerdInventoryStatPeriodByYear(year);
        HomeScreenStatPeriodDto yearOutbound = homeScreenStatsMapper.selectLatestOutboundReportStatPeriodByYear(year);
        HomeScreenStatPeriodDto yearFarmerHousehold =
                homeScreenStatsMapper.selectLatestFarmerHouseholdStatPeriodByYear(year);
        HomeScreenStatPeriodDto yearCooperative =
                homeScreenStatsMapper.selectLatestCooperativeDevelopmentStatPeriodByYear(year);
        HomeScreenStatPeriodDto yearFamilyRanch =
                homeScreenStatsMapper.selectLatestFamilyRanchStatPeriodByYear(year);
        HomeScreenStatPeriodDto yearLargeFarmer =
                homeScreenStatsMapper.selectLatestLargeLivestockFarmerStatPeriodByYear(year);
        HomeScreenStatPeriodDto yearOwnership =
                homeScreenStatsMapper.selectLatestLivestockOwnershipHouseholdStatPeriodByYear(year);
        overview.setInventoryTotal(sumHerdYakAtPeriod(yearHerd));
        overview.setAnnualOutbound(sumOutboundYakAtPeriod(yearOutbound));
        overview.setPastureCount(sumFarmerHouseholdAtPeriod(yearFarmerHousehold));
        overview.setGrasslandAreaMu(sumFarmerHouseholdPastureAreaAtPeriod(yearFarmerHousehold));
        overview.setCooperativeCount(countAtPeriod(yearCooperative,
                homeScreenStatsMapper::countCooperativeDevelopmentByStatYearMonth));
        overview.setFamilyRanchCount(countAtPeriod(yearFamilyRanch,
                homeScreenStatsMapper::countFamilyRanchByStatYearMonth));
        overview.setLargeLivestockFarmerCount(countAtPeriod(yearLargeFarmer,
                homeScreenStatsMapper::countLargeLivestockFarmerByStatYearMonth));
        overview.setWithLivestockHouseholdCount(countAtPeriod(yearOwnership,
                homeScreenStatsMapper::sumWithLivestockHouseholdCountByStatYearMonth));

        // 牲畜出栏 / 自食：所选年出栏表最大填报月
        if (yearOutbound == null)
        {
            vo.setLivestockOutboundStructure(HomeScreenSupport.buildLivestockOutboundStructure(null));
            vo.setSelfConsumption(HomeScreenSupport.buildSelfConsumption(null, null));
        }
        else
        {
            int outYear = yearOutbound.getStatYear();
            int outMonth = yearOutbound.getStatMonth();
            vo.setLivestockOutboundStructure(HomeScreenSupport.buildLivestockOutboundStructure(
                    homeScreenStatsMapper.sumOutboundReportSpeciesByStatYearMonth(outYear, outMonth)));
            vo.setSelfConsumption(HomeScreenSupport.buildSelfConsumption(
                    yearOutbound,
                    homeScreenStatsMapper.sumOutboundReportSelfConsumptionByStatYearMonth(outYear, outMonth)));
        }
        // 畜群存栏结构 / 牦牛存栏结构 / 年龄结构：所选年库中最大填报月
        if (yearHerd == null)
        {
            vo.setHerdInventoryStructure(HomeScreenSupport.buildHerdInventoryStructure(null));
            vo.setYakInventoryStructure(HomeScreenSupport.buildYakInventoryStructure(null));
            vo.setAgeStructure(HomeScreenSupport.buildCowAgeStructureFromHerdReport(null));
        }
        else
        {
            int herdYear = yearHerd.getStatYear();
            int herdMonth = yearHerd.getStatMonth();
            vo.setHerdInventoryStructure(HomeScreenSupport.buildHerdInventoryStructure(
                    homeScreenStatsMapper.sumHerdInventorySpeciesByStatYearMonth(herdYear, herdMonth)));
            vo.setYakInventoryStructure(HomeScreenSupport.buildYakInventoryStructure(
                    homeScreenStatsMapper.sumHerdInventoryYakStructureByStatYearMonth(herdYear, herdMonth)));
            vo.setAgeStructure(HomeScreenSupport.buildCowAgeStructureFromHerdReport(
                    homeScreenStatsMapper.sumHerdInventoryCowAgeByStatYearMonth(herdYear, herdMonth)));
        }
        // 企业年度收入与补助：家庭牧场 / 养殖大户，所选年最大填报月各项合计（万元）
        if (yearFamilyRanch == null)
        {
            vo.setFamilyRanchFinance(HomeScreenSupport.buildEnterpriseFinance(null, null));
        }
        else
        {
            vo.setFamilyRanchFinance(HomeScreenSupport.buildEnterpriseFinance(
                    yearFamilyRanch,
                    homeScreenStatsMapper.sumFamilyRanchFinanceByStatYearMonth(
                            yearFamilyRanch.getStatYear(), yearFamilyRanch.getStatMonth())));
        }
        if (yearLargeFarmer == null)
        {
            vo.setLargeLivestockFarmerFinance(HomeScreenSupport.buildEnterpriseFinance(null, null));
        }
        else
        {
            vo.setLargeLivestockFarmerFinance(HomeScreenSupport.buildEnterpriseFinance(
                    yearLargeFarmer,
                    homeScreenStatsMapper.sumLargeLivestockFarmerFinanceByStatYearMonth(
                            yearLargeFarmer.getStatYear(), yearLargeFarmer.getStatMonth())));
        }
        // 合作社经营模式：所选年最大填报月
        if (yearCooperative == null)
        {
            vo.setCooperativeBusinessModel(HomeScreenSupport.buildCooperativeBusinessModel(null));
        }
        else
        {
            vo.setCooperativeBusinessModel(HomeScreenSupport.buildCooperativeBusinessModel(
                    homeScreenStatsMapper.countCooperativeBusinessModelByStatYearMonth(
                            yearCooperative.getStatYear(), yearCooperative.getStatMonth())));
        }
        // 农牧户分类（本期不展示，改回乡镇补助合计）
        // if (yearFarmerHousehold == null)
        // {
        //     vo.setFarmerHouseholdClassification(HomeScreenSupport.buildFarmerHouseholdClassification(null));
        // }
        // else
        // {
        //     vo.setFarmerHouseholdClassification(HomeScreenSupport.buildFarmerHouseholdClassification(
        //             homeScreenStatsMapper.countFarmerHouseholdClassByStatYearMonth(
        //                     yearFarmerHousehold.getStatYear(), yearFarmerHousehold.getStatMonth())));
        // }
        // 各乡镇补助合计：所选年农牧户最大填报月，按乡镇汇总各村 subsidy_total
        if (yearFarmerHousehold == null)
        {
            vo.setTownSubsidyTotals(Collections.emptyList());
        }
        else
        {
            List<HomeScreenTownSubsidyItemVo> townSubsidies =
                    homeScreenStatsMapper.sumFarmerHouseholdSubsidyTotalByTownStatYearMonth(
                            yearFarmerHousehold.getStatYear(), yearFarmerHousehold.getStatMonth());
            vo.setTownSubsidyTotals(townSubsidies != null ? townSubsidies : Collections.emptyList());
        }
        // 人均收入：以库中最大所属年为终点，向前共 5 年（与所选年无关）
        Integer incomeEndYear = homeScreenStatsMapper.selectLatestDisposableIncomeStatYear();
        if (incomeEndYear == null)
        {
            vo.setPerCapitaIncomeTrend(Collections.emptyList());
        }
        else
        {
            int incomeStartYear = incomeEndYear - 4;
            vo.setPerCapitaIncomeTrend(HomeScreenSupport.buildPerCapitaIncomeTrend(
                    homeScreenStatsMapper.selectDisposableIncomeByYearRange(incomeStartYear, incomeEndYear),
                    incomeEndYear));
        }

        vo.setIndustryOverview(overview);
        vo.setAvailableYears(HomeScreenSupport.buildAvailableYears(
                homeScreenStatsMapper.selectDistinctOutboundYears(),
                homeScreenStatsMapper.selectDistinctAppointmentYears(),
                homeScreenStatsMapper.selectDistinctSubsidyYears(),
                homeScreenStatsMapper.selectDistinctStandardCreateYears(),
                homeScreenStatsMapper.selectDistinctTechPublishYears(),
                homeScreenStatsMapper.selectDistinctTrainingYears()));
        return vo;
    }

    private int sumHerdYakAtPeriod(HomeScreenStatPeriodDto period)
    {
        if (period == null || period.getStatYear() == null || period.getStatMonth() == null)
        {
            return 0;
        }
        return homeScreenStatsMapper.sumHerdInventoryYakTotalByStatYearMonth(
                period.getStatYear(), period.getStatMonth());
    }

    private int sumOutboundYakAtPeriod(HomeScreenStatPeriodDto period)
    {
        if (period == null || period.getStatYear() == null || period.getStatMonth() == null)
        {
            return 0;
        }
        return homeScreenStatsMapper.sumOutboundReportYakCountByStatYearMonth(
                period.getStatYear(), period.getStatMonth());
    }

    private int sumFarmerHouseholdAtPeriod(HomeScreenStatPeriodDto period)
    {
        if (period == null || period.getStatYear() == null || period.getStatMonth() == null)
        {
            return 0;
        }
        return homeScreenStatsMapper.sumFarmerHouseholdCountByStatYearMonth(
                period.getStatYear(), period.getStatMonth());
    }

    private BigDecimal sumFarmerHouseholdPastureAreaAtPeriod(HomeScreenStatPeriodDto period)
    {
        if (period == null || period.getStatYear() == null || period.getStatMonth() == null)
        {
            return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
        }
        BigDecimal area = homeScreenStatsMapper.sumFarmerHouseholdPastureContractAreaByStatYearMonth(
                period.getStatYear(), period.getStatMonth());
        return area != null ? area.setScale(2, RoundingMode.HALF_UP) : BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
    }

    @FunctionalInterface
    private interface YearMonthCountQuery
    {
        int apply(int statYear, int statMonth);
    }

    private int countAtPeriod(HomeScreenStatPeriodDto period, YearMonthCountQuery query)
    {
        if (period == null || period.getStatYear() == null || period.getStatMonth() == null)
        {
            return 0;
        }
        return query.apply(period.getStatYear(), period.getStatMonth());
    }

    /** 按 Tab 分类查询当年已发布养殖标准，并补全字典显示名。 */
    @Override
    public List<HomeScreenStandardListItemVo> listStandards(String statYear, String category)
    {
        int year = AchievementReportValidation.parseStatYear(statYear);
        HomeScreenStandardCategory cat = HomeScreenStandardCategory.parse(category);
        Date yearStart = toDate(LocalDate.of(year, 1, 1));
        Date yearEnd = toDateEndOfDay(LocalDate.of(year, 12, 31));
        List<HomeScreenStandardListItemVo> rows = Collections.emptyList();
        switch (cat)
        {
            case FEEDING:
                rows = homeScreenStandardMapper.selectFeedingForScreen(yearStart, yearEnd);
                break;
            case EQUIPMENT:
                rows = homeScreenStandardMapper.selectEquipmentForScreen(yearStart, yearEnd);
                break;
            case TREATMENT:
                rows = homeScreenStandardMapper.selectTreatmentForScreen(yearStart, yearEnd);
                break;
            case GROWTH:
                rows = homeScreenStandardMapper.selectGrowthForScreen(yearStart, yearEnd);
                break;
            case BREEDING_MGMT:
                rows = homeScreenStandardMapper.selectBreedingMgmtForScreen(yearStart, yearEnd);
                break;
        }
        if (rows == null)
        {
            rows = Collections.emptyList();
        }
        HomeScreenSupport.enrichStandardTypeNames(rows);
        return rows;
    }

    @Override
    public HomeScreenTownMapVo loadTownMapMarkers(String statYear)
    {
        int year = AchievementReportValidation.parseStatYear(statYear);
        HomeScreenStatPeriodDto yearHerd = homeScreenStatsMapper.selectLatestHerdInventoryStatPeriodByYear(year);
        HomeScreenStatPeriodDto yearOutbound = homeScreenStatsMapper.selectLatestOutboundReportStatPeriodByYear(year);

        List<HomeScreenTownMapMarkerVo> markers = homeScreenStatsMapper.selectTownMapMarkers(
                yearHerd != null ? yearHerd.getStatYear() : null,
                yearHerd != null ? yearHerd.getStatMonth() : null,
                yearOutbound != null ? yearOutbound.getStatYear() : null,
                yearOutbound != null ? yearOutbound.getStatMonth() : null);
        HomeScreenTownMapVo vo = new HomeScreenTownMapVo();
        vo.setHerdStatYear(yearHerd != null ? yearHerd.getStatYear() : null);
        vo.setHerdStatMonth(yearHerd != null ? yearHerd.getStatMonth() : null);
        vo.setOutboundStatYear(yearOutbound != null ? yearOutbound.getStatYear() : null);
        vo.setOutboundStatMonth(yearOutbound != null ? yearOutbound.getStatMonth() : null);
        vo.setMarkers(markers != null ? markers : Collections.emptyList());
        return vo;
    }

    @Override
    public List<HomeScreenImbalanceWarningListItemVo> listGrassLivestockImbalanceWarnings(
            Integer statYear, Integer statMonth, Long townDeptId, Long villageDeptId)
    {
        BizGrassLivestockImbalanceWarning query = new BizGrassLivestockImbalanceWarning();
        query.setStatYear(statYear);
        query.setStatMonth(statMonth);
        query.setTownDeptId(townDeptId);
        query.setVillageDeptId(villageDeptId);
        List<BizGrassLivestockImbalanceWarning> rows = grassLivestockImbalanceWarningMapper.selectList(query);
        return HomeScreenSupport.buildImbalanceWarningListItems(rows);
    }

    @Override
    public List<HomeScreenPerCapitaIncomeListItemVo> listPerCapitaIncomes(Integer statYear)
    {
        BizDisposableIncome query = new BizDisposableIncome();
        query.setStatYear(statYear);
        List<BizDisposableIncome> rows = bizDisposableIncomeMapper.selectBizDisposableIncomeList(query);
        return HomeScreenSupport.buildPerCapitaIncomeListItems(rows);
    }

    @Override
    public List<HomeScreenFarmerHouseholdListItemVo> listFarmerHouseholds(
            Integer statYear, Integer statMonth, Long townDeptId, Long villageDeptId)
    {
        BizFarmerHousehold query = new BizFarmerHousehold();
        query.setStatYear(statYear);
        query.setStatMonth(statMonth);
        query.setTownDeptId(townDeptId);
        query.setVillageDeptId(villageDeptId);
        // 大屏全县口径，清空 dataScope，避免走填报部门权限
        query.getParams().put("dataScope", "");
        List<BizFarmerHousehold> rows = bizFarmerHouseholdMapper.selectBizFarmerHouseholdList(query);
        return HomeScreenSupport.buildFarmerHouseholdListItems(rows);
    }

    @Override
    public List<HomeScreenCooperativeDevelopmentListItemVo> listCooperativeDevelopments(
            Integer statYear, Integer statMonth, Long townDeptId, Long villageDeptId)
    {
        BizCooperativeDevelopment query = new BizCooperativeDevelopment();
        query.setStatYear(statYear);
        query.setStatMonth(statMonth);
        query.setTownDeptId(townDeptId);
        query.setVillageDeptId(villageDeptId);
        query.getParams().put("dataScope", "");
        List<BizCooperativeDevelopment> rows =
                bizCooperativeDevelopmentMapper.selectBizCooperativeDevelopmentList(query);
        return HomeScreenSupport.buildCooperativeDevelopmentListItems(rows);
    }

    @Override
    public List<HomeScreenFamilyRanchListItemVo> listFamilyRanches(
            Integer statYear, Integer statMonth, Long townDeptId, Long villageDeptId)
    {
        BizFamilyRanch query = new BizFamilyRanch();
        query.setStatYear(statYear);
        query.setStatMonth(statMonth);
        query.setTownDeptId(townDeptId);
        query.setVillageDeptId(villageDeptId);
        query.getParams().put("dataScope", "");
        List<BizFamilyRanch> rows = bizFamilyRanchMapper.selectBizFamilyRanchList(query);
        return HomeScreenSupport.buildFamilyRanchListItems(rows);
    }

    @Override
    public List<HomeScreenLargeLivestockFarmerListItemVo> listLargeLivestockFarmers(
            Integer statYear, Integer statMonth, Long townDeptId, Long villageDeptId)
    {
        BizLargeLivestockFarmer query = new BizLargeLivestockFarmer();
        query.setStatYear(statYear);
        query.setStatMonth(statMonth);
        query.setTownDeptId(townDeptId);
        query.setVillageDeptId(villageDeptId);
        query.getParams().put("dataScope", "");
        List<BizLargeLivestockFarmer> rows =
                bizLargeLivestockFarmerMapper.selectBizLargeLivestockFarmerList(query);
        return HomeScreenSupport.buildLargeLivestockFarmerListItems(rows);
    }

    @Override
    public List<HomeScreenYakOutboundReportListItemVo> listYakOutboundReports(
            Integer statYear, Integer statMonth, Long townDeptId, Long villageDeptId)
    {
        BizYakOutboundReport query = new BizYakOutboundReport();
        query.setStatYear(statYear);
        query.setStatMonth(statMonth);
        query.setTownDeptId(townDeptId);
        query.setVillageDeptId(villageDeptId);
        query.getParams().put("dataScope", "");
        List<BizYakOutboundReport> rows = bizYakOutboundReportMapper.selectBizYakOutboundReportList(query);
        return HomeScreenSupport.buildYakOutboundReportListItems(rows);
    }

    @Override
    public List<HomeScreenYakHerdInventoryListItemVo> listYakHerdInventories(
            Integer statYear, Integer statMonth, Long townDeptId, Long villageDeptId)
    {
        BizYakHerdInventory query = new BizYakHerdInventory();
        query.setStatYear(statYear);
        query.setStatMonth(statMonth);
        query.setTownDeptId(townDeptId);
        query.setVillageDeptId(villageDeptId);
        query.getParams().put("dataScope", "");
        List<BizYakHerdInventory> rows = bizYakHerdInventoryMapper.selectBizYakHerdInventoryList(query);
        return HomeScreenSupport.buildYakHerdInventoryListItems(rows);
    }

    @Override
    public List<HomeScreenLivestockOwnershipHouseholdListItemVo> listLivestockOwnershipHouseholds(
            Integer statYear, Integer statMonth, Long townDeptId, Long villageDeptId)
    {
        BizLivestockOwnershipHousehold query = new BizLivestockOwnershipHousehold();
        query.setStatYear(statYear);
        query.setStatMonth(statMonth);
        query.setTownDeptId(townDeptId);
        query.setVillageDeptId(villageDeptId);
        query.getParams().put("dataScope", "");
        List<BizLivestockOwnershipHousehold> rows =
                bizLivestockOwnershipHouseholdMapper.selectBizLivestockOwnershipHouseholdList(query);
        return HomeScreenSupport.buildLivestockOwnershipHouseholdListItems(rows);
    }

    @Override
    public List<HomeScreenYakInventoryOutboundListItemVo> listYakInventoryOutbounds(
            Integer statYear, Integer statMonth, Long townDeptId, Long villageDeptId)
    {
        // 年月不默认：未传则跨年全量翻页；传入则按条件过滤
        return homeScreenStatsMapper.selectYakInventoryOutboundList(
                statYear, statMonth, townDeptId, villageDeptId);
    }

    @Override
    public List<HomeScreenBreedingEntityQuantityListItemVo> listBreedingEntityQuantities(
            Integer statYear, Integer statMonth, Long townDeptId, Long villageDeptId)
    {
        // 年月未传不过滤，支持跨多年全量翻页；前端筛选项默认当前年月
        return homeScreenStatsMapper.selectBreedingEntityQuantityList(
                statYear, statMonth, townDeptId, villageDeptId);
    }

    @Override
    public List<Map<String, Object>> listTownOptions()
    {
        return townDeptSupport.toAllOptionList();
    }

    @Override
    public List<TreeSelect> listVillageTree()
    {
        return townDeptSupport.buildAllVillageTree();
    }

    private static Date toDate(LocalDate localDate)
    {
        return Date.from(localDate.atStartOfDay(ZoneId.of(BreedingIndustryRules.ZONE_SHANGHAI)).toInstant());
    }

    private static Date toDateEndOfDay(LocalDate localDate)
    {
        return Date.from(localDate.atTime(23, 59, 59)
                .atZone(ZoneId.of(BreedingIndustryRules.ZONE_SHANGHAI)).toInstant());
    }
}
