package com.yihu.wlyy.service.third.guahao;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.yihu.wlyy.entity.patient.Patient;
import com.yihu.wlyy.entity.patient.PatientReservation;
import com.yihu.wlyy.entity.patient.SignFamily;
import com.yihu.wlyy.repository.organization.HospitalMappingDao;
import com.yihu.wlyy.repository.patient.PatientReservationDao;
import com.yihu.wlyy.repository.patient.SignFamilyDao;
import com.yihu.wlyy.service.app.consult.ConsultService;
import com.yihu.wlyy.service.common.account.PatientService;
import com.yihu.wlyy.service.third.httplog.LogService;
import com.yihu.wlyy.service.third.jw.JwSmjkService;
import com.yihu.wlyy.util.DateUtil;
import com.yihu.wlyy.util.SOAPUtil;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by hzp on 2016/8/13.
 * 厦门市民健康网挂号服务
 */
@Service
public class GuahaoXMService implements IGuahaoService {

    private int nextDays = 8;  //一周内预约号
    private String ORG_LIST = "GetOrgListNew";//获取医院列表
    private String DEP_LIST = "GetDeptListByOrg"; //科室列表
    private String DOCTOR_LIST = "GetRegDeptDoctorList"; //医生列表
    private String DOCTOR_ARRANGE = "GetRegDeptDoctorSectionList"; //医生排班列表
    private String DOCTOR_ARRANGE_SIMPLE = "GetDoctorSectionSimpleList"; //医生排班列表
    private String ORDER_CREATE = "WebRegisterVerify";  //新建预约
    private String ORDER_CANCEL = "Unregister";   //取消预约
    private String ORDER_INFO = "GetReservationRecord";//预约信息
    private String REG_LIST = "GetRegList";//获取市民预约挂号信息

    @Autowired
    private PatientService patientService;

    @Autowired
    private HospitalMappingDao hospitalMappingDao;

    @Autowired
    private PatientReservationDao patientReservationDao;

    @Autowired
    SignFamilyDao signFamilyDao;

    @Autowired
    private LogService logService;

    @Autowired
    private ConsultService consultService;

    private ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 解析挂号后
     */
    private String CreateOrderAfter(String response, String hospitalId, String hospitalName, String hosDeptId, String hosDeptName, String doctorId, String doctorName, String sectionType, String startTime, String endTime, String patient, String patientName, String cardNo, String clinicCard, String patientPhone, String dname, String dcode) throws Exception {
        String code = "";
        if (response.startsWith("error") || response.startsWith("System-Error")) {
            throw new Exception(response);
        } else if (response.toLowerCase().startsWith("ok")) {      //预约成功
            // 预约成功,获取预约号
            code = response.replace("OK:", "").replace("ok:", "");
        } else if (response.split("\\|").length == 3) {
            code = response.split("\\|")[0];
        } else {
            throw new Exception(response);
        }

        // 查询医生职称和头像
        GuahaoDoctor doctor = GetDoctorInfo(doctorId, hospitalId, hosDeptId);
        // 保存预约记录
        PatientReservation reservation = new PatientReservation();
        reservation.setCode(code);
        reservation.setCzrq(new Date());
        reservation.setType("1");
        reservation.setOrgCode(hospitalId);
        reservation.setOrgName(hospitalName);
        reservation.setDeptCode(hosDeptId);
        reservation.setDeptName(hosDeptName);
        reservation.setDoctorCode(doctorId);
        reservation.setDoctorName(doctorName);
        reservation.setDoctorJob(doctor.getTitle());
        reservation.setDoctorPhoto(doctor.getPhoto());
        reservation.setIdcard(cardNo);
        reservation.setName(patientName);
        reservation.setPatient(patient);
        reservation.setPhone(patientPhone);
        reservation.setSectionType(sectionType);
        reservation.setSsc(clinicCard);
        reservation.setStartTime(DateUtil.strToDate(startTime,DateUtil.YYYY_M_D_HH_MM_SS));
        reservation.setEndTime(DateUtil.strToDate(endTime,DateUtil.YYYY_M_D_HH_MM_SS));
        reservation.setStatus(1);
        if (StringUtils.isNotEmpty(dcode)) {
            SignFamily signFamily = signFamilyDao.findByjiatingPatient(patient);
            if (signFamily == null) {
                throw new Exception("can not find patient's family sign info");
            }
            reservation.setSignType(2);
            reservation.setAdminTeamCode(signFamily.getAdminTeamId());
        }
        if (StringUtils.isNotBlank(dname)) {
            reservation.setDname(dname);//代理签约维护待签约人名称
        }
        if (StringUtils.isNotBlank(dcode)) {
            reservation.setDoctor(dcode);//代理签约维护待签约人编码

        }
        // 保存预约记录
        patientReservationDao.save(reservation);
        if(StringUtils.isNotBlank(dcode)){
            Patient p = patientService.findByCode(patient);
            consultService.sendMucMessageBySingnType(dcode,dname,patient,"我已成功为您预约：" + startTime + "，" + hospitalName + hosDeptName + doctorName + "医生的号源。您可直接前往医院就诊</br><a name='guahao' href='javascript:void(0)' data-id='" + reservation.getId() + "'>点击查看详情</a>","1",p.getName());
        }

        return code;
    }

    /**
     * 预约排班xml转列表
     */
    private List<Map<String, Object>> xmlToList(String xml) throws Exception {
        List<Map<String, Object>> re = new ArrayList<>();
        if (StringUtils.isEmpty(xml)) {
            // 请求失败
            throw new Exception("获取医生排班表失败！");
        } else if (StringUtils.startsWith(xml, "System-Error")) {
            // 调用失败
            throw new Exception(xml.substring(xml.indexOf(":") + 1, xml.length()));
        } else if (StringUtils.startsWith(xml, "Error")) {
            // 调用失败
            throw new Exception(xml.substring(xml.indexOf(":") + 1, xml.length()));
        }
        Document document = DocumentHelper.parseText(xml);
        Element root = document.getRootElement();
        if (root.element("doctor") != null)     //包含doctor节点
        {
            root = root.element("doctor");
        }
        List<?> child = root.elements();

        for (Object o : child) {
            Element e = (Element) o;
            // 日期
            String date = e.attributeValue("date");
            // a或者p
            String time = e.attributeValue("time");
            // 限号
            String max = e.attributeValue("max");
            // 已使用的号
            String used = e.attributeValue("used");
            // 1正常、2满号、3已过期
            String status = e.attributeValue("status");
            // 诊查费
            String fee = e.attributeValue("fee");
            Map<String, Object> map = new HashMap<>();
            map.put("date", date);
            map.put("time", time);
            map.put("max", max);
            map.put("used", used);
            map.put("status", status);
            map.put("fee", fee);
            // 排班信息
            List<?> sections = e.elements();
            List<Map<String, String>> arrangeList = new ArrayList<>();
            for (Object s : sections) {
                Element section = (Element) s;
                // 限号
                String s_max = section.attributeValue("max");
                // 已使用的号
                String s_used = section.attributeValue("used");
                // 一次专家坐诊时间段的开始时间
                String start_time = section.attributeValue("start_time");
                // 结束时间
                String end_time = section.attributeValue("end_time");

                Map<String, String> item = new HashMap<>();
                item.put("max", s_max);
                item.put("used", s_used);
                item.put("startTime", start_time);
                item.put("endTime", end_time);
                arrangeList.add(item);
            }
            map.put("sections", arrangeList);
            re.add(map);
        }

        return re;
    }


    /***********************************************************************************************************************************************/
    /**
     * xml验证，并保存日志
     * @param url
     * @param content
     * @param method
     * @param msgBody
     * @param res
     */
    private void  verificationXml(String xml,String title,String url,String content,String method,String msgBody,String res) throws Exception{
        String error = "";
        Boolean isSuccess = false;
        if (StringUtils.isEmpty(xml)) {
            // 请求失败
            //保存http日志
            error = title;
            logService.saveHttpLog(isSuccess,url,content,method,null,msgBody,res,error,logService.archiveType);
            throw new Exception(error);
        } else if (StringUtils.startsWith(xml, "System-Error")) {
            // 调用失败
            //保存http日志
            error = xml.substring(xml.indexOf(":") + 1, xml.length());
            logService.saveHttpLog(isSuccess,url,content,method,null,msgBody,res,error,logService.archiveType);
            throw new Exception(error);
        } else if (StringUtils.startsWith(xml, "Error")) {
            // 调用失败
            //保存http日志
            error = xml.substring(xml.indexOf(":") + 1, xml.length());
            logService.saveHttpLog(isSuccess,url,content,method,null,msgBody,res,error,logService.archiveType);
            throw new Exception(error);
        }
    }
    /**
     * 获取医院列表
     */
    public List<Map<String, String>> GetOrgList(String city, String filter, String type, Integer pageIndex, Integer pageSize) throws Exception {
        List<Map<String, String>> re = new ArrayList<>();

        String[] values = null;

        //医院列表
        if (type.equals("1")) {
            values = SOAPUtil.getCredential("<?xml version=\"1.0\" encoding=\"utf-8\"?><root type=\"1\"></root>", true);
        } else if (type.equals("2")) //社区列表
        {
            values = SOAPUtil.getCredential("<?xml version=\"1.0\" encoding=\"utf-8\"?><root type=\"2\"></root>", true);
        }

        if (values != null && values.length == 3) {
            JSONArray params = new JSONArray();

            JSONObject param1 = new JSONObject();
            param1.put("key", "?strCondition");
            param1.put("value", values[0]);
            params.put(param1);

            JSONObject param2 = new JSONObject();
            param2.put("key", "?strCredential");
            param2.put("value", values[1]);
            params.put(param2);

            JSONObject param3 = new JSONObject();
            param3.put("key", "?strKey");
            param3.put("value", values[2]);
            params.put(param3);

            //新增日志
            String method = "POST";
            String content = "获取医院列表";

            Long startTime = System.currentTimeMillis();
            String xml = SOAPUtil.post(ORG_LIST, params);
            Long spendTime = (System.currentTimeMillis()-startTime)/1000;//计算请求时间
            String res = "耗时："+spendTime+"s,xml="+xml;
            String msgBody = params.toString();
            //xml验证
            verificationXml(xml,"获取机构列表失败！",ORG_LIST,content,method,msgBody,res);

            Document document = DocumentHelper.parseText(xml);
            Element root = document.getRootElement();
            List<?> child = root.elements();
            for (Object o : child) {
                Element e = (Element) o;
                String shortName = e.attribute("short_name").getValue();
                String code = e.attribute("code").getValue();
                String name = e.getText();
                Map<String, String> map = new HashMap<>();
                map.put("id", code);
                map.put("name", shortName);
                map.put("address", name);
                String photo = hospitalMappingDao.getPhotoByMappingCode(code, "1");
                map.put("photo", photo);

                re.add(map);
            }

            //保存http日志
            logService.saveHttpLog(true,ORG_LIST,content,method,null,msgBody,res,null,logService.archiveType);
        }
        return re;
    }

    /**
     * 获取科室接口
     */
    public List<Map<String, String>> GetOrgDepList(String hospitalId, String filter, Integer pageIndex, Integer pageSize) throws Exception {
        List<Map<String, String>> re = new ArrayList<>();
        JSONArray params = new JSONArray();

        JSONObject param1 = new JSONObject();
        param1.put("key", "?orgCode");
        param1.put("value", hospitalId);
        params.put(param1);

        //新增日志
        String method = "POST";
        String content = "获取科室接口";
        Long startTime = System.currentTimeMillis();
        String xml = SOAPUtil.post(DEP_LIST, params);
        Long spendTime = (System.currentTimeMillis()-startTime)/1000;//计算请求时间
        String res = "耗时："+spendTime+"s,xml="+xml;
        String msgBody = params.toString();
        //xml验证
        verificationXml(xml,"获取可预约科室列表失败！",DEP_LIST,content,method,msgBody,res);

        Document document = DocumentHelper.parseText(xml);
        Element root = document.getRootElement();
        List<?> child = root.elements();
        for (Object o : child) {
            Element e = (Element) o;
            if (e.getName().equals("dept")) {
                String code = e.attribute("code").getValue();
                String name = e.attribute("name").getValue();
                Map<String, String> map = new HashMap<>();
                map.put("id", code);
                map.put("name", name);
                map.put("hospitalId", hospitalId);
                re.add(map);
            }
        }

        //保存http日志
        logService.saveHttpLog(true,DEP_LIST,content,method,null,msgBody,res,null,logService.archiveType);

        return re;
    }

    /**
     * 获取医生列表接口
     */
    public List<GuahaoDoctor> GetDoctorList(String hospitalId, String hosDeptId, String filter, Integer pageIndex, Integer pageSize) throws Exception {
        List<GuahaoDoctor> re = new ArrayList<>();
        JSONArray params = new JSONArray();

        JSONObject param1 = new JSONObject();
        param1.put("key", "?OrgCode");
        param1.put("value", hospitalId);
        params.put(param1);

        JSONObject param2 = new JSONObject();
        param2.put("key", "?DeptCode");
        param2.put("value", hosDeptId);
        params.put(param2);

        JSONObject param3 = new JSONObject();
        param3.put("key", "?strStart");
        String nowDate = DateUtil.getStringDateShort();   //当前时间;
        param3.put("value", nowDate);
        params.put(param3);

        JSONObject param4 = new JSONObject();
        param4.put("key", "?strEnd");
        param4.put("value", DateUtil.getNextDay(nowDate, nextDays));  //一周后时间
        params.put(param4);

        //新增日志
        String method = "POST";
        String content = "获取医生列表接口";
        Long startTime = System.currentTimeMillis();
        String xml = SOAPUtil.post(DOCTOR_LIST, params);
        Long spendTime = (System.currentTimeMillis()-startTime)/1000;//计算请求时间
        String res = "耗时："+spendTime+"s,xml="+xml;
        String msgBody = params.toString();
        //xml验证
        verificationXml(xml,"获取医生列表失败！",DOCTOR_LIST,content,method,msgBody,res);

        Document document = DocumentHelper.parseText(xml);
        Element root = document.getRootElement();
        List<?> child = root.elements();
        for (Object o : child) {
            Element e = (Element) o;
            // 医生编码
            String code = e.attributeValue("code");
            // 性别
            String sex = e.attributeValue("sex");
            // 职称
            String tech = e.attributeValue("tech");
            // 学历
            String edu = e.attributeValue("edu");
            // 简介
            String introduce = e.attributeValue("introduce");
            // 专家姓名
            String name = e.attributeValue("name");
            // 照片
            String photo = "";
            if (e.attribute("photo") != null) {
                photo = e.attributeValue("photo");
            }
            // 挂号费
            String fee = e.attributeValue("fee");
            // 科室编码
            String deptcode = e.attributeValue("deptcode");
            // 科室名称
            String deptname = e.attributeValue("deptname");
            // 机构编码
            String orgcode = e.attributeValue("orgcode");
            // 机构名称
            String orgname = e.attributeValue("orgname");
            GuahaoDoctor doctor = new GuahaoDoctor();
            doctor.setId(code);
            doctor.setName(name);
            doctor.setSex(sex);
            doctor.setTitle(tech);
            doctor.setEdu(edu);
            doctor.setIntroduce(introduce);
            doctor.setPhoto(photo);
            doctor.setFee(fee);
            doctor.setHosDeptId(deptcode);
            doctor.setHosDeptName(deptname);
            doctor.setHospitalId(orgcode);
            doctor.setHospitalName(orgname);
            re.add(doctor);
        }

        //保存http日志
        logService.saveHttpLog(true,DOCTOR_LIST,content,method,null,msgBody,res,null,logService.archiveType);

        return re;
    }

    /**
     * 获取医生排班接口(包含排班详细)
     * status 0 停诊、1正常、2满号、3已过期
     */
    public List<Map<String, Object>> GetDoctorArrange(String hospitalId, String hosDeptId, String doctorId) throws Exception {

        JSONArray params = new JSONArray();
        JSONObject param1 = new JSONObject();
        param1.put("key", "?OrgCode");
        param1.put("value", hospitalId);
        params.put(param1);

        JSONObject param2 = new JSONObject();
        param2.put("key", "?DeptCode");
        param2.put("value", hosDeptId);
        params.put(param2);

        JSONObject param3 = new JSONObject();
        param3.put("key", "?DocCode");
        param3.put("value", doctorId);
        params.put(param3);

        JSONObject param4 = new JSONObject();
        param4.put("key", "?strStart");
        String nowDate = DateUtil.getStringDateShort();   //当前时间;
        param4.put("value", nowDate);
        params.put(param4);

        JSONObject param5 = new JSONObject();
        param5.put("key", "?strEnd");
        param5.put("value", DateUtil.getNextDay(nowDate, nextDays));  //一周后时间
        params.put(param5);

        //新增日志
        String method = "POST";
        String content = "获取医生排班接口(包含排班详细)";
        Long startTime = System.currentTimeMillis();
        String xml = SOAPUtil.post(DOCTOR_ARRANGE, params);
        Long spendTime = (System.currentTimeMillis()-startTime)/1000;//计算请求时间
        String res = "耗时："+spendTime+"s,xml="+xml;
        String msgBody = params.toString();
        //xml验证
        verificationXml(xml,"获取医生排班表失败！",DOCTOR_ARRANGE,content,method,msgBody,res);

        //保存http日志
        logService.saveHttpLog(true,DOCTOR_ARRANGE,content,method,null,msgBody,res,null,logService.archiveType);

        return xmlToList(xml);
    }

    /**
     * 获取医生排班接口（一级）
     * status 0 停诊、1正常、2满号、3已过期
     */
    public List<Map<String, String>> GetDoctorArrangeSimple(String hospitalId, String hosDeptId, String doctorId) throws Exception {
        List<Map<String, String>> re = new ArrayList<>();

        JSONArray params = new JSONArray();
        JSONObject param1 = new JSONObject();
        param1.put("key", "?OrgCode");
        param1.put("value", hospitalId);
        params.put(param1);

        JSONObject param2 = new JSONObject();
        param2.put("key", "?DeptCode");
        param2.put("value", hosDeptId);
        params.put(param2);

        JSONObject param3 = new JSONObject();
        param3.put("key", "?DocCode");
        param3.put("value", doctorId);
        params.put(param3);

        JSONObject param4 = new JSONObject();
        param4.put("key", "?strStart");
        String nowDate = DateUtil.getStringDateShort();   //当前时间;
        param4.put("value", nowDate);
        params.put(param4);

        JSONObject param5 = new JSONObject();
        param5.put("key", "?strEnd");
        param5.put("value", DateUtil.getNextDay(nowDate, nextDays));  //一周后时间
        params.put(param5);

        //新增日志
        String method = "POST";
        String content = "获取医生排班接口（一级）";
        Long startTime = System.currentTimeMillis();
        String xml = SOAPUtil.post(DOCTOR_ARRANGE_SIMPLE, params);
        Long spendTime = (System.currentTimeMillis()-startTime)/1000;//计算请求时间
        String res = "耗时："+spendTime+"s,xml="+xml;
        String msgBody = params.toString();
        //xml验证
        verificationXml(xml,"获取医生排班表失败！",DOCTOR_ARRANGE_SIMPLE,content,method,msgBody,res);

        Document document = DocumentHelper.parseText(xml);
        Element root = document.getRootElement();
        List<?> child = root.elements();
        for (Object o : child) {
            Element e = (Element) o;
            // 日期
            String date = e.attributeValue("date");
            // a或者p
            String time = e.attributeValue("time");
            // 限号
            String max = e.attributeValue("max");
            // 已使用的号
            String used = e.attributeValue("used");
            // 1正常、2满号、3已过期
            String status = e.attributeValue("status");
            Map<String, String> map = new HashMap<>();
            map.put("date", date);
            map.put("time", time);
            map.put("max", max);
            map.put("used", used);
            map.put("status", status);  //0 停诊、1正常、2满号、3已过期

            re.add(map);
        }

        //保存http日志
        logService.saveHttpLog(true,DOCTOR_ARRANGE_SIMPLE,content,method,null,msgBody,res,null,logService.archiveType);

        return re;
    }

    /**
     * 创建挂号单
     */
    public String CreateOrder(String hospitalId, String hospitalName, String hosDeptId, String hosDeptName, String doctorId, String doctorName, String arrangeDate, String patient, String patientName, String cardNo, String clinicCard, String patientPhone) throws Exception {
        String re = "";

        Patient p = patientService.findByCode(patient);
        if (p == null) {
            throw new Exception("患者信息不存在！");
        }

        Map<String, String> map = objectMapper.readValue(arrangeDate, Map.class);
        if (map.containsKey("sectionType") && map.containsKey("startTime")) {
            String sectionType = map.get("sectionType");
            String startTime = map.get("startTime");
            String endTime = map.get("endTime");
            StringBuffer sb = new StringBuffer();
            sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
            sb.append("<root>");
            sb.append("<section_type>").append(sectionType).append("</section_type>");
            sb.append("<start_time>").append(startTime).append("</start_time>");
            sb.append("<org_code>").append(hospitalId).append("</org_code>");
            sb.append("<dept_code>").append(hosDeptId).append("</dept_code>");
            sb.append("<dept_name>").append(hosDeptName).append("</dept_name>");
            sb.append("<doctor_code>").append(doctorId).append("</doctor_code>");
            sb.append("<doctor_name>").append(doctorName).append("</doctor_name>");
            sb.append("<id_card>").append(cardNo).append("</id_card>");
            sb.append("<patient_name>").append(patientName).append("</patient_name>");
            sb.append("<ssid>").append(clinicCard).append("</ssid>");
            sb.append("<patient_phone>").append(patientPhone).append("</patient_phone>");
            sb.append("</root>");

            // 生成身份证明
            String[] values = SOAPUtil.getCredential(sb.toString(), true);

            JSONArray params = new JSONArray();

            JSONObject param1 = new JSONObject();
            param1.put("key", "?strCondition");
            param1.put("value", values[0]);
            params.put(param1);

            JSONObject param2 = new JSONObject();
            param2.put("key", "?strCredential");
            param2.put("value", values[1]);
            params.put(param2);

            JSONObject param3 = new JSONObject();
            param3.put("key", "?strKey");
            param3.put("value", values[2]);
            params.put(param3);

            //新增日志
            String method = "POST";
            String content = "创建挂号单";
            Long startTimes = System.currentTimeMillis();
            String response = SOAPUtil.post(ORDER_CREATE, params);
            Long spendTime = (System.currentTimeMillis()-startTimes)/1000;//计算请求时间
            String res = "耗时："+spendTime+"s,xml="+response;
            String msgBody = params.toString();
            //xml验证
            verificationXml(response,"获取医生排班表失败！",ORDER_CREATE,content,method,msgBody,res);
            //保存http日志
            logService.saveHttpLog(true,ORDER_CREATE,content,method,null,msgBody,res,null,logService.archiveType);
            re = CreateOrderAfter(response, hospitalId, hospitalName, hosDeptId, hosDeptName, doctorId, doctorName, sectionType, startTime, endTime, patient, patientName, cardNo, clinicCard, patientPhone, null, null);
        } else {
            throw new Exception("该排班信息错误或者不存在！");
        }

        return re;
    }


    /**
     * 取消挂号单
     */
    public boolean CancelOrder(String orderId, String clinicCard) throws Exception {
        JSONArray params = new JSONArray();

        JSONObject param1 = new JSONObject();
        param1.put("key", "?strSSID");
        param1.put("value", clinicCard);
        params.put(param1);

        JSONObject param2 = new JSONObject();
        param2.put("key", "?strRegID");
        param2.put("value", orderId);
        params.put(param2);

        String[] values = SOAPUtil.getCredential(null, true);

        JSONObject param3 = new JSONObject();
        param3.put("key", "?strCredential");
        param3.put("value", values[1]);
        params.put(param3);

        JSONObject param4 = new JSONObject();
        param4.put("key", "?strKey");
        param4.put("value", values[2]);
        params.put(param4);

        //新增日志
        String method = "POST";
        String content = "取消挂号单";
        Long startTime = System.currentTimeMillis();
        String xml = SOAPUtil.post(ORDER_CANCEL, params);
        Long spendTime = (System.currentTimeMillis()-startTime)/1000;//计算请求时间
        String res = "耗时："+spendTime+"s,xml="+xml;
        String msgBody = params.toString();
        //xml验证
        verificationXml(xml,"取消挂号失败！",ORDER_CANCEL,content,method,msgBody,res);

        Boolean isOk = false;
        if (xml.toLowerCase().startsWith("ok")) {
            isOk =  true;
        }

        //保存http日志
        logService.saveHttpLog(isOk,ORDER_CANCEL,content,method,null,msgBody,res,null,logService.archiveType);

        return isOk;
    }

    /**
     * 获取医生信息
     */
    public GuahaoDoctor GetDoctorInfo(String doctorId, String hospitalId, String hosDeptId) throws Exception {
        GuahaoDoctor doctor = new GuahaoDoctor();

        JSONArray params = new JSONArray();
        JSONObject param1 = new JSONObject();
        param1.put("key", "?OrgCode");
        param1.put("value", hospitalId);
        params.put(param1);
        JSONObject param2 = new JSONObject();
        param2.put("key", "?DeptCode");
        param2.put("value", hosDeptId);
        params.put(param2);
        JSONObject param3 = new JSONObject();
        param3.put("key", "?strStart");
        String nowDate = DateUtil.getStringDateShort();   //当前时间;
        param3.put("value", nowDate);
        params.put(param3);
        JSONObject param4 = new JSONObject();
        param4.put("key", "?strEnd");
        param4.put("value", DateUtil.getNextDay(nowDate, nextDays));  //一周后时间
        params.put(param4);

        //新增日志
        String method = "POST";
        String content = "获取医生信息";
        Long startTime = System.currentTimeMillis();
        String xml = SOAPUtil.post(DOCTOR_LIST, params);
        Long spendTime = (System.currentTimeMillis()-startTime)/1000;//计算请求时间
        String res = "耗时："+spendTime+"s,xml="+xml;
        String msgBody = params.toString();
        //xml验证
        verificationXml(xml,"获取医生列表失败！",DOCTOR_LIST,content,method,msgBody,res);

        Document document = DocumentHelper.parseText(xml);
        Element root = document.getRootElement();
        List<?> child = root.elements();
        for (Object o : child) {
            Element e = (Element) o;
            // 医生编码
            String code = e.attributeValue("code");

            if (code.equals(doctorId)) {
                // 性别
                String sex = e.attributeValue("sex");
                // 职称
                String tech = e.attributeValue("tech");
                // 学历
                String edu = e.attributeValue("edu");
                // 简介
                String introduce = e.attributeValue("introduce");
                // 专家姓名
                String name = e.attributeValue("name");
                // 照片
                String photo = "";
                if (e.attribute("photo") != null) {
                    photo = e.attributeValue("photo");
                }
                // 挂号费
                String fee = e.attributeValue("fee");
                // 科室编码
                String deptcode = e.attributeValue("deptcode");
                // 科室名称
                String deptname = e.attributeValue("deptname");
                // 机构编码
                String orgcode = e.attributeValue("orgcode");
                // 机构名称
                String orgname = e.attributeValue("orgname");

                doctor.setId(code);
                doctor.setName(name);
                doctor.setSex(sex);
                doctor.setTitle(tech);
                doctor.setEdu(edu);
                doctor.setIntroduce(introduce);
                doctor.setPhoto(photo);
                doctor.setFee(fee);
                doctor.setHosDeptId(deptcode);
                doctor.setHosDeptName(deptname);
                doctor.setHospitalId(orgcode);
                doctor.setHospitalName(orgname);
                break;
            }
        }

        //保存http日志
        logService.saveHttpLog(true,DOCTOR_LIST,content,method,null,msgBody,res,null,logService.archiveType);

        return doctor;
    }

    /**
     * 获取预约状态
     * 0 撤销 1 确认 2 已诊  3停诊
     */
    public Integer GetOrderStatus(String hospitalId, String orderId, String clinicCard) throws Exception {
        Integer re = null;
        try {
            StringBuffer sb = new StringBuffer();
            sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
            sb.append("<root>");
            sb.append("<org_code>").append(hospitalId).append("</org_code>");
            sb.append("<resid>").append(orderId).append("</resid>");
            sb.append("<ssid>").append(clinicCard).append("</ssid>");
            sb.append("</root>");

            String[] values = SOAPUtil.getCredential(sb.toString(), true);

            JSONArray params = new JSONArray();

            JSONObject param1 = new JSONObject();
            param1.put("key", "?strCondition");
            param1.put("value", values[0]);
            params.put(param1);

            JSONObject param2 = new JSONObject();
            param2.put("key", "?strCredential");
            param2.put("value", values[1]);
            params.put(param2);

            JSONObject param3 = new JSONObject();
            param3.put("key", "?strKey");
            param3.put("value", values[2]);
            params.put(param3);

            //新增日志
            String method = "POST";
            String content = "获取预约状态";
            Long startTime = System.currentTimeMillis();
            String xml = SOAPUtil.post(ORDER_INFO, params);
            Long spendTime = (System.currentTimeMillis()-startTime)/1000;//计算请求时间
            String res = "耗时："+spendTime+"s,xml="+xml;
            String msgBody = params.toString();
            String errMsg = "获取预约状态失败！";
            //xml验证
            verificationXml(xml,errMsg,ORDER_INFO,content,method,msgBody,res);

            Document document = DocumentHelper.parseText(xml);
            Element root = document.getRootElement();
            List<?> child = root.elements();
            if (child != null) {
                Element obj = (Element) child.get(0);
                String status = obj.attributeValue("status");

                switch (status) {
                    case "撤销": {
                        re = 0;
                        break;
                    }
                    case "确认": {
                        re = 1;
                        break;
                    }
                    case "已诊": {
                        re = 2;
                        break;
                    }
                    case "停诊": {
                        re = 3;
                        break;
                    }
                }

                //保存http日志
                logService.saveHttpLog(true,ORDER_INFO,content,method,null,msgBody,res,null,logService.archiveType);
            } else {
                //保存http日志
                logService.saveHttpLog(false,ORDER_INFO,content,method,null,msgBody,res,errMsg,logService.archiveType);
                throw new Exception(errMsg);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return re;
    }

    /**
     * 根据患者医保卡获取近三个月的预约记录
     */
    public List<PatientReservation> GetRegList(String patientCode, String strStart, String strEnd,Date strStartTime,Date strEndTime) throws Exception {
        Patient patient = patientService.findByCode(patientCode);
        if (patient == null) {
            throw new Exception("不存在该用户！");
        }

        //获取签名信息
        List<PatientReservation> patientRegList = new ArrayList<>();
        String[] values = SOAPUtil.getCredential(null, true);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        JSONArray params = new JSONArray();
        JSONObject param1 = new JSONObject();
        param1.put("key", "?strSSID");
        param1.put("value", patient.getSsc());
        params.put(param1);
        JSONObject param2 = new JSONObject();
        param2.put("key", "?strStart");
        param2.put("value", strStart);
        params.put(param2);
        JSONObject param3 = new JSONObject();
        param3.put("key", "?strEnd");
        param3.put("value", strEnd);
        params.put(param3);
        JSONObject param4 = new JSONObject();
        param4.put("key", "?strCredential");
        param4.put("value", values[1]);
        params.put(param4);
        JSONObject param5 = new JSONObject();
        param5.put("key", "?strKey");
        param5.put("value", values[2]);  //一周后时间
        params.put(param5);

        //新增日志
        String method = "POST";
        String content = "根据患者医保卡获取近三个月的预约记录";
        Long startTime = System.currentTimeMillis();
        String xml = SOAPUtil.post(REG_LIST, params);
        Long spendTime = (System.currentTimeMillis()-startTime)/1000;//计算请求时间
        String res = "耗时："+spendTime+"s,xml="+xml;
        String msgBody = params.toString();
        String errMsg = "获取挂号信息失败！";
        //xml验证
        verificationXml(xml,errMsg,REG_LIST,content,method,msgBody,res);

        Document document = DocumentHelper.parseText(xml);
        Element root = document.getRootElement();
        List<?> child = root.elements();


        if (child.size() > 0) {
            for (Object o : child) {
                Element e = (Element) o;
                // 医生编码
                String regdate = e.attributeValue("regdate");//预约日期
                String time = e.attributeValue("time");//a or p 上下午

                String regBegin = e.attributeValue("start_time");//预约时间段的开始时间
                String regEnd = e.attributeValue("end_time");//预约时间段的结束时间
                String orgID = e.attributeValue("orgID");//机构ID
                String OrgCode = e.attributeValue("OrgCode");//医疗机构编码
                String org = e.attributeValue("org");//医疗机构名称
                String DeptCode = e.attributeValue("DeptCode");//科室代码
                String dept = e.attributeValue("dept");//科室
                String DoctorCode = e.attributeValue("DoctorCode");//医生代码
                String doctor = e.attributeValue("doctor");//医生
                String Introduction = e.attributeValue("Introduction");//医生简介
                String status = e.attributeValue("status");//状态：删除、新建、确认、已诊
                String enter_time = e.attributeValue("enter_time");//预约登记时间
                String notes = e.attributeValue("notes");//备注
                String code = e.getText();//预约号
                PatientReservation patientReservation = new PatientReservation();
                patientReservation.setCode(code);
                patientReservation.setSectionType(time);

                patientReservation.setCzrq(dateFormat.parse(enter_time));
                patientReservation.setDeptCode(DeptCode);
                patientReservation.setDeptName(dept);
                patientReservation.setDoctorCode(DoctorCode);
                patientReservation.setDoctorName(doctor);
                patientReservation.setStartTime(DateUtil.strToDate(regBegin,DateUtil.YYYY_M_D_HH_MM_SS));
                patientReservation.setEndTime(DateUtil.strToDate(regEnd,DateUtil.YYYY_M_D_HH_MM_SS));
                patientReservation.setOrgCode(OrgCode);
                patientReservation.setOrgName(org);
                patientReservation.setType("1");
                patientReservation.setPatient(patientCode);
                patientReservation.setName(patient.getName());
                patientReservation.setIdcard(patient.getIdcard());
                patientReservation.setPhone(patient.getMobile());
                switch (status) {
                    case "删除":
                        patientReservation.setStatus(0);
                        break;
                    case "新建":
                        patientReservation.setStatus(1);
                        break;
                    case "确认":
                        patientReservation.setStatus(2);
                        break;
                    case "已诊":
                        patientReservation.setStatus(3);
                        break;
                    default:
                        patientReservation.setStatus(4);
                }
                ;
                patientReservation.setSsc(patient.getSsc());
                GuahaoDoctor guahaoDoctor = GetDoctorInfo(DoctorCode, OrgCode, DeptCode);
                patientReservation.setDoctorPhoto(guahaoDoctor.getPhoto());//照片
                patientReservation.setDoctorJob(guahaoDoctor.getTitle());//职称
                patientRegList.add(patientReservation);
            }
        }

        //根据患者医保卡获取近三个月的已取消的预约记录
        List<PatientReservation> list = patientReservationDao.findByPatientAndStartTime(patientCode,strStartTime,strEndTime);
        if(list.size()>0){
            patientRegList.addAll(list);

            patientRegList.sort(new Comparator<PatientReservation>() {
                public int compare(PatientReservation o1, PatientReservation o2) {
                    Date startTime1 = o1.getStartTime();
                    Date startTime2 = o2.getStartTime();
                    return startTime2.compareTo(startTime1);
                }
            });
        }

        //保存http日志
        logService.saveHttpLog(true,REG_LIST,content,method,null,msgBody,res,null,logService.archiveType);

        return patientRegList;
    }

    /**
     * 根据患者,预约编号，机构编号获取单条记录预约记录
     */
    public PatientReservation getRegDetail(String patientCode, String orgCode, String regCode) throws Exception {
        //获取签名信息
        Patient patient = patientService.findByCode(patientCode);
        if (patient == null) {
            throw new Exception("获取挂号人员信息失败！");
        }

        StringBuffer sb = new StringBuffer();
        sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
        sb.append("<root>");
        sb.append("<org_code>").append(orgCode).append("</org_code>");
        sb.append("<resid>").append(regCode).append("</resid>");
        sb.append("<ssid>").append(patient.getSsc()).append("</ssid>");
        sb.append("</root>");

        String[] values = SOAPUtil.getCredential(sb.toString(), true);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        JSONArray params = new JSONArray();
        JSONObject param1 = new JSONObject();
        param1.put("key", "?strCondition");
        param1.put("value", values[0]);
        params.put(param1);
        JSONObject param2 = new JSONObject();
        param2.put("key", "?strCredential");
        param2.put("value", values[1]);
        params.put(param2);
        JSONObject param3 = new JSONObject();
        param3.put("key", "?strKey");
        param3.put("value", values[2]);
        params.put(param3);

        //新增日志
        String method = "POST";
        String content = "获取单条记录预约记录";
        Long startTime = System.currentTimeMillis();
        String xml = SOAPUtil.post(ORDER_INFO, params);
        Long spendTime = (System.currentTimeMillis()-startTime)/1000;//计算请求时间
        String res = "耗时："+spendTime+"s,xml="+xml;
        String msgBody = params.toString();
        String errMsg = "获取挂号信息失败！";
        //xml验证
        verificationXml(xml,errMsg,ORDER_INFO,content,method,msgBody,res);

        Document document = DocumentHelper.parseText(xml);
        Element root = document.getRootElement();
        List<?> child = root.elements();

        if (child.size() > 0) {
            Element e = (Element) child.get(0);
            // 医生编码
            String regdate = e.attributeValue("regdate");//预约日期
            String time = e.attributeValue("time");//a or p 上下午

            String regBegin = e.attributeValue("start_time");//预约时间段的开始时间
            String regEnd = e.attributeValue("end_time");//预约时间段的结束时间
            String orgID = e.attributeValue("org_id");//机构ID
            String OrgCode = e.attributeValue("org_code");//医疗机构编码
            String org = e.attributeValue("org_name");//医疗机构名称
            String DeptCode = e.attributeValue("dept_code");//科室代码
            String dept = e.attributeValue("dept_name");//科室
            String DoctorCode = e.attributeValue("doctor_code");//医生代码
            String doctor = e.attributeValue("doctor_name");//医生
            String Introduction = e.attributeValue("introduction");//医生简介
            String status = e.attributeValue("status");//状态：删除、新建、确认、已诊
            String enter_time = e.attributeValue("enter_time");//预约登记时间
            String notes = e.attributeValue("notes");//备注
            String code = e.getText();//预约号
            PatientReservation patientReservation = new PatientReservation();
            patientReservation.setCode(code);
            patientReservation.setSectionType(time);

            patientReservation.setCzrq(dateFormat.parse(enter_time));
            patientReservation.setDeptCode(DeptCode);
            patientReservation.setDeptName(dept);
            patientReservation.setDoctorCode(DoctorCode);
            patientReservation.setDoctorName(doctor);
            patientReservation.setStartTime(DateUtil.strToDate(regBegin,DateUtil.YYYY_M_D_HH_MM_SS));
            patientReservation.setEndTime(DateUtil.strToDate(regEnd,DateUtil.YYYY_M_D_HH_MM_SS));
            patientReservation.setOrgCode(OrgCode);
            patientReservation.setOrgName(org);
            patientReservation.setType("1");
            patientReservation.setPatient(patient.getCode());
            patientReservation.setName(patient.getName());
            patientReservation.setIdcard(patient.getIdcard());
            patientReservation.setPhone(patient.getMobile());
            switch (status) {
                case "删除":
                    patientReservation.setStatus(0);
                    break;
                case "新建":
                    patientReservation.setStatus(1);
                    break;
                case "确认":
                    patientReservation.setStatus(2);
                    break;
                case "已诊":
                    patientReservation.setStatus(3);
                    break;
                default:
                    patientReservation.setStatus(4);
            }
            ;
            patientReservation.setSsc(patient.getSsc());
            GuahaoDoctor guahaoDoctor = GetDoctorInfo(DoctorCode, OrgCode, DeptCode);
            patientReservation.setDoctorPhoto(guahaoDoctor.getPhoto());//照片
            patientReservation.setDoctorJob(guahaoDoctor.getTitle());//职称

            //保存http日志
            logService.saveHttpLog(true,ORDER_INFO,content,method,null,msgBody,res,null,logService.archiveType);

            return patientReservation;
        } else {
            //保存http日志
            logService.saveHttpLog(false,ORDER_INFO,content,method,null,msgBody,res,null,logService.archiveType);
            return null;
        }
    }


    @Autowired
    JwSmjkService jwSmjkService;

    /******************************** 基卫内网服务 ************************************************/
    public List<Map<String, Object>> GetDoctorArrangeTenDay(String hospitalId, String hosDeptId, String doctorId) throws Exception {

        String strStart = DateUtil.getStringDateShort(); //当前时间;
        String strEnd = DateUtil.getNextDay(strStart, 11);         //10天预约

        String response = jwSmjkService.getRegDeptSpeDoctorSectionList(hospitalId, hosDeptId, strStart, strEnd, doctorId);

        return xmlToList(response);
    }

    /**
     * 转诊预约挂号
     */
    public String CreateOrderByDoctor(String hospitalId, String hospitalName, String hosDeptId, String hosDeptName, String doctorId, String doctorName, String arrangeDate, String patient, String patientName, String cardNo, String clinicCard, String patientPhone, String dname, String dcode) throws Exception {
        String re = "";

        Patient p = patientService.findByCode(patient);
        if (p == null) {
            throw new Exception("患者信息不存在！");
        }

        Map<String, String> map = objectMapper.readValue(arrangeDate, Map.class);
        if (map.containsKey("sectionType") && map.containsKey("startTime")) {
            String sectionType = map.get("sectionType");
            String startTime = map.get("startTime");
            String endTime = map.get("endTime");

            String response = jwSmjkService.webRegisterByFamily(cardNo, patientName, clinicCard, sectionType, startTime, hospitalId, hosDeptId, hosDeptName, doctorId, doctorName,patientPhone);

            re = CreateOrderAfter(response, hospitalId, hospitalName, hosDeptId, hosDeptName, doctorId, doctorName, sectionType, startTime, endTime, patient, patientName, cardNo, clinicCard, patientPhone, dname, dcode);
        } else {
            throw new Exception("该排班信息错误或者不存在！");
        }

        return re;
    }

}
