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

import ca.uhn.hl7v2.model.Message;
import ca.uhn.hl7v2.model.v24.message.*;
import ca.uhn.hl7v2.model.v24.segment.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.web.work.hl7.service.*;
import com.ruoyi.web.work.hl7.util.DateTimeConverter;
import com.ruoyi.web.work.domain.Patient;
import com.ruoyi.web.work.hl7.response.ResponseSuccessful;
import com.ruoyi.web.work.mapper.PatientMapper;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 患者信息
 */
@Log4j2
@Service("HL7PatientService")
@Transactional
public class HL7PatientServiceImpl extends ServiceImpl<PatientMapper, Patient> implements HL7PatientService {

    @Autowired
    private HL7VisitService visitService;

    @Autowired
    private HL7DiagnosisService dg1Service;

    @Autowired
    private HL7NextOfKinService kinShipService;

    @Autowired
    HL7ReportService orcReportService; //申请报告单

    @Override
    public Message savePatientInfo(Message message) throws Exception {
        if (message instanceof ADT_A01){
            ADT_A01 a01 = (ADT_A01) message;
            PID pid = a01.getPID();  //提取患者信息
            EVN evn = a01.getEVN();  //提取事件类型
            PV1 pv1 = a01.getPV1();  //提取就诊信息
            PV2 pv2 = a01.getPV2();  //提取pv2就诊补充信息
            List<DG1> dg1All = a01.getDG1All(); //提取患者的诊断信息
            //ADT_A01 ADT_A04 ADT_A08 走a01消息模型
            String msgType = evn.getEventTypeCode().getValue(); //消息类型
            String wnPatId = pid.getPatientID().getID().getValue(); //卫宁患者ID
            //保存患者入院
            if ("A01".equals(msgType)){
                //根据卫宁患者ID查询患者
                Patient patient = findPatientByWnPatId(wnPatId);
                if (patient != null){
                    Long id = patient.getId(); //患者Id
                    //保存患者新的就诊信息tb_visit
                    visitService.saveVisitInfo(dg1All,pv1,pv2, id);
                }else {
                    //保存当前患者基本信息
                    log.info("A01消息类型>>>>>保存本次患者入院的信息");
                    Long PatId = SavePatientInfo(pid, evn);//保存患者基本信息  PatId患者Id
                    //保存本次就诊信息
                    visitService.saveVisitInfo(dg1All,pv1,pv2,PatId);
                    //保存亲属关系表数据
                    kinShipService.saveKinShipInfo(PatId,a01);
                }
                return ResponseSuccessful.ResponseADTA01Msg(a01);
            }
            if ("A08".equals(msgType)){
                //根据卫宁患者ID查询患者
                Patient patient = findPatientByWnPatId(wnPatId);
                if (patient != null) {
                    // 更新患者信息 tb_patient
                    String evenType = evn.getEventReasonCode().getValue();  //住院业务类型
                    String phone = pid.getPhoneNumberHome(0).getPhoneNumber().getValue(); //电话
                    String address = pid.getPatientAddress(0).getStreetAddress().getStreetOrMailingAddress().getValue(); //患者地址
                    String workPhone = pid.getPhoneNumberBusiness(0).getPhoneNumber().getValue(); //工作电话
                    String nation = pid.getEthnicGroup(0).getText().getValue(); //民族
                    String career = pid.getCitizenship(0).getText().getValue(); //职业
                    String nationality = pid.getNationality().getText().getValue(); //国籍
                    if (patient.getWorkPhone() == null){
                        patient.setWorkPhone(workPhone);
                    }
                    if (patient.getNation() == null){
                        patient.setNation(nation);
                    }
                    if (patient.getCareer() == null){
                        patient.setCareer(career);
                    }
                    if (patient.getNationality() == null){
                        patient.setNationality(nationality);
                    }
                    if (patient.getAddress() == null){
                        patient.setAddress(address);
                    }
                    if (patient.getPhone() == null){
                        patient.setPhone(phone);
                    }
                    patient.setEventType(evenType); //住院业务类型
                    baseMapper.updateById(patient);

                    // 获取患者ID
                    Long patId = patient.getId();

                    // 修改tb_visit表
                    visitService.updateVisitInfoByPatId(dg1All, patId, pv1, pv2);
                }
                return ResponseSuccessful.ResponseADTA01Msg(a01);
            }
        }
        if (message instanceof ORU_R01){
            log.info("开始执行对患者报告的检验数据进行入库");
            ORU_R01 oruR01 = (ORU_R01) message;
            //保存报告单
            orcReportService.savePatientReport(oruR01);
            return ResponseSuccessful.ResponseORUR01Msg(oruR01);
        }
        if (message instanceof ADT_A03) {
            log.info("患者出院更新在院状态、出院时间、出院方式");
            ADT_A03 a03 = (ADT_A03) message;
            PV1 pv1 = a03.getPV1(); //提取患者信息段
            PID pid = a03.getPID(); //提取患者的信息段
            EVN evn = a03.getEVN(); //提取患者的事件类型
            List<DG1> dg1All = a03.getDG1All(); //提取患者的诊断信息
            String patClass = pv1.getPatientClass().getValue(); //患者类别 O：门诊、I、住院
            if ("I".equals(patClass)) {
                // 住院患者出院 更新住院业务类型
                String wnPatId = pid.getPatientID().getID().getValue(); //卫宁患者ID
                // 根据卫宁患者ID查询患者
                Patient patient = findPatientByWnPatId(wnPatId);
                if (patient != null) {
                    String evenType = evn.getEventReasonCode().getValue(); //住院业务类型
                    patient.setEventType(evenType);
                    baseMapper.updateById(patient);
                    Long dbPid = patient.getId();  //患者ID
                    //更新患者就诊记录的在院状态、出院时间、出院方式
                    Long visitId = visitService.updateVisitHospitalStatus(dbPid, pv1);
                    //保存诊断信息
                    dg1Service.saveDiagnosisInfo(dg1All,visitId,pv1,dbPid);
                }
                return ResponseSuccessful.ResponseADTA03Msg(a03);
            }
        }
        return null;
    }

    //根据卫宁患者ID查询患者
    public Patient findPatientByWnPatId(String wnPatId) {
        LambdaQueryWrapper<Patient> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Patient::getWnPatId, wnPatId);
        return baseMapper.selectOne(wrapper);
    }

    /**
     * 保存患者的基本信息
     * @param pid
     * @param evn
     * @return
     */
    private Long SavePatientInfo(PID pid,EVN evn){
        String evenTime = evn.getRecordedDateTime().getTimeOfAnEvent().getValue();  //触发时间
        String evenType = evn.getEventReasonCode().getValue(); //住院业务类型
        String patientID = pid.getPatientID().getID().getValue(); //卫宁患者ID
        String patientCode = pid.getPatientIdentifierList(0).getID().getValue(); //患者标识符
        String patientName = pid.getPatientName(0).getFamilyName().getSurname().getValue();//患者姓名
        String strBirthTime = pid.getDateTimeOfBirth().getTimeOfAnEvent().getValue(); //出生时间
        String sex = pid.getAdministrativeSex().getValue(); //性别
        String address = pid.getPatientAddress(0).getStreetAddress().getStreetOrMailingAddress().getValue(); //患者地址
        String phone = pid.getPhoneNumberHome(0).getPhoneNumber().getValue(); //电话
        String workPhone = pid.getPhoneNumberBusiness(0).getPhoneNumber().getValue(); //工作电话
        String marital = pid.getMaritalStatus().getIdentifier().getValue(); //婚姻状况
        String nation = pid.getEthnicGroup(0).getText().getValue(); //民族
        String career = pid.getCitizenship(0).getText().getValue(); //职业
        String nationality = pid.getNationality().getText().getValue(); //国籍
        String BLH = pid.getPatientIdentifierList(1).getID().getValue(); //病历号
        String BRKH = pid.getPatientIdentifierList(2).getID().getValue(); //病人卡号
        String SFZH = pid.getPatientIdentifierList(3).getID().getValue(); //身份证号
        String YEXH = pid.getPatientIdentifierList(4).getID().getValue(); //婴儿序号

        Patient entity = new Patient();
        //患者信息
        String strEvenTime = DateTimeConverter.convertToUnifiedFormat(evenTime);
        entity.setEventTime(strEvenTime); //触发时间
        entity.setEventType(evenType); //住院业务类型
        entity.setBlh(BLH);
        entity.setBrkh(BRKH);
        entity.setSfzh(SFZH);
        entity.setYexh(YEXH);
        entity.setWnPatId(patientID);
        entity.setPatientCode(patientCode);
        entity.setName(patientName);
        String birthTime = DateTimeConverter.convertToUnifiedFormat(strBirthTime);
        entity.setBirthDate(birthTime);
        entity.setSex(sex);
        entity.setAddress(address);
        entity.setPhone(phone);
        entity.setWorkPhone(workPhone);
        entity.setMarital(marital);
        entity.setNation(nation);
        entity.setCareer(career);
        entity.setNationality(nationality);
        baseMapper.insert(entity);
        return entity.getId();
    }
}
