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

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
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;

/**
 * 第三方健康源 OpenAPI DTO → 本地 {@link BizYakHealthSourceRecord} 映射。
 * <p>
 * {@code external_id} 前缀约定：检疫 {@code Q:}、诊疗 {@code D:}、养殖过程 {@code B:} + 第三方主键。<br>
 * 供 {@link com.ruoyi.web.modules.industryservice.service.YakDiseaseWarningSyncService} 同步落库前调用。<br>
 * 地区键、记录时间等字段直接影响后续「同区同日」集中预警分组。
 * </p>
 */
public final class HealthRecordOpenApiMapper
{
    private static final SimpleDateFormat DATE_TIME = createDateTimeFormat();

    private static final SimpleDateFormat DATE_ONLY = createDateOnlyFormat();

    private HealthRecordOpenApiMapper()
    {
    }

    /** 检疫 OpenAPI → 本地；{@code externalId = Q:{id}} */
    public static BizYakHealthSourceRecord fromQuarantine(OpenQuarantineRecordDto dto)
    {
        requireId(dto != null ? dto.getId() : null, "检疫记录");
        BizYakHealthSourceRecord row = baseRow(YakDiseaseWarningAnalysisRules.RECORD_TYPE_QUARANTINE,
                "Q:" + dto.getId(), dto.getFarmId(), dto.getFarmName());
        row.setEnclosureId(dto.getFarmEnclosureId());
        row.setEnclosureName(StringUtils.trim(dto.getFarmEnclosureName()));
        row.setCattleId(dto.getCattleId());
        row.setEarTagNumber(StringUtils.trim(dto.getEarTagNumber()));
        row.setYakNo(resolveYakNo(dto.getEarTagNumber(), dto.getCattleId()));
        row.setRecordTime(parseDateTimeRequired(dto.getQuarantineTime(), "检疫时间"));
        row.setSourceCreateTime(parseDateTimeOptional(dto.getCreateTime()));
        row.setQuarantineUnitId(dto.getQuarantineUnitId());
        row.setQuarantineUnitName(StringUtils.trim(dto.getQuarantineUnitName()));
        row.setQuarantinePersonnelId(dto.getQuarantinePersonnelId());
        row.setQuarantinePersonnelName(StringUtils.trim(dto.getQuarantinePersonnelName()));
        row.setQuarantineItem(StringUtils.trim(dto.getQuarantineItem()));
        row.setQuarantineResult(StringUtils.trim(dto.getQuarantineResult()));
        row.setQuarantineReport(StringUtils.trim(dto.getQuarantineReport()));
        row.setCertificate(StringUtils.trim(dto.getCertificate()));
        row.setScenePicture(StringUtils.trim(dto.getScenePicture()));
        return row;
    }

    /** 诊疗 OpenAPI → 本地；{@code externalId = D:{id}} */
    public static BizYakHealthSourceRecord fromDiagnosis(OpenDiagnosisRecordDto dto)
    {
        requireId(dto != null ? dto.getId() : null, "诊疗记录");
        BizYakHealthSourceRecord row = baseRow(YakDiseaseWarningAnalysisRules.RECORD_TYPE_DIAGNOSIS,
                "D:" + dto.getId(), dto.getFarmId(), null);
        row.setEnclosureId(dto.getFarmEnclosureId());
        row.setCattleId(dto.getCattleId());
        row.setYakNo(resolveYakNo(null, dto.getCattleId()));
        row.setRecordTime(parseDateTimeRequired(dto.getDiagnosisTime(), "诊疗时间"));
        row.setSourceCreateTime(parseDateTimeOptional(dto.getCreateTime()));
        row.setAge(StringUtils.trim(dto.getAge()));
        row.setEtiology(StringUtils.trim(dto.getEtiology()));
        row.setDiagnosisResult(StringUtils.trim(dto.getDiagnosisResult()));
        row.setMedicationName(StringUtils.trim(dto.getMedicationName()));
        row.setMedicationMethod(StringUtils.trim(dto.getMedicationMethod()));
        row.setClinic(StringUtils.trim(dto.getClinic()));
        row.setTreatmentTime(parseDateTimeOptional(dto.getTreatmentTime()));
        row.setTreatmentCycle(StringUtils.trim(dto.getTreatmentCycle()));
        row.setTreatmentEffect(StringUtils.trim(dto.getTreatmentEffect()));
        row.setConditionChange(StringUtils.trim(dto.getConditionChange()));
        row.setRecoveryTime(parseDateTimeOptional(dto.getRecoveryTime()));
        row.setRecoveryHealthStatus(StringUtils.trim(dto.getRecoveryHealthStatus()));
        return row;
    }

    /** 养殖过程 OpenAPI → 本地；{@code externalId = B:{id}}；本期分析仅标记已读不生成预警 */
    public static BizYakHealthSourceRecord fromBreedingProcess(OpenBreedingProcessRecordDto dto)
    {
        requireId(dto != null ? dto.getId() : null, "养殖过程记录");
        BizYakHealthSourceRecord row = baseRow(YakDiseaseWarningAnalysisRules.RECORD_TYPE_BREEDING,
                "B:" + dto.getId(), dto.getFarmId(), null);
        row.setRecordNo(StringUtils.trim(dto.getRecordNo()));
        row.setSourceType(StringUtils.trim(dto.getSourceType()));
        row.setTaskId(dto.getTaskId());
        row.setOperationType(StringUtils.trim(dto.getOperationType()));
        row.setEnclosureId(dto.getEnclosureId());
        row.setBatchId(dto.getBatchId());
        row.setCattleIds(StringUtils.trim(dto.getCattleIds()));
        row.setYakNo(resolveProcessYakNo(dto.getCattleIds()));
        row.setRecordTime(parseDateTimeRequired(dto.getExecuteTime(), "执行时间"));
        row.setSourceCreateTime(parseDateTimeOptional(dto.getCreateTime()));
        row.setExecutorUserId(dto.getExecutorUserId());
        row.setExecutorName(StringUtils.trim(dto.getExecutorName()));
        row.setExecuteResult(StringUtils.trim(dto.getExecuteResult()));
        row.setDetailJson(StringUtils.trim(dto.getDetailJson()));
        row.setMaterialUsageJson(StringUtils.trim(dto.getMaterialUsageJson()));
        row.setAttachments(StringUtils.trim(dto.getAttachments()));
        row.setExceptionFlag(StringUtils.trim(dto.getExceptionFlag()));
        row.setExceptionDesc(StringUtils.trim(dto.getExceptionDesc()));
        row.setRemark(StringUtils.trim(dto.getRemark()));
        return row;
    }

    private static BizYakHealthSourceRecord baseRow(int recordType, String externalId, Long farmId, String farmName)
    {
        BizYakHealthSourceRecord row = new BizYakHealthSourceRecord();
        row.setRecordType(recordType);
        row.setExternalId(externalId);
        row.setFarmId(farmId);
        row.setFarmName(StringUtils.trim(farmName));
        row.setRegionKey(HealthRecordRegionSupport.buildRegionKey(farmId, farmName));
        row.setAnalyzedFlag(YakDiseaseWarningAnalysisRules.ANALYZED_NO);
        return row;
    }

    private static String resolveYakNo(String earTag, Long cattleId)
    {
        if (StringUtils.isNotEmpty(earTag))
        {
            return earTag.trim();
        }
        if (cattleId != null)
        {
            return String.valueOf(cattleId);
        }
        return null;
    }

    private static String resolveProcessYakNo(String cattleIds)
    {
        if (StringUtils.isEmpty(cattleIds))
        {
            return null;
        }
        String text = cattleIds.trim();
        int comma = text.indexOf(',');
        return comma > 0 ? text.substring(0, comma).trim() : text;
    }

    private static void requireId(Long id, String label)
    {
        if (id == null)
        {
            throw new ServiceException(label + "ID 不能为空");
        }
    }

    private static Date parseDateTimeRequired(String value, String label)
    {
        if (StringUtils.isEmpty(value))
        {
            throw new ServiceException(label + "不能为空");
        }
        return parseDateTime(value.trim());
    }

    private static Date parseDateTimeOptional(String value)
    {
        if (StringUtils.isEmpty(value))
        {
            return null;
        }
        return parseDateTime(value.trim());
    }

    private static Date parseDateTime(String text)
    {
        try
        {
            synchronized (DATE_TIME)
            {
                if (text.length() > 10)
                {
                    return DATE_TIME.parse(text);
                }
            }
            synchronized (DATE_ONLY)
            {
                return DATE_ONLY.parse(text);
            }
        }
        catch (ParseException e)
        {
            throw new ServiceException("时间格式无效：" + text);
        }
    }

    private static SimpleDateFormat createDateTimeFormat()
    {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        df.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        df.setLenient(false);
        return df;
    }

    private static SimpleDateFormat createDateOnlyFormat()
    {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        df.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        df.setLenient(false);
        return df;
    }
}
