package com.ann.demo.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.ann.demo.entity.constant.AliasName;
import com.ann.demo.entity.constant.InterfaceName;
import com.ann.demo.entity.constant.WebServiceInfoMap;
import com.ann.demo.entity.constant.WebserviceId;
import com.ann.demo.entity.filing.MessageSubordinate;
import com.ann.demo.entity.filing.WebserviceInfo;
import com.ann.demo.entity.filing.dto.MessageDto;
import com.ann.demo.entity.filing.dto.PatientMainDto;
import com.ann.demo.entity.interfaceEntity.*;
import com.ann.demo.entity.other.RunningItem;
import com.ann.demo.entity.other.ServerHelper;
import com.ann.demo.repository.ArchiveMasterRepository;
import com.ann.demo.repository.MessageExtendRepository;
import com.ann.demo.utils.XMLUtils;
import com.ann.demo.utils.XmlUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.thymeleaf.util.StringUtils;
import org.w3c.dom.Node;

import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;

/**
 * 解析逻辑
 *
 * @Author: LeiJiaXin
 * @Date: 2019/8/20 16:29
 */
@Component
public class AnalysisService {

    static final Logger logger = LoggerFactory.getLogger(AnalysisService.class);

    @Autowired
    MessageService messageService;

    @Autowired
    MessageSubordinateService messageSubordinateService;

    @Autowired
    ArchiveMasterRepository archiveMasterRepository;

    @Autowired
    ExamApplyService examApplyService;

    @Autowired
    MessageExtendRepository messageExtendRepository;

    /**
     * 2019-7-8
     *
     * @Param xmlStr 需要解析的字符串
     * @Param tClass 被解析字符串的实体类
     * @Param parameter 如果是报告 携带参数
     * 返回返回参数xml
     */
    public String getHIPMessageServerResult(String message, Class tClass, String parameter,String webserviceId) throws Exception {
        long startTime = System.currentTimeMillis();
        String textContent = "成功啦~", type = "", typeCodeValue = "AE", outContent = "", patientMainStr = "",archiveMasterId = null;
        Date xmlCreateTime = null;
        MessageLog messageLog = null;
        Integer result = 0;
        long endTime = 0;

        message = message.replaceAll("&amp;", "&");

        // 判断是否插入
        messageLog = new MessageLog(message, InterfaceName.HIP_MESSAGE_SERVER, new Date(),webserviceId);
        // 只要没有传过 才会插入新的
        messageService.save(messageLog);
        MessageDto messageDto = XMLUtils.xpathToBean(message, tClass, parameter);
        if (messageDto != null) {
            String textContentTemp = null;
            if(StringUtils.isEmpty(messageDto.getVisitId()) && Objects.equals(messageDto.getType(),AliasName.PETCT_REPORT)){
                //如果是pet-ct报告 那么还要查出住院次数
                UltrasonicReport ultrasonicReport = JSON.parseObject(messageDto.getObject().toString(), UltrasonicReport.class);
                String authorReportTime = ultrasonicReport.getAuthorReportTime();
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
                Date date = simpleDateFormat.parse(authorReportTime, new ParsePosition(0));
                String visitId = archiveMasterRepository.findVisitIdByTimeAndInpNo(date, messageDto.getInpNo());
                messageDto.setVisitId(visitId);
            }
            archiveMasterId = messageService.getArchiveMasterId(messageDto.getInpNo(), messageDto.getVisitId(),messageDto.getPatientId());
            if(StringUtils.isEmpty(archiveMasterId) && "125".equals(messageDto.getType())){
                archiveMasterId = messageService.getArchiveMasterId(messageDto.getInpNo(),messageDto.getPatientId());
            }
            if(archiveMasterId != null){
                if (Objects.equals(messageDto.getEntity(), ExamApply.class.getName())) { // 申请单
                    //设置骨密度的需要值，存进extend_value字段里
                    if("125".equals(messageDto.getType())){
                        setExtendValue(message, archiveMasterId);
                    }
                    ExamApply examApply = JSON.parseObject(messageDto.getObject().toString(), ExamApply.class);
                    textContentTemp = changeApply(examApply,parameter);
                }

                // 保存消息从属表
                patientMainStr = JSON.toJSONString(new PatientMainDto(messageDto.getInpNo(), messageDto.getVisitId()), SerializerFeature.WriteMapNullValue);
                if (textContentTemp != null) {
                    textContent = textContentTemp;
                } else {
                    xmlCreateTime = messageDto.getXmlCreateTime();
                    type = messageDto.getType();
                    typeCodeValue = "AA";
                    result = 1;
                }
            }else{
                textContent = "没有入院消息";
            }
        } else {
            textContent = "传过来的消息无法解析";
        }

        outContent = XMLUtils.generateV3XmlStr(typeCodeValue, textContent);
        if (!outContent.equals("")) {
            endTime = System.currentTimeMillis();
            messageLog.setValue(archiveMasterId,outContent, result, messageDto == null ? "" : JSON.toJSONString(messageDto), xmlCreateTime, (endTime - startTime), new Date(), type, textContent);
            messageService.save(messageLog);
            if (Objects.equals(typeCodeValue, "AA")) {
                if (Objects.equals(type, AliasName.EKG_REPORT)
                        || Objects.equals(type, AliasName.PATHOLOGY_REPORT)
                        || Objects.equals(type, AliasName.RADIATION_REPORT)
                        || Objects.equals(type, AliasName.ULTRASONIC_REPORT)
                        || Objects.equals(type, AliasName.PETCT_REPORT )
                        || Objects.equals(type, AliasName.OTHER_REPORT)) {
                    messageSubordinateService.save(new MessageSubordinate(messageLog.getId(), patientMainStr, JSON.toJSONString(messageLog)));
                }
            }
        }
        logger.info("-----------------------检查报告" + type + "总用时长" + (endTime - startTime) + "-------------------------");
        return outContent;
    }

    /**
     * 骨密度需要增加的值
     * @param masterId
     * @param message
     */
    private void setExtendValue(String message,String masterId) {
        XmlUtil xmlUtil = XmlUtil.of(message);
        Node node = xmlUtil.getNode("/POOR_IN200901UV/controlActProcess/subject/placerGroup/component2/observationRequest/component2/observationRequest/AccessionNo/@value");
        if(null != node) {
            String textContent = node.getTextContent();
            if (!StringUtils.isEmpty(textContent) && textContent.startsWith("OT")) {
                MessageExtend messageExtend = new MessageExtend();
                messageExtend.setMasterId(masterId);
                messageExtend.setType(1);
                messageExtend.setExtendValue(textContent);
                messageExtendRepository.save(messageExtend);
            }
        }
    }




    private String changeApply(ExamApply examApply,String interfaceName)  throws Exception{
        String textContent = null;
        ExamApply examApplyTemp = examApplyService.findExamApply(examApply.getApplyId());
        //1 先判断检验申请单是否存在 存在做以下操作
        if(examApplyTemp != null){
            if (Objects.equals(examApply.getResult(), "delete")) {
                // 1.2 判断是否是删除
                if (!examApplyService.updateExamApplyIsValid(examApplyTemp.getApplyId())) {
                    textContent = "申请单删除失败了";
                }
            }else if(Objects.equals(interfaceName,InterfaceName.PARAMETER_EXAMAPPLYSTATECHANGE)){
                // 1.3 如果是检查申请单状态变更设置IsOpenHIS
                if (Objects.equals(examApply.getIsOpenHis(), "F")) {
                    examApplyTemp.setIsValid(1);
                    examApplyTemp.setIsOpenHis("F");
                    examApplyService.save(examApplyTemp);
                }
            }else if(Objects.equals(interfaceName,InterfaceName.PARAMETER_VERIFICATIONEXAMAPPLY)){
                // 1.4 如果是检查申请单检体验收设置IsOpenLIS
                if (Objects.equals(examApply.getIsOpenOther(), "F")) {
                    examApplyTemp.setIsValid(1);
                    examApplyTemp.setIsOpenOther("F");
                    examApplyService.save(examApplyTemp);
                }
            }else {
                // 1.5 如果存在，又不做任何操作，返回已存在
                textContent = "该申请单已存在";
            }
        }else{
            // 2 如果不存在，那就判断是否是新增，否则该申请单不存在
            if (Objects.equals(examApply.getResult(), "new") && Objects.equals(interfaceName,InterfaceName.PARAMETER_EXAMAPPLY)) {
                if (examApply.getReportType() != null) {
                    switch (examApply.getReportType()) {
                        case "病理":
                            examApply.setReportType(AliasName.PATHOLOGY_REPORT);
                            break;
                        case "超声":
                            examApply.setReportType(AliasName.ULTRASONIC_REPORT);
                            break;
                        case "心电":
                            examApply.setReportType(AliasName.EKG_REPORT);
                            break;
                        case "放射":
                            examApply.setReportType(AliasName.RADIATION_REPORT);
                            break;
                        case "核医学":
                            examApply.setReportType(AliasName.PETCT_REPORT);
                            break;
                        default:
                            //除了这5个 其他报告都归在一类
                            examApply.setReportType(AliasName.OTHER_REPORT);
                            break;
//                        case "肌电图":
//                            examApply.setReportType(AliasName.ELECTROMYOGRAPHY);
//                            break;
//                        case "临床试验":
//                            examApply.setReportType(AliasName.CLINICAL_TRIALS);
//                            break;
//                        case "内镜":
//                            examApply.setReportType(AliasName.ENDOSCOPIC_REPORT);
//                            break;
//                        case "脑彩超":
//                            examApply.setReportType(AliasName.BRAIN_COLOR_ULTRASOUND);
//                            break;
//                        case "脑电图":
//                            examApply.setReportType(AliasName.BRAIN_ELECTRIC_REPORT);
//                            break;
                    }
                }
                examApplyService.save(examApply);
            } else {
                textContent = "该申请单不存在";
            }
        }
        return textContent;
    }
}
