package thyyxxk.webserver.service.medicalinsurance;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import thyyxxk.webserver.config.exception.BizException;
import thyyxxk.webserver.constants.sidicts.SiFunction;
import thyyxxk.webserver.dao.his.medicalinsurance.EmrUploadDao;
import thyyxxk.webserver.entity.medicalinsurance.emrupload.*;
import thyyxxk.webserver.utils.DateUtil;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class EmrUploadService {
    private final EmrUploadDao dao;
    private final ExecService exec;

    @Autowired
    public EmrUploadService(EmrUploadDao dao, ExecService exec) {
        this.dao = dao;
        this.exec = exec;
    }

    public String testUpload(String patNo, int times) {
        JSONObject response = new JSONObject();
        JSONObject body = makeUploadReqBody(patNo, times);

        com.alibaba.fastjson.JSONObject input =
                exec.makeTradeHeader(SiFunction.UPLOAD_EMR);
        input.getJSONObject("input").put("adminfo", body.getJSONObject("adminfo"));
        input.getJSONObject("input").put("coursrinfo", body.getJSONArray("coursrinfo"));
        input.getJSONObject("input").put("dieinfo", body.getJSONArray("dieinfo"));
        input.getJSONObject("input").put("diseinfo", body.getJSONArray("diseinfo"));
        input.getJSONObject("input").put("dscginfo", body.getJSONArray("dscginfo"));
        input.getJSONObject("input").put("oprninfo", body.getJSONArray("oprninfo"));
        input.getJSONObject("input").put("rescinfo", body.getJSONArray("rescinfo"));

        response.putOnce("request", input);
        com.alibaba.fastjson.JSONObject ret = exec.executeTrade(input, SiFunction.UPLOAD_EMR);
        response.putOnce("response", ret);
        return response.toString();
    }

    public JSONObject makeUploadReqBody(String patNo, int times) {
        List<SimpleEmrPatientData> emrList = dao.getEmrList(patNo, times);
        if (emrList.isEmpty()) {
            throw new BizException("患者没有电子病历。");
        }

        Adminfo adminfo = dao.selectAdminfo(patNo, times);
        if (null == adminfo) {
            throw new BizException("没有已经结算的就诊信息。");
        }
        HeightWeight hw = dao.getHeightWeight(patNo, times);
        adminfo.setPhysexmHeight(hw.getHeight());
        adminfo.setPhysexmWt(hw.getWeight());

        TmpDiseinfo diseinfo = null;
        Coursrinfo coursrinfo = null;
        Dieinfo dieinfo = null;
        Dscginfo dscginfo = null;
        List<Oprninfo> oprninfoList = new ArrayList<>();
        List<Rescinfo> rescinfoList = new ArrayList<>();

        String conphyCode = null;
        String conphyName = null;
        String leaderCode = null;
        String leaderName = null;

        for (SimpleEmrPatientData emr : emrList) {
            if (null != emr.getConsultPhysicianName() && null != emr.getDeptDirectorName()) {
                conphyCode = emr.getConsultPhysician();
                conphyName = emr.getConsultPhysicianName();
                leaderCode = emr.getDeptDirector();
                leaderName = emr.getDeptDirectorName();
                break;
            }
        }

        for (SimpleEmrPatientData emr : emrList) {
            if (null == emr.getConsultPhysicianName() || null == emr.getDeptDirectorName()) {
                emr.setConsultPhysician(conphyCode);
                emr.setConsultPhysicianName(conphyName);
                emr.setDeptDirector(leaderCode);
                emr.setDeptDirectorName(leaderName);
            }

            if (emr.getEmrCategoryCode().equals("ruyuanjiluzhuanyong")) {
                getAndMergeAdminfo(adminfo, emr);
            }
            if (emr.getEmrCategoryCode().equals("chuyuanjilu")) {
                diseinfo = getDiseinfoList(emr);
                dscginfo = getDscginfo(emr);
            }
            if (emr.getEmrCategoryCode().equals("shoucibingchengjilu")) {
                coursrinfo = getCoursrinfo(emr);
            }
            if (emr.getEmrCategoryCode().equals("shoushujilu")) {
                getAndMergeOprninfoList(oprninfoList, emr);
            }
            if (emr.getEmrCategoryCode().equals("siwangjilu")) {
                dieinfo = getDieinfo(emr);
            }
            if (emr.getEmrCategoryCode().equals("qiangjiujilu")) {
                getAndMergeRescinfo(rescinfoList, emr);
            }
        }
        if (null != coursrinfo && null != diseinfo) {
            Diseinfo admdise = diseinfo.getAdmMain();
            if (null != admdise) {
                coursrinfo.setPrelWmDiagCode(admdise.getWmDiagCode());
                coursrinfo.setPrelWmDiseName(admdise.getWmDiagName());
            }
            Diseinfo disdise = diseinfo.getDisMain();
            if (null != disdise) {
                coursrinfo.setFinlWmDiagCode(disdise.getWmDiagCode());
                coursrinfo.setFinlWmDiagName(disdise.getWmDiagName());
            }
        }
        if (null != coursrinfo) {
            coursrinfo.setDeptCode(adminfo.getDeptCode());
            coursrinfo.setDeptName(adminfo.getDeptName());
            coursrinfo.setWardareaName(adminfo.getWardareaName());
            coursrinfo.setBedno(adminfo.getBedno());
            coursrinfo.setPrntDocCode(leaderCode);
            coursrinfo.setPrntDocName(leaderName);
        }

        JSONObject body = JSONUtil.createObj();

        JSONArray coursrinfoArr = JSONUtil.createArray();
        if (null != coursrinfo) {
            coursrinfoArr.add(JSONUtil.parseObj(coursrinfo));
        }

        JSONArray dieinfoArr = JSONUtil.createArray();
        if (null != dieinfo) {
            dieinfoArr.add(JSONUtil.parseObj(dieinfo));
        }

        JSONArray dscginfoArr = JSONUtil.createArray();
        if (null != dscginfo) {
            dscginfoArr.add(JSONUtil.parseObj(dscginfo));
        }

        JSONArray diseinfoArr;
        if (null != diseinfo && null != diseinfo.getDiseinfoList()) {
            diseinfoArr = JSONUtil.parseArray(diseinfo.getDiseinfoList());
        } else {
            diseinfoArr = JSONUtil.createArray();
        }

        JSONArray oprninfoArr = JSONUtil.parseArray(oprninfoList);
        JSONArray rescinfoArr = JSONUtil.parseArray(rescinfoList);

        body.putOnce("adminfo", JSONUtil.parseObj(adminfo));
        body.putOnce("coursrinfo", coursrinfoArr);
        body.putOnce("dieinfo", dieinfoArr);
        body.putOnce("diseinfo", diseinfoArr);
        body.putOnce("dscginfo", dscginfoArr);
        body.putOnce("oprninfo", oprninfoArr);
        body.putOnce("rescinfo", rescinfoArr);
        return body;
    }

    public void getAndMergeAdminfo(Adminfo adminfo, SimpleEmrPatientData data) {

        adminfo.setStopSmokDays("0");

        JSONObject obj = JSONUtil.parseObj(data.getEmrDataElement());
        adminfo.setAdmRecNo(String.valueOf(data.getId()));
        adminfo.setChfcomp(obj.getByPath("主诉.value", String.class));
        adminfo.setDiseNow(obj.getByPath("现病史.value", String.class));

        JSONObject rxyl = getFirstObjInArray(obj, "日吸烟量.value");
        String tempRxyl = rxyl.getStr("name", "");
        String smokDay = "0";
        if (tempRxyl.contains("：") && tempRxyl.contains("支，")) {
            smokDay = tempRxyl.replaceAll("支，", "").split("：")[1];
        }
        adminfo.setSmokDay(smokDay);

        JSONObject ryjl = getFirstObjInArray(obj, "日饮酒量.value");
        String tempRylj = ryjl.getStr("name", "");
        String drnkDay = "0";
        if (tempRylj.contains("：") && tempRylj.contains("mL，")) {
            drnkDay = tempRylj.replaceAll("mL，", "").split("：")[1];
        }
        adminfo.setDrnkDay(drnkDay);

        JSONObject yfjzs = getFirstObjInArray(obj, "预防接种史.value");
        adminfo.setPrevVcnt(yfjzs.getStr("name", ""));
        JSONObject sss = getFirstObjInArray(obj, "手术史.value");
        adminfo.setOprnHis(sss.getStr("name", ""));
        JSONObject sxs = getFirstObjInArray(obj, "输血史.value");
        adminfo.setBldHis(sxs.getStr("name", ""));
        JSONObject gms = getFirstObjInArray(obj, "过敏史.value");
        adminfo.setAlgsHis(gms.getStr("name", ""));

        JSONObject yjs = getFirstObjInArray(obj, "月经史.value");
        adminfo.setMenaHis(yjs.getStr("name", ""));
        JSONObject jzs = getFirstObjInArray(obj, "家族史.value");
        adminfo.setFmhis(jzs.getStr("name", ""));

        adminfo.setPhysexmTprt(obj.getByPath("入院体温.value", String.class));
        adminfo.setPhysexmPule(obj.getByPath("入院脉搏.value", String.class));

        JSONObject hxpl = getFirstObjInArray(obj, "呼吸频率.value");
        adminfo.setPhysexmVentFrqu(hxpl.getStr("name", ""));

        String bldprs = obj.getByPath("入院血压.value", String.class);
        if (null != bldprs && bldprs.contains("/")) {
            String[] prs = bldprs.split("/");
            adminfo.setPhysexmSystolicPre(prs[0]);
            adminfo.setPhysexmDstlPre(prs[1]);
        }

        JSONObject pfnm = getFirstObjInArray(obj, "皮肤黏膜.value");
        adminfo.setPhysexmSkinMusl(pfnm.getStr("name", ""));

        JSONObject gmjwszq = getFirstObjInArray(obj, "肛门及外生殖器.value");
        adminfo.setPhysexmFingerExam(gmjwszq.getStr("name", ""));
        adminfo.setPhysexmGenitalArea(gmjwszq.getStr("name", ""));

        JSONObject jzwx = getFirstObjInArray(obj, "脊柱外形.value");
        adminfo.setPhysexmSpin(jzwx.getStr("name", ""));

        JSONObject szwx = getFirstObjInArray(obj, "四肢外形.value");
        adminfo.setPhysexmAllFors(szwx.getStr("name", ""));

        adminfo.setSpcyInfo(obj.getByPath("专科情况.value", String.class));
        adminfo.setAsstExamRslt(obj.getByPath("辅助检查结果.value", String.class));

        adminfo.setHlcon("");

        adminfo.setRecDocCode(data.getReferPhysician());
        adminfo.setRecDocName(data.getReferPhysicianName());
        adminfo.setIpdrCode(data.getReferPhysician());
        adminfo.setIpdrName(data.getReferPhysicianName());
        adminfo.setChfdrCode(data.getDeptDirector());
        adminfo.setChfdrName(data.getDeptDirectorName());
        adminfo.setChfpdrCode(data.getReferPhysician());
        adminfo.setChfpdrName(data.getReferPhysicianName());

        JSONObject fy = getFirstObjInArray(obj, "发育.value");
        adminfo.setGrowthDeg(fy.getStr("name", ""));
        adminfo.setEvalTime(data.getCreateDate());
        adminfo.setValiFlag("1");

    }

    public TmpDiseinfo getDiseinfoList(SimpleEmrPatientData data) {
        TmpDiseinfo result = new TmpDiseinfo();
        List<Diseinfo> list = new ArrayList<>();
        JSONObject obj = JSONUtil.parseObj(data.getEmrDataElement());
        JSONArray admdiags = obj.getByPath("入院诊断.value", JSONArray.class);
        JSONArray disdiags = obj.getByPath("出院诊断.value", JSONArray.class);
        String admdate = obj.getByPath("入院时间.value", String.class);
        for (int i = 0; i < admdiags.size(); i++) {
            JSONObject admdiag = admdiags.getJSONObject(i);
            Diseinfo diseinfo = new Diseinfo();
            diseinfo.setInoutDiagType("1");
            diseinfo.setMaindiagFlag(i == 0 ? "1" : "0");
            diseinfo.setDiagSeq(i + 1);
            diseinfo.setDiagTime(admdate);
            diseinfo.setWmDiagCode(admdiag.getStr("code"));
            diseinfo.setWmDiagName(admdiag.getStr("name", ""));
            diseinfo.setValiFlag("1");
            list.add(diseinfo);
            if (i == 0) {
                result.setAdmMain(diseinfo);
            }
        }
        for (int i = 0; i < disdiags.size(); i++) {
            JSONObject disdiag = disdiags.getJSONObject(i);
            Diseinfo diseinfo = new Diseinfo();
            diseinfo.setInoutDiagType("2");
            diseinfo.setMaindiagFlag(i == 0 ? "1" : "0");
            diseinfo.setDiagSeq(i + 1);
            diseinfo.setDiagTime(DateUtil.formatDatetime(data.getCreateDate()));
            diseinfo.setWmDiagCode(disdiag.getStr("code"));
            diseinfo.setWmDiagName(disdiag.getStr("name", ""));
            diseinfo.setValiFlag("1");
            list.add(diseinfo);
            if (i == 0) {
                result.setDisMain(diseinfo);
            }
        }
        result.setDiseinfoList(list);
        return result;
    }

    public Coursrinfo getCoursrinfo(SimpleEmrPatientData data) {
        Coursrinfo coursrinfo = new Coursrinfo();
        coursrinfo.setRcdTime(data.getCreateDate());
        JSONObject obj = JSONUtil.parseObj(data.getEmrDataElement());
        coursrinfo.setChfcomp(obj.getByPath("主诉.value", String.class));

        JSONObject bltd = obj.getByPath("病例特点.items", JSONObject.class);
        StringBuilder sb = new StringBuilder();
        bltd.keySet().forEach(key -> {
            JSONObject item = bltd.getJSONObject(key);
            sb.append(key).append(":").append(item.getStr("value")).append("；");
        });

        coursrinfo.setCasFtur(sb.toString());
        coursrinfo.setDiseEvid(obj.getByPath("诊断依据.value", String.class));
        coursrinfo.setDisePlan(obj.getByPath("诊疗计划.value", String.class));
        coursrinfo.setIpdrCode(data.getReferPhysician());
        coursrinfo.setIpdrName(data.getReferPhysicianName());
        coursrinfo.setPrntDocName(data.getDeptDirectorName());
        coursrinfo.setValiFlag("1");
        coursrinfo.setCodseRcdId(data.getId());
        return coursrinfo;
    }

    public void getAndMergeOprninfoList(List<Oprninfo> list, SimpleEmrPatientData data) {
        JSONObject obj = JSONUtil.parseObj(data.getEmrDataElement());

        JSONObject sqzd = getFirstObjInArray(obj, "术前诊断.value");
        JSONObject shzd = getFirstObjInArray(obj, "术后诊断.value");
        JSONObject mzfs = getFirstObjInArray(obj, "麻醉方式.value");
        JSONObject zdys = getFirstObjInArray(obj, "术者.value");
        JSONObject zs1 = getFirstObjInArray(obj, "第一助手.value");
        JSONObject zs2 = getFirstObjInArray(obj, "第二助手.value");
        JSONObject mzys = getFirstObjInArray(obj, "麻醉医生.value");
        JSONObject hyaMcbNBsf = obj.getByPath("hyaMcbNBsf.items", JSONObject.class);

        String sqyngrStrVal = "否";
        String yfkjywStrVal = "否";
        if (null != hyaMcbNBsf) {
            JSONObject sqyngr = getFirstObjInArray(hyaMcbNBsf, "术前院内感染.value");
            sqyngrStrVal = sqyngr.getStr("name", "否");
            JSONObject yfkjyw = getFirstObjInArray(hyaMcbNBsf, "预防抗菌药物.value");
            yfkjywStrVal = yfkjyw.getStr("name", "否");
        }

        String oprndate = obj.getByPath("手术日期.value", String.class);
        JSONArray oprns = getJSONArrayByPath(obj, "已行手术.value");
        for (int i = 0; i < oprns.size(); i++) {
            JSONObject item = oprns.getJSONObject(i);
            Oprninfo oprninfo = new Oprninfo();
            oprninfo.setOprnAppyId(data.getId() + "_" + list.size());
            oprninfo.setOprnSeq("seq-" + oprninfo.getOprnAppyId());
            oprninfo.setOprnTime(oprndate);
            oprninfo.setBfpnDiagCode(sqzd.getStr("code"));
            oprninfo.setBfpnOprnDiagName(sqzd.getStr("name", ""));
            oprninfo.setAfpnDiagCode(shzd.getStr("code"));
            oprninfo.setAfpnDiagName(shzd.getStr("name", ""));
            oprninfo.setOprnOprtCode(item.getStr("code"));
            oprninfo.setOprnOprtName(item.getStr("name", ""));
            oprninfo.setAnstMtdCode(mzfs.getStr("code"));
            oprninfo.setAnstMtdName(mzfs.getStr("name", ""));
            oprninfo.setOprnOperCode(zdys.getStr("code"));
            oprninfo.setOprnOperName(zdys.getStr("name", ""));
            oprninfo.setOprnAsitCode1(zs1.getStr("code"));
            oprninfo.setOprnAsitName1(zs1.getStr("name", ""));
            oprninfo.setOprnAsitCode2(zs2.getStr("code"));
            oprninfo.setOprnAsitName2(zs2.getStr("name", ""));
            oprninfo.setAnstDrCode(mzys.getStr("code"));
            oprninfo.setAnstDrName(mzys.getStr("name", ""));

            oprninfo.setBfpnInhospIfet(sqyngrStrVal);
            oprninfo.setPrevAbtlMedn(yfkjywStrVal);

            oprninfo.setValiFlag("1");
            list.add(oprninfo);
        }
    }

    public void getAndMergeRescinfo(List<Rescinfo> list, SimpleEmrPatientData data) {

    }

    public Dieinfo getDieinfo(SimpleEmrPatientData data) {
        JSONObject obj = JSONUtil.parseObj(data.getEmrDataElement());
        JSONObject ryzd = getFirstObjInArray(obj, "入院诊断.value");
        JSONObject cyzd = getFirstObjInArray(obj, "出院诊断.value");
        Dieinfo dieinfo = new Dieinfo();
        dieinfo.setDeptName(obj.getByPath("所在科室名称.value", String.class));
        dieinfo.setWardareaName(obj.getByPath("所在病室名称.value", String.class));
        dieinfo.setBedno(obj.getByPath("床号.value", String.class));
        dieinfo.setAdmTime(obj.getByPath("入院时间.value", String.class));
        dieinfo.setAdmDise(ryzd.getStr("code"));
        dieinfo.setAdmInfo(obj.getByPath("病情摘要.value", String.class));
        dieinfo.setTrtProcDscr(obj.getByPath("抢救经过.value", String.class));
        dieinfo.setDieTime("");
        dieinfo.setDieDrtRea(obj.getByPath("死亡原因.value", String.class));
        dieinfo.setDieDrtReaCode("");
        dieinfo.setDieDiagCode(cyzd.getStr("code"));
        dieinfo.setDieDiseName(cyzd.getStr("name", ""));
        dieinfo.setIpdrName(data.getReferPhysicianName());
        dieinfo.setChfpdrCode(data.getReferPhysician());
        dieinfo.setChfpdrName(data.getReferPhysicianName());
        dieinfo.setChfdrName(data.getDeptDirectorName());
        dieinfo.setSignTime(DateUtil.formatDatetime(data.getCreateDate()));
        dieinfo.setValiFlag("1");
        return dieinfo;
    }

    public Dscginfo getDscginfo(SimpleEmrPatientData data) {
        JSONObject obj = JSONUtil.parseObj(data.getEmrDataElement());
        JSONObject ryzd = getFirstObjInArray(obj, "入院诊断.value");
        JSONObject cyzd = getFirstObjInArray(obj, "出院诊断.value");
        Dscginfo dscginfo = new Dscginfo();
        dscginfo.setDscgDate(obj.getByPath("出院时间.value", String.class));
        dscginfo.setAdmDiagDscr(ryzd.getStr("showExtraDisplay"));
        dscginfo.setDscgDiseDscr(cyzd.getStr("showExtraDisplay"));
        dscginfo.setAdmInfo(obj.getByPath("入院情况.value", String.class));
        dscginfo.setTrtProcRsltDscr(obj.getByPath("诊疗经过.value", String.class));
        dscginfo.setDscgInfo(obj.getByPath("出院情况.value", String.class));
        dscginfo.setDscgDrord(obj.getByPath("出院医嘱.value", String.class));
        String deptName = obj.getByPath("所在科室名称.value", String.class);
        dscginfo.setCaty(dao.getSiCaty(deptName));
        dscginfo.setRecDoc(data.getCreateName());
        dscginfo.setMainDrugName("");
        dscginfo.setOthImpInfo("");
        dscginfo.setValiFlag("1");
        return dscginfo;
    }

    private JSONArray getJSONArrayByPath(JSONObject obj, String path) {
        JSONArray arr = obj.getByPath(path, JSONArray.class);
        if (null == arr) {
            arr = new JSONArray();
        }
        if (arr.isEmpty()) {
            arr.add(new JSONObject());
        }
        return arr;
    }

    private JSONObject getFirstObjInArray(JSONObject obj, String path) {
        JSONArray arr = getJSONArrayByPath(obj, path);
        return JSONUtil.parseObj(arr.get(0));
    }

}
