package com.ruoyi.web.modules.diagnosis.service;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.web.modules.diagnosis.domain.dto.ConsultAskerIpCountDto;
import com.ruoyi.web.modules.diagnosis.mapper.BizConsultMessageMapper;
import com.ruoyi.web.modules.diagnosis.support.AiConsultDiseaseWarningProperties;
import com.ruoyi.web.modules.diagnosis.support.AiConsultDiseaseWarningRules;
import com.ruoyi.web.modules.diagnosis.support.ConsultAskerIpRegionResolver;
import com.ruoyi.web.modules.diagnosis.support.ConsultSessionRules;
import com.ruoyi.web.modules.industryservice.domain.BizYakDiseaseWarning;
import com.ruoyi.web.modules.industryservice.mapper.BizYakDiseaseWarningMapper;

/**
 * 按 AI 问诊 IP 集中程度生成/更新牦牛疾病预警。
 */
@Service
public class AiConsultDiseaseWarningService
{
    private static final Logger log = LoggerFactory.getLogger(AiConsultDiseaseWarningService.class);

    private static final TimeZone ZONE = TimeZone.getTimeZone("Asia/Shanghai");

    @Autowired
    private AiConsultDiseaseWarningProperties properties;

    @Autowired
    private BizConsultMessageMapper consultMessageMapper;

    @Autowired
    private BizYakDiseaseWarningMapper warningMapper;

    @Autowired
    private ConsultAskerIpRegionResolver ipRegionResolver;

    @Transactional(rollbackFor = Exception.class)
    public int scanAndPersistWarnings()
    {
        if (!properties.isEnabled())
        {
            return 0;
        }
        int threshold = Math.max(1, properties.getThreshold());
        Date now = new Date();
        Date monthStart = monthBegin(now);
        List<ConsultAskerIpCountDto> ipCounts = consultMessageMapper.selectAiYakDiseaseAskerIpCounts(
                ConsultSessionRules.CONSULT_TYPE_AI, AiConsultDiseaseWarningRules.AI_CATEGORY, monthStart, now);
        if (ipCounts == null || ipCounts.isEmpty())
        {
            return 0;
        }
        Map<String, Long> regionTotals = aggregateByRegion(ipCounts, threshold);
        int affected = 0;
        for (Map.Entry<String, Long> entry : regionTotals.entrySet())
        {
            if (upsertRegionWarning(entry.getKey(), entry.getValue(), now, monthStart))
            {
                affected++;
            }
        }
        if (affected > 0)
        {
            log.info("AI 问诊疫病预警扫描完成，更新/新增 {} 个地区", affected);
        }
        return affected;
    }

    private Map<String, Long> aggregateByRegion(List<ConsultAskerIpCountDto> ipCounts, int threshold)
    {
        Map<String, Long> regionTotals = new HashMap<>();
        for (ConsultAskerIpCountDto row : ipCounts)
        {
            if (row == null || row.getMessageCount() == null || row.getMessageCount() < threshold)
            {
                continue;
            }
            String district = ipRegionResolver.resolveDistrictLabel(row.getAskerIp());
            if (StringUtils.isEmpty(district))
            {
                continue;
            }
            regionTotals.merge(district, row.getMessageCount(), Long::sum);
        }
        return regionTotals;
    }

    private boolean upsertRegionWarning(String districtLabel, long totalCount, Date alertTime, Date monthStart)
    {
        String alertMessage = AiConsultDiseaseWarningRules.buildAlertMessage(districtLabel, totalCount);
        BizYakDiseaseWarning existing = warningMapper.selectMonthlyWarningByPastureName(
                districtLabel, AiConsultDiseaseWarningRules.WARNING_TYPE_AI_CONSULT, monthStart, alertTime);
        if (existing != null)
        {
            BizYakDiseaseWarning patch = new BizYakDiseaseWarning();
            patch.setId(existing.getId());
            patch.setAlertTime(alertTime);
            patch.setAlertMessage(alertMessage);
            patch.setMeasuredValue(String.valueOf(totalCount));
            patch.setLastSyncTime(alertTime);
            patch.setUpdateTime(alertTime);
            warningMapper.updateAlertContent(patch);
            return true;
        }
        BizYakDiseaseWarning row = new BizYakDiseaseWarning();
        row.setPastureName(districtLabel);
        row.setAlertTime(alertTime);
        row.setAlertMessage(alertMessage);
        row.setWarningType(AiConsultDiseaseWarningRules.WARNING_TYPE_AI_CONSULT);
        row.setMeasuredValue(String.valueOf(totalCount));
        row.setDataSource(AiConsultDiseaseWarningRules.DATA_SOURCE);
        row.setLastSyncTime(alertTime);
        row.setCreateTime(alertTime);
        row.setUpdateTime(alertTime);
        warningMapper.insertBizYakDiseaseWarning(row);
        return true;
    }

    static Date monthBegin(Date ref)
    {
        Calendar cal = Calendar.getInstance(ZONE);
        cal.setTime(ref != null ? ref : new Date());
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }
}
