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 org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.web.modules.industryservice.domain.dto.BreedingIndustryYakSnapshot;
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.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.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;

/**
 * 大屏首页统计服务实现。
 */
@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);

        List<Long> allowedPastureIds = safeActivePastureIds();
        List<BreedingIndustryYakSnapshot> snapshots = allowedPastureIds.isEmpty()
                ? Collections.emptyList()
                : safeSnapshots(allowedPastureIds);

        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.setPastureCount(allowedPastureIds.isEmpty()
                ? 0
                : breedingIndustryStatsMapper.countPastureInScope(allowedPastureIds));
        overview.setGrasslandCount(breedingIndustryStatsMapper.countGrassland());
        BigDecimal area = breedingIndustryStatsMapper.sumGrasslandAreaMu();
        overview.setGrasslandAreaMu(area != null ? area.setScale(2, RoundingMode.HALF_UP) : BigDecimal.ZERO);

        HomeScreenInventoryChangeVo inventoryChange = new HomeScreenInventoryChangeVo();
        if (allowedPastureIds.isEmpty())
        {
            overview.setInventoryTotal(0);
            overview.setAnnualOutbound(0);
            inventoryChange.setBullCount(0);
            inventoryChange.setCowCount(0);
            inventoryChange.setUnknownGenderCount(0);
            inventoryChange.setMonthlyTrend(HomeScreenSupport.buildBullCowMonthlyTrend(
                    Collections.emptyList(), statDate));
            vo.setAgeStructure(HomeScreenSupport.buildAgeStructureAtDate(Collections.emptyList(), statDate));
            vo.setOutboundMonthly(HomeScreenSupport.buildOutboundMonthly(null, statDate));
        }
        else
        {
            int inventoryTotal = HomeScreenSupport.countInventoryAtDate(snapshots, statDate);
            int[] gender = HomeScreenSupport.countGenderAtDate(snapshots, statDate);
            overview.setInventoryTotal(inventoryTotal);
            overview.setAnnualOutbound(breedingIndustryStatsMapper.countAnnualOutbound(
                    allowedPastureIds, yearStart, yearEnd));
            inventoryChange.setBullCount(gender[0]);
            inventoryChange.setCowCount(gender[1]);
            inventoryChange.setUnknownGenderCount(Math.max(0, inventoryTotal - gender[0] - gender[1]));
            inventoryChange.setMonthlyTrend(HomeScreenSupport.buildBullCowMonthlyTrend(snapshots, statDate));
            vo.setAgeStructure(HomeScreenSupport.buildAgeStructureAtDate(snapshots, statDate));
            vo.setOutboundMonthly(HomeScreenSupport.buildOutboundMonthly(
                    homeScreenStatsMapper.selectOutboundCountByMonth(allowedPastureIds, yearStart, yearEnd),
                    statDate));
        }

        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.selectAppointmentMonthlyByYear(year),
                statDate));
        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.countPublishedTrainingsWithTrainingTimeInYear(year) > 0;
        vo.setTrainingTrend(HomeScreenSupport.buildTrainingTrend(
                homeScreenStatsMapper.selectTrainingTrendByTrainingYear(year),
                hasTraining,
                statDate));
        vo.setAvailableYears(HomeScreenSupport.buildAvailableYears(
                homeScreenStatsMapper.selectDistinctOutboundYears(),
                homeScreenStatsMapper.selectDistinctAppointmentYears(),
                homeScreenStatsMapper.selectDistinctSubsidyYears(),
                homeScreenStatsMapper.selectDistinctStandardCreateYears(),
                homeScreenStatsMapper.selectDistinctTechPublishYears(),
                homeScreenStatsMapper.selectDistinctTrainingYears()));
        return vo;
    }

    @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;
    }

    private List<Long> safeActivePastureIds()
    {
        List<Long> ids = breedingIndustryStatsMapper.selectActivePastureIds();
        return ids != null ? ids : Collections.emptyList();
    }

    private List<BreedingIndustryYakSnapshot> safeSnapshots(List<Long> allowedPastureIds)
    {
        List<BreedingIndustryYakSnapshot> list = breedingIndustryStatsMapper.selectYakSnapshotsInScope(allowedPastureIds);
        return list != null ? list : Collections.emptyList();
    }

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