package com.ruoyi.web.work.hl7.service.impl;

import ca.uhn.hl7v2.HL7Exception;
import ca.uhn.hl7v2.model.Varies;
import ca.uhn.hl7v2.model.v24.datatype.CE;
import ca.uhn.hl7v2.model.v24.group.ORU_R01_OBSERVATION;
import ca.uhn.hl7v2.model.v24.message.ORU_R01;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.web.work.hl7.service.HL7MicrobialReportService;
import com.ruoyi.web.work.hl7.util.DateTimeConverter;
import com.ruoyi.web.work.domain.Result;
import com.ruoyi.web.work.hl7.service.HL7ResultService;
import com.ruoyi.web.work.mapper.ResultMapper;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 检测检查报告结果
 */
@Service
@Log4j2
@Transactional
public class HL7ResultServiceImpl extends ServiceImpl<ResultMapper, Result> implements HL7ResultService {

    @Autowired
    HL7MicrobialReportService microbialReportService;

    /**
     * 保存请求报告结果obx
     *
     * @param obrId
     * @param oruR01
     */
    @Override
    public void saveReportResult(Long obrId, ORU_R01 oruR01) throws HL7Exception {
        List<ORU_R01_OBSERVATION> observationAll = oruR01.getPATIENT_RESULT().getORDER_OBSERVATION().getOBSERVATIONAll();
        if (CollectionUtils.isEmpty(observationAll)) {
            log.info("没有观察结果需要保存");
            return;
        }

        for (ORU_R01_OBSERVATION observation : observationAll) {
            String dataType = observation.getOBX().getValueType().getValue();
            switch (dataType) {
                case "1": // 数字（检验报告）
                    processNumericObservation(observation, obrId);
                    break;
                case "0": // 普通文本（检查报告）
                    processTextObservation(observation, obrId);
                    break;
                case "CE": // 微生物报告
                    processMicrobialReport(oruR01, obrId);
                    return; // 处理完微生物报告后退出循环
                default:
                    log.warn("未知的数据类型: {}", dataType);
                    continue;
            }
        }
        log.info("保存请求结果obx完成!");
    }

    /**
     * 检验报告
     * @param observation
     * @param obrId 检查项目tb_obr_request id
     */
    private void processNumericObservation(ORU_R01_OBSERVATION observation, Long obrId) {
        List<Result> entities = new ArrayList<>();
        Result entity = createObxEntity(observation, obrId);
        // 设置检验报告特有的属性
        entity.setObsProjectDetail(observation.getOBX().getObservationSubId().getValue());//结果值
        entity.setMecTechObsProject(observation.getOBX().getObservationIdentifier().getIdentifier().getValue());//检查项目代码
        entity.setMecTechObsName(observation.getOBX().getObservationIdentifier().getText().getValue()); //检查项目名称
        entity.setUnitCode(observation.getOBX().getUnits().getIdentifier().getValue()); //单位代码
        entity.setResult(observation.getOBX().getReferencesRange().getValue());//参考结果
        entities.add(entity);
        baseMapper.insert(entity);
    }

    /**
     * 检查报告结果
     * @param observation
     * @param obrId 检查项目tb_obr_request id
     */
    private void processTextObservation(ORU_R01_OBSERVATION observation, Long obrId) {
        Result entity = createObxEntity(observation, obrId);
        // 设置检查报告特有的属性
        entity.setMecTechObsName(observation.getOBX().getObservationSubId().getValue());//检查名称
        entity.setMecTechObsProject(observation.getOBX().getObservationIdentifier().getIdentifier().getValue());//检查代码
        baseMapper.insert(entity);
    }

    /**
     * 微生物报告结果
     * @param oruR01
     * @param obrId
     */
    private void processMicrobialReport(ORU_R01 oruR01, Long obrId) throws HL7Exception {
        for (ORU_R01_OBSERVATION r01Observation : oruR01.getPATIENT_RESULT().getORDER_OBSERVATION().getOBSERVATIONAll()) {
            Result entity = new Result();
            processObservation(r01Observation, entity, obrId);
            baseMapper.insert(entity);
        }
    }

    private Result createObxEntity(ORU_R01_OBSERVATION observation, Long obrId) {
        Result entity = new Result();
        // 通用属性的设置
        entity.setDataType(observation.getOBX().getValueType().getValue());
        entity.setObrId(obrId);
        entity.setSign(observation.getOBX().getAbnormalFlags().getValue()); //高低标志
        String reportTime = observation.getOBX().getDateTimeOfTheObservation().getTimeOfAnEvent().getValue();
        entity.setReportTime(DateTimeConverter.convertToUnifiedFormat(reportTime));//报告时间
        return entity;
    }



    /**
     * 微生物报告结果
     * @param r01Observation
     * @param entity
     * @param obrId
     */
    private void processObservation(ORU_R01_OBSERVATION r01Observation, Result entity, Long obrId) {
        String resultsCultivation = null;
        String cultivationName = null;
        String resultCode = null;
        String resultName = null;

        int index = 0;
        for (Varies varies : r01Observation.getOBX().getObservationValue()) {
            if (varies.getData() instanceof CE) {
                CE ceData = (CE) varies.getData();
                if (index == 0) {
                    resultCode = ceData.getIdentifier().getValue();
                    resultName = ceData.getText().getValue();
                } else if (index == 1) {
                    resultsCultivation = ceData.getIdentifier().getValue();
                    cultivationName = ceData.getText().getValue();
                }
            }
            index++;
        }

        String result = r01Observation.getOBX().getReferencesRange().getValue();
        String dataType = r01Observation.getOBX().getValueType().getValue();
        String obsClassification = r01Observation.getOBX().getUserDefinedAccessChecks().getValue();

        entity.setResult(result);
        entity.setObrId(obrId);
        entity.setMecTechObsProject(resultCode);
        entity.setMecTechObsName(resultName);
        entity.setObsProjectDetail(resultsCultivation);
        entity.setProjectInfo(cultivationName);
        entity.setDataType(dataType);
        entity.setObsClassification(obsClassification);


        // 保存NTE段
        microbialReportService.saveNotesForOBX(r01Observation,obrId);
    }
}
