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.repository.organization.HospitalMappingDao;
import com.yihu.wlyy.repository.patient.PatientReservationDao;
import com.yihu.wlyy.service.common.account.PatientService;
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.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";//预约信息

    @Autowired
    private PatientService patientService;

    @Autowired
    private HospitalMappingDao hospitalMappingDao;

    @Autowired
    private PatientReservationDao patientReservationDao;

    private ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 获取医院列表
     */
    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 xml = SOAPUtil.post(ORG_LIST, params);
            if (StringUtils.isEmpty(xml)) {
                // 请求失败
                throw new Exception("获取机构列表失败！");
            } else if (StringUtils.startsWith(xml, "System-Error")) {
                // 调用失败
                throw new Exception(xml.substring(xml.indexOf(":") + 1, xml.length()));
            }
            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);
            }
        }
        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 xml = SOAPUtil.post(DEP_LIST, params);
        if (StringUtils.isEmpty(xml)) {
            // 请求失败
            throw new Exception("获取可预约科室列表失败！");
        } else if (StringUtils.startsWith(xml, "System-Error")) {
            // 调用失败
            throw new Exception(xml.substring(xml.indexOf(":") + 1, xml.length()));
        }
        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);
            }
        }
        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 xml = SOAPUtil.post(DOCTOR_LIST, params);
        if (StringUtils.isEmpty(xml)) {
            // 请求失败
            throw new Exception("获取医生列表失败！");
        } else if (StringUtils.startsWith(xml, "System-Error")) {
            // 调用失败
            throw new Exception(xml.substring(xml.indexOf(":") + 1, xml.length()));
        }
        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);
        }
        return  re;
    }

    /**
     * 获取医生排班接口(包含排班详细)
     * status 0 停诊、1正常、2满号、3已过期
     */
    public List<Map<String,Object>> GetDoctorArrange(String hospitalId,String hosDeptId,String doctorId) throws Exception{
        List<Map<String,Object>> 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 xml = SOAPUtil.post(DOCTOR_ARRANGE, params);
        if (StringUtils.isEmpty(xml)) {
            // 请求失败
            throw new Exception("获取医生排班表失败！");
        } else if (StringUtils.startsWith(xml, "System-Error")) {
            // 调用失败
            throw new Exception(xml.substring(xml.indexOf(":") + 1, xml.length()));
        }
        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,Object> map = new HashMap<>();
            map.put("date", date);
            map.put("time", time);
            map.put("max", max);
            map.put("used", used);
            map.put("status", status);
            // 排班信息
            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;
    }

    /**
     * 获取医生排班接口（一级）
     * 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 xml = SOAPUtil.post(DOCTOR_ARRANGE_SIMPLE, params);
        if (StringUtils.isEmpty(xml)) {
            // 请求失败
            throw new Exception("获取医生排班表失败！");
        } else if (StringUtils.startsWith(xml, "System-Error")) {
            // 调用失败
            throw new Exception(xml.substring(xml.indexOf(":") + 1, xml.length()));
        }
        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);
        }
        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 xml = SOAPUtil.post(ORDER_CREATE, params);
            if (StringUtils.isEmpty(xml)) {
                // 请求失败
                throw new Exception("请求失败！");
            } else if (StringUtils.startsWith(xml, "System-Error")) {
                // 调用失败
                throw new Exception(xml.substring(xml.indexOf(":") + 1, xml.length()));
            }

            //预约成功
            if (xml.toLowerCase().startsWith("ok")) {
                // 预约成功,获取预约号
                String code = xml.replace("OK:", "");
                // 查询医生职称和头像
                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(startTime);
                reservation.setEndTime(endTime);
                reservation.setStatus(1);
                // 保存预约记录
                patientReservationDao.save(reservation);
                re = code;
            }
        }
        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 xml = SOAPUtil.post(ORDER_CANCEL, params);
        if (StringUtils.isEmpty(xml)) {
            // 请求失败
            throw new Exception("取消挂号失败！");
        } else if (StringUtils.startsWith(xml, "System-Error")) {
            // 调用失败
            throw new Exception(xml.substring(xml.indexOf(":") + 1, xml.length()));
        }
        if (xml.toLowerCase().startsWith("ok")) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 获取医生信息
     */
    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 xml = SOAPUtil.post(DOCTOR_LIST, params);
        if (StringUtils.isEmpty(xml)) {
            // 请求失败
            throw new Exception("获取医生列表失败！");
        } else if (StringUtils.startsWith(xml, "System-Error")) {
            // 调用失败
            throw new Exception(xml.substring(xml.indexOf(":") + 1, xml.length()));
        }
        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;
            }
        }
        return  doctor;
    }

    /**
     * 获取预约状态
     * 0 撤销 1 确认 2 已诊  3停诊
     */
    public Integer GetOrderStatus(String hospitalId,String orderId,String clinicCard) throws Exception
    {
        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 xml = SOAPUtil.post(ORDER_INFO, params);
        if (StringUtils.isEmpty(xml)) {
            // 请求失败
            throw new Exception("获取预约状态失败！");
        } else if (StringUtils.startsWith(xml, "System-Error")) {
            // 调用失败
            throw new Exception(xml.substring(xml.indexOf(":") + 1, xml.length()));
        }

        Document document = DocumentHelper.parseText(xml);
        Element root = document.getRootElement();
        List<?> child = root.elements();
        if(child!=null)
        {
            Integer re = 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;
                }
            }
            return re;
        }
        else {
            throw new Exception("获取预约状态失败！");
        }
    }

}
