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

import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.web.modules.industryservice.domain.BizYakHealthSourceRecord;
import com.ruoyi.web.modules.industryservice.domain.dto.OpenBreedingProcessRecordDto;
import com.ruoyi.web.modules.industryservice.domain.dto.OpenDiagnosisRecordDto;
import com.ruoyi.web.modules.industryservice.domain.dto.OpenQuarantineRecordDto;
import com.ruoyi.web.modules.industryservice.domain.vo.YakAssetSyncResultVo;
import com.ruoyi.web.modules.industryservice.support.HealthRecordOpenApiMapper;
import com.ruoyi.web.modules.industryservice.support.ThirdPartyHealthRecordClient;
import com.ruoyi.web.modules.industryservice.support.YakDiseaseWarningRules;

/**
 * 第三方健康源同步：拉取检疫/诊疗/养殖过程 → 落库 → 规则分析生成预警。
 */
@Service
public class YakDiseaseWarningSyncService
{
    private final AtomicBoolean syncing = new AtomicBoolean(false);

    @Autowired
    private ThirdPartyHealthRecordClient thirdPartyHealthRecordClient;

    @Autowired
    private YakHealthSourceRecordSyncTxService healthSourceRecordSyncTxService;

    @Autowired
    private YakDiseaseWarningAnalyzer warningAnalyzer;

    public YakAssetSyncResultVo syncFromThirdParty()
    {
        if (!syncing.compareAndSet(false, true))
        {
            throw new ServiceException(YakDiseaseWarningRules.MSG_SYNC_IN_PROGRESS);
        }
        try
        {
            YakAssetSyncResultVo result = new YakAssetSyncResultVo();
            Date syncTime = new Date();
            syncQuarantineRecords(result, syncTime);
            syncDiagnosisRecords(result, syncTime);
            syncBreedingRecords(result, syncTime);
            try
            {
                int warningCreated = warningAnalyzer.analyzeAndGenerate(syncTime);
                result.setInsertCount(result.getInsertCount() + warningCreated);
            }
            catch (Exception e)
            {
                result.setFailCount(result.getFailCount() + 1);
                result.getFailMessages().add("分析生成预警: " + e.getMessage());
            }
            result.setSyncTime(syncTime);
            return result;
        }
        finally
        {
            syncing.set(false);
        }
    }

    private void syncQuarantineRecords(YakAssetSyncResultVo result, Date syncTime)
    {
        List<OpenQuarantineRecordDto> records = fetchSafely(() -> thirdPartyHealthRecordClient.fetchQuarantineRecords());
        for (OpenQuarantineRecordDto dto : records)
        {
            persistSource(result, syncTime, () -> HealthRecordOpenApiMapper.fromQuarantine(dto),
                    dto != null ? String.valueOf(dto.getId()) : "?");
        }
    }

    private void syncDiagnosisRecords(YakAssetSyncResultVo result, Date syncTime)
    {
        List<OpenDiagnosisRecordDto> records = fetchSafely(() -> thirdPartyHealthRecordClient.fetchDiagnosisRecords());
        for (OpenDiagnosisRecordDto dto : records)
        {
            persistSource(result, syncTime, () -> HealthRecordOpenApiMapper.fromDiagnosis(dto),
                    dto != null ? String.valueOf(dto.getId()) : "?");
        }
    }

    private void syncBreedingRecords(YakAssetSyncResultVo result, Date syncTime)
    {
        List<OpenBreedingProcessRecordDto> records = fetchSafely(
                () -> thirdPartyHealthRecordClient.fetchBreedingProcessRecords());
        for (OpenBreedingProcessRecordDto dto : records)
        {
            persistSource(result, syncTime, () -> HealthRecordOpenApiMapper.fromBreedingProcess(dto),
                    dto != null ? String.valueOf(dto.getId()) : "?");
        }
    }

    private interface SourceMapper
    {
        BizYakHealthSourceRecord map();
    }

    private interface RecordFetcher<T>
    {
        List<T> fetch();
    }

    private <T> List<T> fetchSafely(RecordFetcher<T> fetcher)
    {
        try
        {
            return fetcher.fetch();
        }
        catch (ServiceException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            throw new ServiceException("第三方服务不可用：" + e.getMessage());
        }
    }

    private void persistSource(YakAssetSyncResultVo result, Date syncTime, SourceMapper mapper, String failKey)
    {
        try
        {
            BizYakHealthSourceRecord row = mapper.map();
            boolean inserted = healthSourceRecordSyncTxService.persistSourceRecord(row, syncTime);
            if (inserted)
            {
                result.setInsertCount(result.getInsertCount() + 1);
            }
            else
            {
                result.setUpdateCount(result.getUpdateCount() + 1);
            }
        }
        catch (Exception e)
        {
            result.setFailCount(result.getFailCount() + 1);
            result.getFailMessages().add(failKey + ": " + e.getMessage());
        }
    }
}
