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

import java.time.YearMonth;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.web.modules.circulation.mapper.BizQuarantineStationMapper;
import com.ruoyi.web.modules.epidemic.domain.BizEpidemicReport;
import com.ruoyi.web.modules.epidemic.domain.BizLabDetection;
import com.ruoyi.web.modules.epidemic.domain.BizRiskFactorWeight;
import com.ruoyi.web.modules.epidemic.mapper.BizEpidemicReportMapper;
import com.ruoyi.web.modules.epidemic.mapper.BizLabDetectionMapper;
import com.ruoyi.web.modules.epidemic.mapper.BizRiskFactorWeightMapper;
import com.ruoyi.web.modules.prosperity.support.AchievementReportValidation;
import com.ruoyi.web.modules.screen.domain.vo.EpidemicRiskScreenDashboardVo;
import com.ruoyi.web.modules.screen.domain.vo.ScreenEpidemicReportListItemVo;
import com.ruoyi.web.modules.screen.service.IEpidemicRiskScreenService;
import com.ruoyi.web.modules.screen.support.EpidemicRiskScreenSupport;
import com.ruoyi.web.modules.screen.support.HomeScreenSupport;

/**
 * 大屏疫病风险统计服务实现。
 * <p>
 * 按统计年分别拉取：检测记录（检测年）、上报记录（上报年）、已解除记录（解除年）、
 * 在控记录（上报年）。各区块无数据时对应 {@code hasXxxData=false} 或空列表。
 */
@Service
public class EpidemicRiskScreenServiceImpl implements IEpidemicRiskScreenService
{
    /** 风险因子权重配置固定主键，见 {@code biz_risk_factor_weight} */
    private static final long RISK_FACTOR_CONFIG_ID = 1L;

    @Autowired
    private BizLabDetectionMapper labDetectionMapper;

    @Autowired
    private BizEpidemicReportMapper epidemicReportMapper;

    @Autowired
    private BizQuarantineStationMapper quarantineStationMapper;

    @Autowired
    private BizRiskFactorWeightMapper riskFactorWeightMapper;

    @Override
    public EpidemicRiskScreenDashboardVo loadDashboard(String statYear)
    {
        int year = AchievementReportValidation.parseStatYear(statYear);
        List<BizLabDetection> labRows = safeLabByYear(year);
        List<BizEpidemicReport> reportRows = safeReportByYear(year);
        List<BizEpidemicReport> relievedRows = safeRelievedByReleaseYear(year);
        List<BizEpidemicReport> activeRows = safeActiveControlByYear(year);

        boolean hasLabData = !labRows.isEmpty();
        boolean hasEpidemicData = !reportRows.isEmpty();
        boolean hasRelievedData = !relievedRows.isEmpty();

        YearMonth rollingAnchor = HomeScreenSupport.currentYearMonth();
        List<BizLabDetection> rollingLabRows = safeLabByTestDateBetween(rollingAnchor);

        EpidemicRiskScreenDashboardVo vo = new EpidemicRiskScreenDashboardVo();
        vo.setStatYear(year);
        vo.setHasLabData(hasLabData);
        vo.setHasEpidemicData(hasEpidemicData);
        vo.setHasRelievedData(hasRelievedData);
        vo.setLabDetection(!rollingLabRows.isEmpty()
                ? EpidemicRiskScreenSupport.buildLabDetection(rollingLabRows, rollingAnchor) : null);
        vo.setSampleSourceStats(EpidemicRiskScreenSupport.buildSampleSourceStats(labRows, hasLabData));
        vo.setRiskLevelStats(EpidemicRiskScreenSupport.buildRiskLevelStats(reportRows));
        vo.setEpidemicTypeStats(EpidemicRiskScreenSupport.buildEpidemicTypeStats(reportRows));
        vo.setTransmissionRouteStats(EpidemicRiskScreenSupport.buildTransmissionRouteStats(reportRows));
        vo.setRelieveDurationByType(EpidemicRiskScreenSupport.buildRelieveDurationByType(relievedRows));
        vo.setEpidemicSituation(buildSituation(activeRows, relievedRows));
        vo.setRiskFactorWeights(EpidemicRiskScreenSupport.buildRiskFactorWeights(loadRiskFactorConfig()));
        vo.setAvailableYears(EpidemicRiskScreenSupport.buildAvailableYears(
                labDetectionMapper.selectDistinctTestYears(),
                epidemicReportMapper.selectDistinctReportYears()));
        return vo;
    }

    @Override
    public List<ScreenEpidemicReportListItemVo> listReportsByReportYear(String statYear)
    {
        int year = AchievementReportValidation.parseStatYear(statYear);
        return EpidemicRiskScreenSupport.toReportListItems(safeReportByYear(year));
    }

    private com.ruoyi.web.modules.screen.domain.vo.EpidemicSituationVo buildSituation(
            List<BizEpidemicReport> activeRows, List<BizEpidemicReport> relievedRows)
    {
        int available = quarantineStationMapper.countForScreenByOperateStatus(
                EpidemicRiskScreenSupport.normalOperateStatus());
        int disabled = quarantineStationMapper.countForScreenDisabled();
        return EpidemicRiskScreenSupport.buildEpidemicSituation(available, disabled, activeRows, relievedRows);
    }

    private BizRiskFactorWeight loadRiskFactorConfig()
    {
        return riskFactorWeightMapper.selectBizRiskFactorWeightById(RISK_FACTOR_CONFIG_ID);
    }

    private List<BizLabDetection> safeLabByTestDateBetween(YearMonth anchor)
    {
        java.time.LocalDate rangeEnd = HomeScreenSupport.rolling12MonthWindowEnd(anchor);
        java.util.Date start = toDate(anchor.minusMonths(11).atDay(1));
        java.util.Date end = toDateEndOfDay(rangeEnd);
        List<BizLabDetection> list = labDetectionMapper.selectByTestDateBetween(start, end);
        return list != null ? list : new ArrayList<>();
    }

    private static java.util.Date toDate(java.time.LocalDate localDate)
    {
        return java.util.Date.from(localDate.atStartOfDay(
                java.time.ZoneId.of(com.ruoyi.web.modules.industryservice.support.BreedingIndustryRules.ZONE_SHANGHAI))
                .toInstant());
    }

    private static java.util.Date toDateEndOfDay(java.time.LocalDate localDate)
    {
        return java.util.Date.from(localDate.atTime(23, 59, 59)
                .atZone(java.time.ZoneId.of(com.ruoyi.web.modules.industryservice.support.BreedingIndustryRules.ZONE_SHANGHAI))
                .toInstant());
    }

    private List<BizLabDetection> safeLabByYear(int year)
    {
        List<BizLabDetection> list = labDetectionMapper.selectByTestYear(year);
        return list != null ? list : new ArrayList<>();
    }

    private List<BizEpidemicReport> safeReportByYear(int year)
    {
        List<BizEpidemicReport> list = epidemicReportMapper.selectByReportYear(year);
        return list != null ? list : new ArrayList<>();
    }

    private List<BizEpidemicReport> safeRelievedByReleaseYear(int year)
    {
        List<BizEpidemicReport> list = epidemicReportMapper.selectRelievedByReleaseYear(year);
        return list != null ? list : new ArrayList<>();
    }

    private List<BizEpidemicReport> safeActiveControlByYear(int year)
    {
        List<BizEpidemicReport> list = epidemicReportMapper.selectActiveControlByReportYear(year);
        return list != null ? list : new ArrayList<>();
    }
}
