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

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.ZoneId;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.web.modules.industryservice.domain.vo.BreedingIndustryDegradationStatVo;
import com.ruoyi.web.modules.industryservice.mapper.BreedingIndustryStatsMapper;
import com.ruoyi.web.modules.industryservice.support.BreedingIndustryRules;
import com.ruoyi.web.modules.prosperity.support.AchievementReportValidation;
import com.ruoyi.web.modules.screen.domain.dto.HomeScreenHerdCowAgeSumDto;
import com.ruoyi.web.modules.screen.domain.dto.HomeScreenHerdGenderSumDto;
import com.ruoyi.web.modules.screen.domain.dto.HomeScreenStatPeriodDto;
import com.ruoyi.web.modules.screen.domain.vo.HomeScreenDashboardVo;
import com.ruoyi.web.modules.screen.domain.vo.HomeScreenIndustryOverviewVo;
import com.ruoyi.web.modules.screen.domain.vo.HomeScreenInventoryChangeVo;
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.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>
 * 牦牛存栏/出栏/年龄/趋势取自 {@code biz_yak_herd_inventory}、{@code biz_yak_outbound_report} 全县填报；
 * 产业总览三项取各表<strong>最近填报年月</strong>合计；趋势图取看板所选 {@code statYear} 的 12 个月。
 * 当年未到的月份在 Support 中补零，避免折线图出现未来数据。
 */
@Service
public class HomeScreenServiceImpl implements IHomeScreenService
{
    @Autowired
    private BreedingIndustryStatsMapper breedingIndustryStatsMapper;

    @Autowired
    private HomeScreenStatsMapper homeScreenStatsMapper;

    @Autowired
    private HomeScreenStandardMapper homeScreenStandardMapper;

    @Override
    public HomeScreenDashboardVo loadDashboard(String statYear)
    {
        int year = AchievementReportValidation.parseStatYear(statYear);
        LocalDate statDate = HomeScreenSupport.resolveStatDate(year);
        Date yearStart = toDate(LocalDate.of(year, 1, 1));
        Date yearEnd = toDateEndOfDay(statDate);

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

        // 产业总览：供应商/承销商/市场/草场数量
        HomeScreenIndustryOverviewVo overview = new HomeScreenIndustryOverviewVo();
        overview.setSupplierCount(homeScreenStatsMapper.countSupplierForScreen());
        overview.setDistributorCount(homeScreenStatsMapper.countDistributorForScreen());
        overview.setTradeMarketCount(homeScreenStatsMapper.countTradeMarketForScreen());
        overview.setGrasslandCount(breedingIndustryStatsMapper.countGrassland());
        BigDecimal area = breedingIndustryStatsMapper.sumGrasslandAreaMu();
        overview.setGrasslandAreaMu(area != null ? area.setScale(2, RoundingMode.HALF_UP) : BigDecimal.ZERO);

        HomeScreenStatPeriodDto latestHerd = homeScreenStatsMapper.selectLatestHerdInventoryStatPeriod();
        HomeScreenStatPeriodDto latestOutbound = homeScreenStatsMapper.selectLatestOutboundReportStatPeriod();

        // 产业总览三项：最近填报年月全县合计（接口字段名不变）
        overview.setInventoryTotal(sumHerdYakAtPeriod(latestHerd));
        overview.setAnnualOutbound(sumOutboundYakAtPeriod(latestOutbound));
        overview.setPastureCount(sumFarmerHouseholdAtPeriod(latestOutbound));

        HomeScreenInventoryChangeVo inventoryChange = new HomeScreenInventoryChangeVo();
        if (latestHerd == null)
        {
            inventoryChange.setBullCount(0);
            inventoryChange.setCowCount(0);
            inventoryChange.setUnknownGenderCount(0);
            vo.setAgeStructure(HomeScreenSupport.buildCowAgeStructureFromHerdReport(null));
        }
        else
        {
            HomeScreenHerdGenderSumDto genderSum = homeScreenStatsMapper.sumHerdInventoryGenderByStatYearMonth(
                    latestHerd.getStatYear(), latestHerd.getStatMonth());
            int bull = genderSum != null && genderSum.getBullTotal() != null ? genderSum.getBullTotal() : 0;
            int cow = genderSum != null && genderSum.getCowTotal() != null ? genderSum.getCowTotal() : 0;
            int yakTotal = genderSum != null && genderSum.getYakTotal() != null ? genderSum.getYakTotal() : 0;
            inventoryChange.setBullCount(bull);
            inventoryChange.setCowCount(cow);
            inventoryChange.setUnknownGenderCount(Math.max(0, yakTotal - bull - cow));
            HomeScreenHerdCowAgeSumDto cowAge = homeScreenStatsMapper.sumHerdInventoryCowAgeByStatYearMonth(
                    latestHerd.getStatYear(), latestHerd.getStatMonth());
            vo.setAgeStructure(HomeScreenSupport.buildCowAgeStructureFromHerdReport(cowAge));
        }
        YearMonth anchor = HomeScreenSupport.currentYearMonth();
        int startYm = HomeScreenSupport.yearMonthKey(anchor.minusMonths(11));
        int endYm = HomeScreenSupport.yearMonthKey(anchor);
        inventoryChange.setMonthlyTrend(HomeScreenSupport.buildRolling12MonthBullCowTrend(
                homeScreenStatsMapper.selectHerdInventoryBullCowByYearMonthRange(startYm, endYm), anchor));
        vo.setOutboundMonthly(HomeScreenSupport.buildRolling12MonthOutbound(
                homeScreenStatsMapper.selectOutboundReportYakCountByYearMonthRange(startYm, endYm), anchor));

        vo.setIndustryOverview(overview);
        vo.setInventoryChange(inventoryChange);
        vo.setGrassland(HomeScreenSupport.buildGrasslandVo(
                overview.getGrasslandCount(),
                breedingIndustryStatsMapper.countAvailableGrassland(),
                breedingIndustryStatsMapper.countInUseGrassland(toDate(statDate)),
                breedingIndustryStatsMapper.selectDegradationGroupCounts()));
        vo.setAppointment(HomeScreenSupport.buildAppointment(
                homeScreenStatsMapper.selectAppointmentAnnualByYear(year),
                homeScreenStatsMapper.selectAppointmentMonthlyByYearMonthRange(startYm, endYm),
                anchor));
        vo.setSubsidy(HomeScreenSupport.buildSubsidy(
                homeScreenStatsMapper.sumSubsidyAmountByTypeForYear(yearStart, yearEnd),
                homeScreenStatsMapper.countSubsidyGrantInYear(yearStart, yearEnd) > 0));
        int videoCount = homeScreenStatsMapper.countVideoCoursesPublishedInYear(yearStart, yearEnd);
        int trainingPublishCount = homeScreenStatsMapper.countTrainingsPublishedInYear(yearStart, yearEnd);
        vo.setAgriClassroom(HomeScreenSupport.buildAgriClassroom(videoCount, trainingPublishCount));
        boolean hasTraining = homeScreenStatsMapper.countPublishedTrainingsWithTrainingTimeInYearMonthRange(
                startYm, endYm) > 0;
        vo.setTrainingTrend(HomeScreenSupport.buildTrainingTrend(
                homeScreenStatsMapper.selectTrainingTrendByTrainingYearMonthRange(startYm, endYm),
                hasTraining,
                anchor));
        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.sumOutboundReportFarmerHouseholdCountByStatYearMonth(
                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()
    {
        HomeScreenStatPeriodDto latestHerd = homeScreenStatsMapper.selectLatestHerdInventoryStatPeriod();
        HomeScreenStatPeriodDto latestOutbound = homeScreenStatsMapper.selectLatestOutboundReportStatPeriod();

        List<HomeScreenTownMapMarkerVo> markers = Collections.emptyList();
        if (latestHerd != null || latestOutbound != null)
        {
            markers = homeScreenStatsMapper.selectTownMapMarkers(
                    latestHerd != null ? latestHerd.getStatYear() : null,
                    latestHerd != null ? latestHerd.getStatMonth() : null,
                    latestOutbound != null ? latestOutbound.getStatYear() : null,
                    latestOutbound != null ? latestOutbound.getStatMonth() : null);
        }
        HomeScreenTownMapVo vo = new HomeScreenTownMapVo();
        vo.setHerdStatYear(latestHerd != null ? latestHerd.getStatYear() : null);
        vo.setOutboundStatYear(latestOutbound != null ? latestOutbound.getStatYear() : null);
        vo.setMarkers(markers != null ? markers : Collections.emptyList());
        return vo;
    }

    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());
    }
}
