package thyyxxk.webserver.service.medicalinsurance.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import thyyxxk.webserver.config.exception.BizException;
import thyyxxk.webserver.config.exception.ExceptionEnum;
import thyyxxk.webserver.constants.sidicts.MedType;
import thyyxxk.webserver.dao.his.medicalinsurance.SiMzDao;
import thyyxxk.webserver.entity.dictionary.CodeName;
import thyyxxk.webserver.entity.medicalinsurance.inpatient.*;
import thyyxxk.webserver.entity.medicalinsurance.query.SiPatInfo;
import thyyxxk.webserver.service.medicalinsurance.ZyOrJzYbData;
import thyyxxk.webserver.utils.DateUtil;
import thyyxxk.webserver.utils.StringUtil;

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

@Service
public class JzYbData implements ZyOrJzYbData {
    private final SiMzDao dao;

    @Autowired
    public JzYbData(SiMzDao dao) {
        this.dao = dao;
    }

    @Override
    public AdmMdtrtinfo getAdmMdtrtinfo(ZyPatientInfo jzptnt) {
        AdmMdtrtinfo admMdtrtinfo = dao.selectAdmMdtrtinfo(jzptnt.getInpatientNo(), jzptnt.getAdmissTimes());
        if (null == admMdtrtinfo) {
            throw new BizException("没有查询到此患者的参保信息，请按正确流程操作。");
        }
        if (admMdtrtinfo.getMdtrtCertType().equals("01")) {
            admMdtrtinfo.setMdtrtCertType("02");
        }
        Date setlEndTime = dao.selectSetlEndTime(jzptnt.getInpatientNo(), jzptnt.getAdmissTimes());
        if (null != setlEndTime && setlEndTime.after(admMdtrtinfo.getBegntime())) {
            throw new BizException(ExceptionEnum.LOGICAL_ERROR, "此患者有 " +
                    DateUtil.formatDatetime(setlEndTime, "yyyy-MM-dd") + " 的医保结算条目，不可重复登记。");
        }
        jzptnt.setYbRegisterDate(admMdtrtinfo.getBegntime());
        jzptnt.setDismissDate(admMdtrtinfo.getBegntime());
        jzptnt.setName(admMdtrtinfo.getPsnName());
        return admMdtrtinfo;
    }

    @Override
    public List<AdmDiseinfo> getAdmDiseinfo(String patNo, int times) {
        CodeName icd = dao.getMzIcd(patNo, times);
        List<AdmDiseinfo> list = emptyIcdContent(icd) ?
                getAdmDiseinfoFromTable(patNo, times) :
                makeAdmDiseinfoFromIcd(patNo, times, icd);
        if (null == list || list.isEmpty()) {
            throw new BizException(ExceptionEnum.LOGICAL_ERROR, "医保诊断不能为空！");
        }
        return list;
    }

    private boolean emptyIcdContent(CodeName icd) {
        return null == icd || StringUtil.isBlank(icd.getCode()) || StringUtil.isBlank(icd.getName());
    }

    private List<AdmDiseinfo> getAdmDiseinfoFromTable(String patNo, int times) {
        return dao.getAdmDiseinfo(patNo, times);
    }

    private List<AdmDiseinfo> makeAdmDiseinfoFromIcd(String patNo, int times, CodeName icd) {
        AdmMdtrtinfo admMdtrtinfo = dao.selectAdmMdtrtinfo(patNo, times);
        admMdtrtinfo.setMedType(MedType.GENERAL_HOSPITALIZATION.getCode());
        if (admMdtrtinfo.getMdtrtCertType().equals("01")) {
            admMdtrtinfo.setMdtrtCertType("02");
        }
        String[] icdCodeArr = icd.getCode().split(",");
        String[] icdNameArr = icd.getName().split(",");
        List<AdmDiseinfo> list = new ArrayList<>();
        for (int i = 0; i < icdCodeArr.length; i++) {
            AdmDiseinfo diseinfo = new AdmDiseinfo();
            diseinfo.setPsnNo(admMdtrtinfo.getPsnNo());
            diseinfo.setPsnName(admMdtrtinfo.getPsnName());
            diseinfo.setDiagType("1");
            diseinfo.setDiagSrtNo(i + 1);
            diseinfo.setDiagCode(icdCodeArr[i]);
            diseinfo.setDiagName(icdNameArr[i]);
            diseinfo.setDiagDept(admMdtrtinfo.getAdmDeptName());
            diseinfo.setDiagTime(admMdtrtinfo.getBegntime());
            diseinfo.setMaindiagFlag(i == 0 ? "1" : "0");
            list.add(diseinfo);
        }
        return list;
    }

    @Override
    public PreSetlmt getPreSetlmt(ZyPatientInfo zyptnt) {
        PreSetlmt preSetlmt = dao.getPreSetlmt(zyptnt.getInpatientNo(), zyptnt.getAdmissTimes());
        if (null == preSetlmt || StringUtil.isBlank(preSetlmt.getMdtrtId())) {
            throw new BizException(ExceptionEnum.LOGICAL_ERROR, "此患者没有有效的医保在院信息！");
        }
        return preSetlmt;
    }

    @Override
    public Dscginfo getDscginfo(ZyPatientInfo zyptnt) {
        Dscginfo dscginfo = dao.getDscginfo(zyptnt.getInpatientNo(), zyptnt.getAdmissTimes());
        if (StringUtil.isBlank(dscginfo.getDscgDeptCodg())) {
            throw new BizException(ExceptionEnum.LOGICAL_ERROR, "出院科室【" +
                    dscginfo.getDscgDeptName() + "】编码不符合医保字典规范，请联系医保科匹配。");
        }
        return dscginfo;
    }

    @Override
    public List<SetlDiseinfo> getSetlDiseinfo(ZyPatientInfo zyptnt) {
        List<AdmDiseinfo> admDiseinfoList = getAdmDiseinfo(zyptnt.getInpatientNo(), zyptnt.getAdmissTimes());
        String mdtrtId = dao.getMdtrtId(zyptnt.getInpatientNo(), zyptnt.getAdmissTimes());
        List<SetlDiseinfo> setlDiseinfoList = new ArrayList<>();
        for (AdmDiseinfo admDiseinfo : admDiseinfoList) {
            SetlDiseinfo setlDiseinfo = new SetlDiseinfo();
            setlDiseinfo.setMdtrtId(mdtrtId);
            setlDiseinfo.setDiagType(admDiseinfo.getDiagType());
            setlDiseinfo.setMaindiagFlag(admDiseinfo.getMaindiagFlag());
            setlDiseinfo.setDiagSrtNo(admDiseinfo.getDiagSrtNo());
            setlDiseinfo.setDiagCode(admDiseinfo.getDiagCode());
            setlDiseinfo.setDiagName(admDiseinfo.getDiagName());
            setlDiseinfo.setDiagDept(admDiseinfo.getDiagDept());
            setlDiseinfo.setDiagTime(admDiseinfo.getDiagTime());
            setlDiseinfo.setDiseDorNo(admDiseinfo.getDiseDorNo());
            setlDiseinfo.setDiseDorName(admDiseinfo.getDiseDorName());
            setlDiseinfoList.add(setlDiseinfo);
        }
        return setlDiseinfoList;
    }

    @Override
    public PreSetlmt getSetlmt(ZyPatientInfo zyptnt) {
        return getPreSetlmt(zyptnt);
    }
}
