package com.docus.server.message.rpc.impl;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.docus.core.util.DateUtil;
import com.docus.core.util.Func;
import com.docus.server.message.config.SdRyReportQueryConfig;
import com.docus.server.message.config.ShunDePeopleInterfaceConfig;
import com.docus.server.message.rpc.ShunDePeopleRpc;
import com.docus.server.message.rpc.request.HisZyCyYzRequest;
import com.docus.server.message.rpc.response.HisZyCyYzResponse;
import com.docus.server.message.util.HttpUrlUtil;
import com.docus.server.message.util.IdUtil;
import com.docus.server.message.util.JaxWsDynamicClient;
import com.docus.server.message.util.XmlUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 顺德人医远程调用实现
 * @author wyb
 */
@Slf4j
@Service
public class ShunDePeopleRpcImpl implements ShunDePeopleRpc {
    @Resource
    private SdRyReportQueryConfig sdRyReportQueryConfig;

    @Override
    public HisZyCyYzResponse hisZyCyYz(HisZyCyYzRequest request) {
        ShunDePeopleInterfaceConfig.InterfaceConfig interfaceConfig = ShunDePeopleInterfaceConfig.getTaskConfig("HIS_ZY_CYYZ");
        if(interfaceConfig==null){
            log.warn("查询住院出院医嘱接口未配置！");
            return null;
        }
        // 组织url
        String standardUuId = IdUtil.standardUUID();
        String timeMini = DateUtil.formatDateTimeMini(LocalDateTime.now());
        Map<String, String> otherParam = interfaceConfig.getOtherParam();
        otherParam.put("uuid",standardUuId);
        otherParam.put("creationTime",timeMini);
        String url = HttpUrlUtil.addUrlParam(interfaceConfig.getUrl(), otherParam);
        try {
            log.info("[{}]:查询住院出院医嘱接口地址:{}",standardUuId,url);
            String resp = HttpUtil.post(url, JSON.toJSONString(request));
            log.info("[{}]:查询住院出院医嘱接口返回值：{}",standardUuId,resp);
            return JSON.parseObject(resp, new TypeReference<HisZyCyYzResponse>() {
            });
        }catch (Exception ex){
            log.error("["+standardUuId+"]:"+"查询住院出院医嘱接口出错啦！===》"+ex.getMessage(),ex);
            return null;
        }
    }

    @Override
    public byte[] getBloodReport(String fileName) {
        ShunDePeopleInterfaceConfig.InterfaceConfig interfaceConfig = ShunDePeopleInterfaceConfig.getTaskConfig("BLOOD");
        if(interfaceConfig==null){
            log.warn("查询输血报告文件接口未配置！");
            return null;
        }
        Map<String, String> otherParam = interfaceConfig.getOtherParam();
        String url = interfaceConfig.getUrl() + "?file_folder=TmisPdfFile&file_name=" + fileName;
//        String url = "http://192.168.16.63:9314/blood/1_out.pdf";
        return HttpUtil.createGet(url)
                .header("Content-Type", "application/octet-stream")
                .header("HQ_TOKEN", otherParam.get("hqToken"))
                .header("HQ_METHOD", otherParam.get("hqMethod"))
                .execute().bodyBytes();
    }

    @Override
    public List<String> getSdRyMzReportJxIds(String sdRyIndex) {

            List<String> indexes = new ArrayList<>();
            try {
                String mzParam = organizationQuerySdRyReportIndexParam(sdRyIndex, 1);
                String[] mzParams = {"HIP1179", mzParam};
                return getSdRyReportJxIds(mzParams);
            } catch (Exception ex) {
                log.error(ex.getMessage(), ex);
            }
            return indexes;

    }
    /**
     * 组织顺德人医查询交叉索引的请求参数
     *
     * @param sDryIndex 顺德人医关联索引
     * @param type      1:门诊 3:住院
     * @return 顺德人医查询交叉索引的请求参数
     */
    private String organizationQuerySdRyReportIndexParam(String sDryIndex, int type) {
        sDryIndex = sDryIndex.toLowerCase()
                .replace("m", "")
                .replace("z", "");
        String receiver = "Orion-001";
        String sender = "PaperlessManagementMRIS-001";
        String now = Func.format(new Date(), DateUtil.PATTERN_DATETIME_MINI);

        return "<PRPA_HIP1179 xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ITSVersion=\"XML_1.0\" xmlns=\"urn:hl7-org:v3\" xsi:schemaLocation=\"urn:hl7-org:v3 ../multicacheschemas/PRPA_IN201306UV02.xsd\">\n" +
                "\t<id root=\"2.16.156.10011.0\" extension=\"" + IdUtil.standardUUID() + "\"/>\n" +
                "\t<creationTime value=\"" + now + "\"/>\n" +
                "\t<interactionId root=\"2.16.840.1.113883.1.6\" extension=\"PRPA_IHIP1179\"/>\n" +
                "\t<processingCode code=\"P\"/>\n" +
                "\t<processingModeCode/>\n" +
                "\t<acceptAckCode code=\"AL\"/>\n" +
                "\t<receiver typeCode=\"RCV\">\n" +
                "\t\t<telecom/>\n" +
                "\t\t<device classCode=\"DEV\" determinerCode=\"INSTANCE\">\n" +
                "\t\t\t<id>\n" +
                "\t\t\t\t<item root=\"2.16.156.10011.0.1.1\" extension=\"" + receiver + "\"/>\n" +
                "\t\t\t</id>\n" +
                "\t\t</device>\n" +
                "\t</receiver>\n" +
                "\t<sender typeCode=\"SND\">\n" +
                "\t\t<telecom/>\n" +
                "\t\t<device classCode=\"DEV\" determinerCode=\"INSTANCE\">\n" +
                "\t\t\t<id>\n" +
                "\t\t\t\t<item root=\"2.16.156.10011.0.1.2\" extension=\"" + sender + "\"/>\n" +
                "\t\t\t</id>\n" +
                "\t\t</device>\n" +
                "\t</sender>\n" +
                "\t<controlActProcess classCode=\"CACT\" moodCode=\"EVN\">\n" +
                "\t\t<code code=\"empiIndexQuery\">\n" +
                "\t\t\t<displayName value=\"交叉索引查询\"/>\n" +
                "\t\t</code>\n" +
                "\t\t<queryByParameter>\n" +
                "\t\t\t<!-- 查询条件：type：类型 value：值 -->\n" +
                "\t\t\t<!--type 1:患者id 2:身份证 3::电子健康码-->\n" +
                "\t\t\t<queryParam type=\"1\" value=\"" + sDryIndex + "\"/>\n" +
                "\t\t\t<!--1:门诊 3:住院-->\n" +
                "\t\t\t<visitType type=\"" + type + "\"/>\n" +
                "\t\t</queryByParameter>\n" +
                "\t</controlActProcess>\n" +
                "</PRPA_HIP1179>\n";
    }
    private List<String> getSdRyReportJxIds(String[] qrIndexParams) {
        List<String> indexes = new ArrayList<>();
        try {
            List<String> zyIndex = getIndex(qrIndexParams);
            indexes.addAll(zyIndex);
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
        return indexes;
    }
    private List<String> getIndex(String[] params) {
        try {
            String namespaceUri = sdRyReportQueryConfig.getQueryReportIndexWsdlNamespaceUri();
            String wsdlAddr = sdRyReportQueryConfig.getQueryReportIndexWsdlAddr();
            String operationName = sdRyReportQueryConfig.getQueryReportIndexWsdlOperationName();
            String result = JaxWsDynamicClient.send(wsdlAddr, namespaceUri, operationName, params);
            log.info("查询顺德人医患者交叉索引数据，返回值：{}", result);
            if (result == null) {
                return new ArrayList<>();
            }
            return parseQuerySdRyReportIndex(result);
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
            return new ArrayList<>();
        }
    }
    private List<String> parseQuerySdRyReportIndex(String result) {
        try {
            XmlUtil xmlUtil = XmlUtil.of(result);
            NodeList nodeList = xmlUtil.getNodeList("/PRPA_HIP1179/controlActProcess/subject/empiIndex/patientIds/patientId");
            int nodeListLength = nodeList.getLength();
            ArrayList<String> patientIds = new ArrayList<>();
            if (nodeListLength > 0) {
                for (int i = 0; i < nodeListLength; i++) {
                    Node node = nodeList.item(i);
                    String patientId = node.getTextContent();
                    if (Func.isNotBlank(patientId)) {
                        patientIds.add(patientId);
                    }
                }
            }
            return patientIds;
        } catch (Exception ex) {
            log.error("顺德人医解析患者交叉索引失败。", ex);
            return new ArrayList<>();
        }
    }
    public static void main(String[] args) {

    }
}
