package com.lantone.qc.kernel;

import com.lantone.qc.pub.jdbc.MysqlJdbc;
import com.lantone.qc.pub.util.FastJsonUtils;
import com.lantone.qc.pub.util.PropertiesUtil;
import com.lantone.qc.dbanaly.facade.changx.CxXmlUtil;
import com.lantone.qc.trans.changx.util.CxXmlUtilTemp;
import com.lantone.qc.dbanaly.facade.taizhou.TzXmlUtil;
import org.apache.commons.lang3.StringUtils;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPInputStream;

/**
 * @ClassName : TaizDataImportApiTest
 * @Description :
 * @Author : 楼辉荣
 * @Date: 2020-03-31 19:34
 */
public class ChangxDataImportApiTest {
    private static String hospitalId = "1";
    private static String cid = "changx";

    private Map<String,String> caseMap = new HashMap<>();
    private List<String> deletePatient = new ArrayList<>();

    private static Map<String, String> tableMap = new HashMap<>();

    private static void initTableMap() {
        if (cid.equals("changx")) {
            tableMap.put("BR_INPATIENTINFO", "BR_INPATIENTINFO");//患者信息
            tableMap.put("MR_MEDICALRECORDS", "MR_MEDICALRECORDS");//病案首页--手术
            tableMap.put("AR_MEDIRECCLASS", "AR_MEDIRECCLASS");//病案首页--手术
            tableMap.put("MR_MRCONTENT", "MR_MRCONTENT");//病案首页--手术
            tableMap.put("GI_USERINFO", "GI_USERINFO"); //医生
            tableMap.put("HI_DEPTINFO", "HI_DEPTINFO");//科室
            tableMap.put("BR_RECHOME", "BR_RECHOME");//病案首页
            tableMap.put("BR_RECDIAGNOSE", "BR_RECDIAGNOSE");//病案首页--出院诊断 门急诊诊断
            tableMap.put("BR_DOCTADVICE", "BR_DOCTADVICE");//医嘱
            tableMap.put("BR_RECOPERATION", "BR_RECOPERATION");//病案首页--手术
        } else if (cid.equals("taizhou")) {
            tableMap.put("BR_INPATIENTINFO", "BR_INPATIENTINFO_TZ");
            tableMap.put("GI_USERINFO", "GI_USERINFO_TZ");
            tableMap.put("HI_DEPTINFO", "HI_DEPTINFO_TZ");
            tableMap.put("BR_RECHOME", "BR_RECHOME_TZ");
            tableMap.put("BR_RECDIAGNOSE", "BR_RECDIAGNOSE_TZ");
            tableMap.put("BR_DOCTADVICE", "BR_DOCTADVICE_TZ");
            tableMap.put("BR_RECOPERATION", "BR_RECOPERATION_CX");
        }
    }

    public static void main(String[] args) {
//        String patientId = "ZY010000661273";
//
        ChangxDataImportApiTest test = new ChangxDataImportApiTest();
        test.dayevent();
//        initTableMap();
//        //模块映射
//        test.loadModelHospital();
//        //患者信息
//        test.insertPatient(test.loadOraclePatients(tableMap.get("BR_INPATIENTINFO"), patientId));
//        test.insertDoctor(test.loadOracleDoctorInfos(tableMap.get("GI_USERINFO"), tableMap.get("HI_DEPTINFO")));

//        //病人流水号获取    病历号--->id
//        Map<String, String> patientMap = test.loadPatients(hospitalId, patientId);
//        //model-->id
//        Map<String, String> modelMap = test.loadModel();
//        test.insertPatientText(patientMap, modelMap);
    }

    private void dayevent() {
        MysqlJdbc mysqlJdbc = initMysqlJdbc();
        Connection conn = mysqlJdbc.connect();
        Statement st = null;
        ResultSet rs = null;
        String r1, r2;
        Map<String, String> map = new HashMap<>();
        try {
            st = conn.createStatement();
            String sql = "select t2.xml_text, t1.behospital_code from med_medical_record t1, med_medical_record_content t2 where t1.rec_id = t2.rec_id and t1.rec_title = '日常病程记录'";
            rs = st.executeQuery(sql);
            while (rs.next()) {
                r1 = rs.getString(1);
                r2 = rs.getString(2);
                Map<String, String> xmlNodeValueMap = CxXmlUtil.firstLevelNodeValue(r1);
                System.out.println(r2 + ":" + xmlNodeValueMap.get("日常病程记录++++文本框"));
            }
        } catch (SQLException sqle) {
            sqle.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            mysqlJdbc.close(rs, st, conn);
        }
    }

    private void insertPatient(List<Patient> patients) {
        List<Map<String, Object>> list = new ArrayList<>();
        for (Patient patient : patients) {
            Map<String, Object> patientMap = new HashMap<>();
            patientMap.put("case_number", patient.getBrzyid());
            patientMap.put("hospital_id", hospitalId);
            list.add(patientMap);
        }
        initMysqlJdbc().insert(list, "qc_cases_number", new String[]{"hospital_id", "case_number"});
    }

    private void insertDoctor(List<Doctor> doctors) {
        List<Map<String, Object>> list = new ArrayList<>();
        for (Doctor doctor : doctors) {
            Map<String, Object> doctorMap = new HashMap<>();
            doctorMap.put("doctor_id", doctor.getDoctorId());
            doctorMap.put("doctor_name", doctor.getDoctorName());
            doctorMap.put("dept_id", doctor.getDeptId());
            doctorMap.put("dept_name", doctor.getDeptName());
            doctorMap.put("professor", doctor.getProfessor());
            list.add(doctorMap);
        }
        initMysqlJdbc().insert(list, "qc_doctor_info", new String[]{"doctor_id", "doctor_name", "dept_id", "dept_name", "professor"});
    }

    private void insertPatientText(Map<String, String> patientMap, Map<String, String> modelMap) {
        List<Map<String, Object>> list = new ArrayList<>();
        for (Map.Entry<String, String> entry : patientMap.entrySet()) {
            List<PatientText> patientTexts = new ArrayList<>();
            //病人的病案首页内容
            List<Map<String, Object>> homePageList = DataTest.loadHomePage(hospitalId, tableMap.get("BR_RECHOME"), entry.getKey());
            if (homePageList == null || homePageList.isEmpty()) { //没病案首页直接不导入
                deletePatient.add(entry.getKey()); //没病案首页的患者也要删除
                continue;
            }
            Map<String, Object> homePageMap = homePageList.get(0);
            homePageMap.put("出院诊断", FastJsonUtils.getBeanToJson(DataTest.loadHomePageDiagnose(hospitalId, tableMap.get("BR_RECDIAGNOSE"),"2", entry.getKey())).replaceAll("\"", "'"));
            homePageMap.put("损伤、中毒外部原因", FastJsonUtils.getBeanToJson(DataTest.loadHomePageDiagnose(hospitalId, tableMap.get("BR_RECDIAGNOSE"),"3", entry.getKey())).replaceAll("\"", "'"));
            homePageMap.put("病理诊断", FastJsonUtils.getBeanToJson(DataTest.loadHomePageDiagnose(hospitalId, tableMap.get("BR_RECDIAGNOSE"), "4", entry.getKey())).replaceAll("\"", "'"));
            homePageMap.put("手术信息", FastJsonUtils.getBeanToJson(DataTest.loadHomePageOperation(hospitalId, tableMap.get("BR_RECOPERATION"), tableMap.get("GI_USERINFO"), entry.getKey())).replaceAll("\"", "'"));

            Map<String, Object> firstPageTextMap = new HashMap<>();
            firstPageTextMap.put("case_number", entry.getKey());
            firstPageTextMap.put("case_number_id", patientMap.get(entry.getKey()));
            firstPageTextMap.put("hospital_id", hospitalId);
            firstPageTextMap.put("mode_id", 6);
            firstPageTextMap.put("origin_mode", "病案首页");
            firstPageTextMap.put("origin_text", FastJsonUtils.getBeanToJson(homePageMap));
            String pagetext = "";
            for (Map.Entry<String, Object> e : homePageMap.entrySet()) {
                pagetext = pagetext + "【" + e.getKey() + "】：" + e.getValue().toString() + "\n";
            }
            firstPageTextMap.put("text", pagetext);
            if ("changx".equals(cid)) {
                patientTexts = loadChangxOraclePatientTexts(entry.getKey());
            }
            if ("taizhou".equals(cid)) {
                patientTexts = loadTaizhouOraclePatientTexts(entry.getKey());
            }
            if (patientTexts.size() == 0 || !wholePatientRecord(patientTexts, modelMap)) {
                continue;
            }
            //数据完整后才放入病案首页
            list.add(firstPageTextMap);

            //病人医嘱信息
            List<Map<String, Object>> docAdviceMap = DataTest.loadHomePage(hospitalId, tableMap.get("BR_DOCTADVICE"), entry.getKey());
            for (Map<String, Object> docMap : docAdviceMap) {
                Map<String, Object> docAdviceTextMap = new HashMap<>();
                docAdviceTextMap.put("case_number", entry.getKey());
                docAdviceTextMap.put("case_number_id", patientMap.get(entry.getKey()));
                docAdviceTextMap.put("hospital_id", hospitalId);
                docAdviceTextMap.put("mode_id", 8);
                docAdviceTextMap.put("origin_mode", "医嘱信息");
                docAdviceTextMap.put("origin_text", FastJsonUtils.getBeanToJson(docMap));
                pagetext = "";
                for (Map.Entry<String, Object> e : docMap.entrySet()) {
                    pagetext = pagetext + "【" + e.getKey() + "】：" + e.getValue().toString() + "\n";
                }
                docAdviceTextMap.put("text", pagetext);
                list.add(docAdviceTextMap);
            }
            //病人其他文书信息
            for (PatientText patientText : patientTexts) {
                Map<String, Object> patientTextMap = new HashMap<>();
                patientTextMap.put("case_number", patientText.getBrzyid());
                patientTextMap.put("case_number_id", patientMap.get(patientText.getBrzyid()));
                patientTextMap.put("hospital_id", hospitalId);
                patientTextMap.put("mode_id", modelMap.get(caseMap.get(patientText.getBljlmc())));
                patientTextMap.put("origin_mode", patientText.getBljlmc());
                if (patientTextMap.get("mode_id") == null) {
                    continue;
                }
                patientTextMap.put("origin_text", patientText.getBljlnr());

                String text = "";
                Map<String, String> textMap = new HashMap<>();
                if ("changx".equals(cid)) {
                    textMap = CxXmlUtilTemp.beHospitalizedXmlToMap(patientText.getBljlnr(), caseMap.get(patientText.getBljlmc()));
                }
                if ("taizhou".equals(cid)) {
                    textMap = TzXmlUtil.getXmlToMapForTZ(patientText.getBljlnr());
                }
                for (Map.Entry<String, String> e : textMap.entrySet()) {
                    text = text + "【" + e.getKey() + "】：" + e.getValue() + "\n";
                }
                patientTextMap.put("text", text);
                list.add(patientTextMap);
            }
        }
        initMysqlJdbc().insert(list, "qc_model_mapping", new String[]{"case_number", "case_number_id", "origin_text", "mode_id", "text", "origin_mode"});

        deletePatientInfos(deletePatient);
    }

    /**
     * 验证数据完整性
     * @param patientTexts
     * @param modelMap
     * @return
     */
    private boolean wholePatientRecord(List<PatientText> patientTexts, Map<String, String> modelMap) {
        Map<String, String> m = new HashMap<>();
        for (PatientText patientText : patientTexts) {
            String modelId = modelMap.get(caseMap.get(patientText.getBljlmc()));
            if (StringUtils.isEmpty(modelId)) {
                continue;
            }
            if (modelId.equals("1") && patientText.getBljlnr().indexOf("<") != 0) {
                deletePatient.add(patientTexts.get(0).getBrzyid());
                return false;
            }
            m.put(modelId, modelId);
        }
        if (m.get("1") != null && m.get("2") != null && m.get("4") != null && (m.get("5") != null || m.get("24") != null)) {
            return true;
        } else {
            deletePatient.add(patientTexts.get(0).getBrzyid());
        }
        return false;
    }

    private List<Patient> loadOraclePatients(String tableName) {
        return loadOraclePatients(tableName, "");
    }

    private List<Patient> loadOraclePatients(String tableName, String patientId) {
        MysqlJdbc mysqlJdbc = initOracleJdbc();
        Connection conn = mysqlJdbc.connect();
        Statement st = null;
        ResultSet rs = null;
        String r1, r2;
        List<Patient> patients = new ArrayList<>();
        try {
            st = conn.createStatement();
            String sql = "";
            if (StringUtils.isNotEmpty(patientId)) {
                sql = "select BRZYID from " + tableName + " where BRZYID = '" + patientId + "'";
            } else {
                sql = "select BRZYID from " + tableName;
            }
            rs = st.executeQuery(sql);
            while (rs.next()) {
                r1 = rs.getString(1);
                Patient patient = new Patient();
                patient.setBrzyid(r1);
                patients.add(patient);
            }
        } catch (SQLException sqle) {
            sqle.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            mysqlJdbc.close(rs, st, conn);
        }
        return patients;
    }

    private List<Doctor> loadOracleDoctorInfos(String tableUser, String tableDept) {
        MysqlJdbc mysqlJdbc = initOracleJdbc();
        Connection conn = mysqlJdbc.connect();
        Statement st = null;
        ResultSet rs = null;
        List<Doctor> doctors = new ArrayList<>();
        try {
            st = conn.createStatement();
            String sql = "select u.yhrydm, u.yhrymc, u.yhryzc, dept.zzksid, dept.zzksmc from " + tableDept + " dept, " + tableUser + " u where u.zzksid = dept.zzksid";
            rs = st.executeQuery(sql);
            while (rs.next()) {
                Doctor doctor = new Doctor();
                doctor.setDoctorId(rs.getString(1));
                doctor.setDoctorName(rs.getString(2));
                doctor.setProfessor(rs.getString(3));
                doctor.setDeptId(rs.getString(4));
                doctor.setDeptName(rs.getString(5));
                doctors.add(doctor);
            }
        } catch (SQLException sqle) {
            sqle.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            mysqlJdbc.close(rs, st, conn);
        }
        return doctors;
    }

    private List<PatientText> loadTaizhouOraclePatientTexts(String brzyid) {
        MysqlJdbc mysqlJdbc = initOracleJdbc();
        Connection conn = mysqlJdbc.connect();
        Statement st = null;
        ResultSet rs = null;
        String r1, r2, r3;
        List<PatientText> patientTexts = new ArrayList<>();
        try {
            st = conn.createStatement();
            String sql = "select brzyid,bljlmc,bljlnr from mr_medicalrecords_TZ a " +
                    "left join mr_mrcontent_TZ b on a.bljlid=b.bljlid " +
                    "where bljlnr is not null and brzyid = '" + brzyid + "' " +
                    "order by brzyid";
            rs = st.executeQuery(sql);
            while (rs.next()) {
                r1 = rs.getString(1);
                r2 = rs.getString(2);
                r3 = rs.getString(3);
                PatientText patientText = new PatientText();
                patientText.setBrzyid(r1);
                patientText.setBljlmc(r2);
                patientText.setBljlnr(r3);
                patientTexts.add(patientText);
            }
        } catch (SQLException sqle) {
            sqle.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            mysqlJdbc.close(rs, st, conn);
        }
        return patientTexts;
    }
    private List<PatientText> loadChangxOraclePatientTexts(String brzyid) {
        MysqlJdbc mysqlJdbc = initOracleJdbc();
        Connection conn = mysqlJdbc.connect();
        Statement st = null;
        ResultSet rs = null;
        String r1, r2;
        List<PatientText> patientTexts = new ArrayList<>();
        try {
            st = conn.createStatement();
            String sql = "select a.brzyid,c.bllbmc,b.bljlnr from " + tableMap.get("MR_MEDICALRECORDS") + " a " +
                    "left join " + tableMap.get("MR_MRCONTENT") + " b on a.bljlid=b.bljlid " +
                    "left join " + tableMap.get("AR_MEDIRECCLASS") + " c on a.Bllbid = c.bllbid " +
                    "where bljlnr is not null and brzyid = '" + brzyid + "' and a.bljlmc != '诊断证明书' " +
                    "order by brzyid";
            rs = st.executeQuery(sql);
            while (rs.next()) {
                r1 = rs.getString(1);
                r2 = rs.getString(2);
                java.sql.Blob blob = rs.getBlob(3);

                InputStream in = blob.getBinaryStream();

                GZIPInputStream ginzip = new GZIPInputStream(in);

                ByteArrayOutputStream out = new ByteArrayOutputStream();
                byte[] buffer = new byte[1024];
                int offset = -1;
                while ((offset = ginzip.read(buffer)) != -1) {
                    out.write(buffer, 0, offset);
                }
                String decompressed = out.toString();
                in.close();
                out.close();
                ginzip.close();

                PatientText patientText = new PatientText();
                patientText.setBrzyid(r1);
                patientText.setBljlmc(r2);
                patientText.setBljlnr(decompressed);
                patientTexts.add(patientText);
            }
        } catch (SQLException sqle) {
            sqle.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            mysqlJdbc.close(rs, st, conn);
        }
        return patientTexts;
    }

    private Map<String, String> loadPatients(String hospitalId) {
        return loadPatients(hospitalId, null);
    }

    private Map<String, String> loadPatients(String hospitalId, String patientId) {
        MysqlJdbc mysqlJdbc = initMysqlJdbc();
        Connection conn = mysqlJdbc.connect();
        Statement st = null;
        ResultSet rs = null;
        String r1, r2;
        Map<String, String> map = new HashMap<>();
        try {
            st = conn.createStatement();
            String sql = "";
            if (StringUtils.isNotEmpty(patientId)) {
                sql = "select id, case_number from qc_cases_number where hospital_id = " + hospitalId + " and case_number = '" + patientId + "'";
            } else {
                sql = "select id, case_number from qc_cases_number where hospital_id = " + hospitalId;
            }
            rs = st.executeQuery(sql);
            while (rs.next()) {
                r1 = rs.getString(1);
                r2 = rs.getString(2);
                map.put(r2, r1);
            }
        } catch (SQLException sqle) {
            sqle.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            mysqlJdbc.close(rs, st, conn);
        }
        return map;
    }

    private Map<String, String> loadModel() {
        MysqlJdbc mysqlJdbc = initMysqlJdbc();
        Connection conn = mysqlJdbc.connect();
        Statement st = null;
        ResultSet rs = null;
        String r1, r2;
        Map<String, String> map = new HashMap<>();
        try {
            st = conn.createStatement();
            String sql = "select id, name from qc_mode";
            rs = st.executeQuery(sql);
            while (rs.next()) {
                r1 = rs.getString(1);
                r2 = rs.getString(2);
                map.put(r2, r1);
            }
        } catch (SQLException sqle) {
            sqle.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            mysqlJdbc.close(rs, st, conn);
        }
        return map;
    }

    private void loadModelHospital() {
        MysqlJdbc mysqlJdbc = initMysqlJdbc();
        Connection conn = mysqlJdbc.connect();
        Statement st = null;
        ResultSet rs = null;
        String r1, r2;
        try {
            st = conn.createStatement();
            String sql = "select hospital_model_name, stand_model_name from qc_model_hospital where stand_model_name is not null and hospital_id = " + hospitalId;
            rs = st.executeQuery(sql);
            while (rs.next()) {
                r1 = rs.getString(1);
                r2 = rs.getString(2);
                caseMap.put(r1, r2);
            }
        } catch (SQLException sqle) {
            sqle.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            mysqlJdbc.close(rs, st, conn);
        }
    }

    private void deletePatientInfos(List<String> caseNumbers) {
        MysqlJdbc mysqlJdbc = initMysqlJdbc();
        Connection conn = mysqlJdbc.connect();
        Statement st = null;
        ResultSet rs = null;
        String r1, r2;
        try {
            st = conn.createStatement();
            for (String caseNumber : caseNumbers) {
                String sql = "delete from qc_cases_number where case_number = '" + caseNumber + "'";
                st.execute(sql);
            }
        } catch (SQLException sqle) {
            sqle.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            mysqlJdbc.close(rs, st, conn);
        }
    }

    private MysqlJdbc initMysqlJdbc() {
        PropertiesUtil propertiesUtil = new PropertiesUtil("kernel.properties");
        MysqlJdbc mysqlJdbc = new MysqlJdbc(propertiesUtil.getProperty("mysql.test.user"),
                propertiesUtil.getProperty("mysql.test.password"),
                propertiesUtil.getProperty("mysql.test.url"));
        return mysqlJdbc;
    }

    private MysqlJdbc initOracleJdbc() {
        PropertiesUtil propertiesUtil = new PropertiesUtil("kernel.properties");
        MysqlJdbc mysqlJdbc = new MysqlJdbc(propertiesUtil.getProperty("oracle.test.user"),
                propertiesUtil.getProperty("oracle.test.password"),
                propertiesUtil.getProperty("oracle.test.url"), propertiesUtil.getProperty("oracle.test.driver"));
        return mysqlJdbc;
    }
}