package thyyxxk.webserver.service.zygl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import thyyxxk.webserver.config.exception.BizException;
import thyyxxk.webserver.config.exception.ExceptionEnum;
import thyyxxk.webserver.constants.BedStatusEnum;
import thyyxxk.webserver.constants.SettleTypeEnum;
import thyyxxk.webserver.constants.YesOrNo;
import thyyxxk.webserver.constants.ZyDepositFileStatusEnum;
import thyyxxk.webserver.constants.ZyReqEnum;
import thyyxxk.webserver.dao.his.datamodify.ZyDetailChargeDao;
import thyyxxk.webserver.dao.his.dictionary.ZdUnitCodeDao;
import thyyxxk.webserver.dao.his.medicaladvice.common.DictDataDao;
import thyyxxk.webserver.dao.his.zygl.APatientMiDao;
import thyyxxk.webserver.dao.his.zygl.MzZyReqDao;
import thyyxxk.webserver.dao.his.zygl.ZyActpatientDao;
import thyyxxk.webserver.dao.his.zygl.ZyAdtDao;
import thyyxxk.webserver.dao.his.zygl.ZyBedMiDao;
import thyyxxk.webserver.dao.his.zygl.ZyDepositFileDao;
import thyyxxk.webserver.dao.his.zygl.ZyLedgerFileDao;
import thyyxxk.webserver.entity.ResultVo;
import thyyxxk.webserver.entity.dictionary.ZdUnitCode;
import thyyxxk.webserver.entity.executeItem.NumberEnum;
import thyyxxk.webserver.entity.executeItem.ZyLedgerFile;
import thyyxxk.webserver.entity.inpatient.ZyActpatient;
import thyyxxk.webserver.entity.inpatient.charge.PatientParam;
import thyyxxk.webserver.entity.inpatient.charge.ZyDepositFile;
import thyyxxk.webserver.entity.medicaladvice.medicamanage.MzZyReq;
import thyyxxk.webserver.entity.medicaladvice.medicamanage.patientinfo.ZyBedMi;
import thyyxxk.webserver.entity.zygl.APatientMi;
import thyyxxk.webserver.entity.zygl.CodeNameEntity;
import thyyxxk.webserver.entity.zygl.ZyAdt;
import thyyxxk.webserver.entity.zygl.ZyConfig;
import thyyxxk.webserver.entity.zygl.ZyWorkLog;
import thyyxxk.webserver.service.hutoolcache.UserCache;
import thyyxxk.webserver.utils.AssertUtil;
import thyyxxk.webserver.utils.CommonUtil;
import thyyxxk.webserver.utils.TokenUtil;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description: 住院服务
 * @Author:lihong
 * @Date: 2025/5/8
 */
@Service
@Slf4j
public class ZyActpatientService {
    private static final String[] UPDATE__TABLE_NAMES = {"zy_adt","zy_ledger_file","zy_receipt","zy_deposit_file","zy_drug","zy_detail_charge","zy_detail_charge_yb","zy_owe_file",
            "zy_owe_change","yz_act_order","yz_erase_order","yz_inact_order","yz_yp_zy_order","yz_zy_patient_fee","yz_act_occ","yz_print_rec","yz_temperature","yp_zy_patient",
            "op_record","ysh_yj_req","ysh_bl_record","ysh_hz_record","tjsb_ry_record","tjsb_cy_record","yj_jc_patient","yb_zy_review_record"};

    @Resource
    private APatientMiService aPatientMiService;
    @Resource
    private ZyActpatientDao zyActpatientMapper;
    @Resource
    private ZyBedMiDao zyBedMiMapper;
    @Resource
    private ZyConfigService zyConfigService;
    @Resource
    private MzZyReqDao mzZyReqMapper;
    @Resource
    private ZyAdtDao zyAdtMapper;
    @Resource
    private ZyLedgerFileDao zyLedgerFileMapper;
    @Resource
    private ZyDepositFileService zyDepositFileService;
    @Resource
    private ZyDetailChargeDao zyDetailChargeDao;
    @Resource
    private APatientMiDao aPatientMiMapper;
    @Resource
    private UserCache userCache;
    @Resource
    private DictDataDao dictDataDao;
    @Resource
    private ZdUnitCodeDao zdUnitCodeDao;
    @Resource
    private ZyDepositFileDao zyDepositFileDao;

    /**
     * @description: 保存入院信息
     * @author: lihong
     * @date: 2025/5/8 15:05
     * @param: zyActpatient
     * @return: int
     **/
    @Transactional(rollbackFor = Exception.class)
    public int saveZyActpatientFull(ZyActpatient zyActpatient)  {
        BeanUtil.trimStrFields(zyActpatient);
        AssertUtil.isnotBlank(zyActpatient.getInpatientNo(),"住院号不能为空");
        AssertUtil.isnotBlank(zyActpatient.getAdmissDate(),"入院日期不能为空");
        AssertUtil.isnotBlank(zyActpatient.getAdmissPhysician(),"入院医生不能为空");
        AssertUtil.isnotBlank(zyActpatient.getClinicDiag(),"门诊诊断编码不能为空");
        if(!CommonUtil.validateClinicDiagnose(zyActpatient.getClinicDiag())){
            throw new BizException(ExceptionEnum.LOGICAL_ERROR, "入院登记诊断编码范围应为:A~U开头和Z开头的编码;不包括字母V、W、X、Y开头的编码,请重新开具住院证");
        }
        AssertUtil.isnotBlank(zyActpatient.getClinicDiagStr(),"门诊诊断不能为空");
        AssertUtil.isnotBlank(zyActpatient.getAdmissDiagStr(),"住院诊断不能为空");
        AssertUtil.isnotBlank(zyActpatient.getAdmissDiag(),"住院诊断编码不能为空");
        AssertUtil.isnotBlank(zyActpatient.getAdmissDept(),"病区不能为空");
        AssertUtil.isnotBlank(zyActpatient.getAdmissWard(),"病区不能为空");
        AssertUtil.isnotBlank(zyActpatient.getSmallDept(),"小科室不能为空");
        AssertUtil.isnotBlank(zyActpatient.getBedNo(),"床号不能为空");
        AssertUtil.isnotBlank(zyActpatient.getAdmissStatus(),"入院状态不能为空");
        AssertUtil.isnotBlank(zyActpatient.getResponceType(),"病人身份不能为空");
        APatientMi aPatientMiDb = aPatientMiService.queryPatientMiByInPatientNo(zyActpatient.getInpatientNo());
        if (aPatientMiDb == null) {
            throw new  BizException(ExceptionEnum.LOGICAL_ERROR,"当前病人还未建档成功！");
        }
        if (zyActpatientMapper.selectCountByInpatientNo(aPatientMiDb.getInpatientNo()) > 0) {
            throw new BizException(ExceptionEnum.LOGICAL_ERROR,"当前病人是在院病人，请不要重复操作！");
        }
        List<String> patNos = zyActpatientMapper.selectBySocialNo(aPatientMiDb.getSocialNo());
        if(CollUtil.isNotEmpty(patNos)){
            throw new BizException(ExceptionEnum.LOGICAL_ERROR,"当前病人是在院病人，办理住院的住院号为"+CollUtil.join(patNos,",")+"，请不要重复操作！");
        }
        ZyBedMi tempZyBedMi = zyBedMiMapper.selectZyBedMi(zyActpatient.getAdmissDept(), zyActpatient.getAdmissDept(), zyActpatient.getBedNo());
        if(tempZyBedMi != null && ZyBedMi.BED_STATUS_HOLD_UP.equals(tempZyBedMi.getBedStatus())){
            throw new BizException(ExceptionEnum.LOGICAL_ERROR,"当前病人分配的床位已经有病人，请换床号办理入院！");
        }
        if (aPatientMiDb.getLastadmissTimes() == null) {
            aPatientMiDb.setLastadmissTimes(0);
        }
        Date now = new Date();
        Integer lastTimes = getLastadmissTimes(aPatientMiDb.getLastadmissTimes(),zyActpatient.getInpatientNo());
        aPatientMiDb.setLastadmissTimes(lastTimes + 1);
        aPatientMiService.updateLastadmissTimes(aPatientMiDb);
        zyActpatient.setMzNo(aPatientMiDb.getMzNo());
        zyActpatient.setChargeType(YesOrNo.YES.getCode().toString());
        zyActpatient.setInpatientNo(aPatientMiDb.getInpatientNo());
        zyActpatient.setAdmissTimes(aPatientMiDb.getLastadmissTimes());
        zyActpatient.setName(aPatientMiDb.getName());
        zyActpatient.setOutpatientNo(aPatientMiDb.getOutpatientNo());
        zyActpatient.setAdmissDate(now);
        zyActpatient.setVisitType(ZyActpatient.SELF_PAYING_RESPONCE_TYPE);
        zyActpatient.setTimesBilled(1);
        zyActpatient.setBedStatus(BedStatusEnum.PRE_ADMISS.code);
        zyActpatient.setZySerialNo(zyConfigService.getZySerialNo());
        zyActpatient.setResponceType(StrUtil.isBlank(zyActpatient.getResponceType()) ? ZyActpatient.SELF_PAYING_RESPONCE_TYPE : zyActpatient.getResponceType());
        zyActpatient.setBalance(BigDecimal.ZERO);
        zyActpatient.setTotalCharge(BigDecimal.ZERO);
        zyActpatient.setCharge1(BigDecimal.ZERO);
        zyActpatient.setCharge2(BigDecimal.ZERO);
        zyActpatient.setCharge3(BigDecimal.ZERO);
        zyActpatient.setCharge4(BigDecimal.ZERO);
        zyActpatient.setCharge5(BigDecimal.ZERO);
        zyActpatient.setCharge6(BigDecimal.ZERO);
        zyActpatient.setCharge7(BigDecimal.ZERO);
        zyActpatient.setCharge8(BigDecimal.ZERO);
        zyActpatient.setCharge9(BigDecimal.ZERO);
        zyActpatient.setCharge10(BigDecimal.ZERO);
        zyActpatient.setCharge11(BigDecimal.ZERO);
        zyActpatient.setCharge12(BigDecimal.ZERO);
        zyActpatient.setCharge13(BigDecimal.ZERO);
        zyActpatient.setCharge14(BigDecimal.ZERO);
        zyActpatient.setCharge15(BigDecimal.ZERO);
        zyActpatient.setCharge16(BigDecimal.ZERO);
        zyActpatient.setCharge17(BigDecimal.ZERO);
        zyActpatient.setCharge18(BigDecimal.ZERO);
        zyActpatient.setCharge19(BigDecimal.ZERO);
        zyActpatient.setCharge20(BigDecimal.ZERO);
        zyActpatient.setCharge21(BigDecimal.ZERO);
        zyActpatient.setCharge22(BigDecimal.ZERO);
        zyActpatient.setCharge23(BigDecimal.ZERO);
        zyActpatient.setCharge24(BigDecimal.ZERO);
        zyActpatient.setCharge25(BigDecimal.ZERO);
        zyActpatient.setCharge26(BigDecimal.ZERO);
        zyActpatient.setCharge27(BigDecimal.ZERO);
        zyActpatient.setCharge28(BigDecimal.ZERO);
        zyActpatient.setCharge29(BigDecimal.ZERO);
        zyActpatient.setCharge30(BigDecimal.ZERO);
        zyActpatient.setDept(zyActpatient.getAdmissDept());
        zyActpatient.setWard(zyActpatient.getAdmissWard());
        zyActpatient.setSex(aPatientMiDb.getSex());
        zyActpatient.setInputDate(now);
        zyActpatient.setZkWard(zyActpatient.getSmallDept());
        zyActpatient.setTableName(ZyActpatient.ZY_ACTPATIENT);
        int num = zyActpatientMapper.insertZyActpatient(zyActpatient);
        if (num > 0) {
            //修改门诊住院申请单
            MzZyReq mzZyReq = new MzZyReq();
            mzZyReq.setPatientId(zyActpatient.getMzNo());
            mzZyReq.setConfirmId(zyActpatient.getOpIdCode());
            mzZyReq.setConfirmDate(zyActpatient.getAdmissDate());
            mzZyReq.setZySerialNo(zyActpatient.getZySerialNo());
            mzZyReq.setReqStatus(ZyReqEnum.IN_HOSPITAL.code);
            mzZyReqMapper.updateMzZyReq(mzZyReq);
            //病人流转入库
            ZyAdt zyAdt = new ZyAdt();
            zyAdt.setZySerialNo(zyActpatient.getZySerialNo());
            zyAdt.setInpatientNo(zyActpatient.getInpatientNo());
            zyAdt.setAdmissTimes(zyActpatient.getAdmissTimes());
            zyAdt.setTransTimes(0);
            zyAdt.setAdmissDate(zyActpatient.getAdmissDate());
            zyAdt.setCurrWard(zyActpatient.getWard());
            zyAdt.setCurrDept(zyActpatient.getDept());
            zyAdt.setCurrRoom(null);
            zyAdt.setCurrBed(zyActpatient.getBedNo());
            zyAdt.setMark(NumberEnum.ONE.getCode());
            zyAdtMapper.deleteZyAdt(zyAdt.getInpatientNo(), zyAdt.getAdmissTimes());
            zyAdtMapper.inserZyAdt(zyAdt);
            //更新床号记录
            ZyBedMi zyBedMi = new ZyBedMi();
            zyBedMi.setBedStatus(ZyBedMi.BED_STATUS_HOLD_UP);
            zyBedMi.setInpatientNo(zyActpatient.getInpatientNo());
            zyBedMi.setAdmissTimes(zyActpatient.getAdmissTimes());
            zyBedMi.setDeptCode(zyActpatient.getDept());
            zyBedMi.setWardCode(zyActpatient.getDept());
            zyBedMi.setBedNo(zyActpatient.getBedNo());
            zyBedMiMapper.updateZyBedMi(zyBedMi);
            //入库账页信息
            ZyLedgerFile zyLedgerFile = new ZyLedgerFile();
            zyLedgerFile.setInpatientNo(zyActpatient.getInpatientNo());
            zyLedgerFile.setAdmissTimes(zyActpatient.getAdmissTimes());
            zyLedgerFile.setLedgerSn(1);
            zyLedgerFile.setOpIdCode(zyActpatient.getOpIdCode());
            zyLedgerFile.setDeposit(BigDecimal.ZERO);
            zyLedgerFile.setBalance(BigDecimal.ZERO);
            zyLedgerFile.setTotalCharge(BigDecimal.ZERO);
            zyLedgerFile.setCharge1(BigDecimal.ZERO);
            zyLedgerFile.setCharge2(BigDecimal.ZERO);
            zyLedgerFile.setCharge3(BigDecimal.ZERO);
            zyLedgerFile.setCharge4(BigDecimal.ZERO);
            zyLedgerFile.setCharge5(BigDecimal.ZERO);
            zyLedgerFile.setCharge6(BigDecimal.ZERO);
            zyLedgerFile.setCharge7(BigDecimal.ZERO);
            zyLedgerFile.setCharge8(BigDecimal.ZERO);
            zyLedgerFile.setCharge9(BigDecimal.ZERO);
            zyLedgerFile.setCharge10(BigDecimal.ZERO);
            zyLedgerFile.setCharge11(BigDecimal.ZERO);
            zyLedgerFile.setCharge12(BigDecimal.ZERO);
            zyLedgerFile.setCharge13(BigDecimal.ZERO);
            zyLedgerFile.setCharge14(BigDecimal.ZERO);
            zyLedgerFile.setCharge15(BigDecimal.ZERO);
            zyLedgerFile.setCharge16(BigDecimal.ZERO);
            zyLedgerFile.setCharge17(BigDecimal.ZERO);
            zyLedgerFile.setCharge18(BigDecimal.ZERO);
            zyLedgerFile.setCharge19(BigDecimal.ZERO);
            zyLedgerFile.setCharge20(BigDecimal.ZERO);
            zyLedgerFile.setCharge21(BigDecimal.ZERO);
            zyLedgerFile.setCharge22(BigDecimal.ZERO);
            zyLedgerFile.setCharge23(BigDecimal.ZERO);
            zyLedgerFile.setCharge24(BigDecimal.ZERO);
            zyLedgerFile.setCharge25(BigDecimal.ZERO);
            zyLedgerFile.setCharge26(BigDecimal.ZERO);
            zyLedgerFile.setCharge27(BigDecimal.ZERO);
            zyLedgerFile.setCharge28(BigDecimal.ZERO);
            zyLedgerFile.setCharge29(BigDecimal.ZERO);
            zyLedgerFile.setCharge30(BigDecimal.ZERO);
            zyLedgerFile.setSettle(BigDecimal.ZERO);
            zyLedgerFile.setLastBalance(BigDecimal.ZERO);
            zyLedgerFile.setSettleType("0");
            zyLedgerFile.setDeptCode(zyActpatient.getDept());
            zyLedgerFile.setWardCode(zyActpatient.getWard());
            zyLedgerFile.setDeptX("");
            zyLedgerFile.setWardX("");
            zyLedgerFile.setAccountDate(null);
            zyLedgerFile.setCashDate(null);
            zyLedgerFile.setCashId("");
            zyLedgerFile.setDcountNo("");
            zyLedgerFile.setDcountDate(null);
            zyLedgerFile.setZySerialNo(zyActpatient.getZySerialNo());
            zyLedgerFileMapper.insetZyLedgerFile(zyLedgerFile);
        }
        return num;
    }

    private Integer getLastadmissTimes(Integer lastadmissTimes, String inpatientNo) {
        Integer maxTimes = zyActpatientMapper.selectMaxTimes(inpatientNo);
        return Convert.toInt(lastadmissTimes, 0) <= Convert.toInt(maxTimes, 0) ? Convert.toInt(maxTimes, 0) : Convert.toInt(lastadmissTimes, 0);
    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteZyActpatient(ZyActpatient param) {
        AssertUtil.isnotBlank(param.getInpatientNo(), "住院号不能为空");
        APatientMi aPatientMiDb = aPatientMiService.queryPatientMiByInPatientNo(param.getInpatientNo());
        if (aPatientMiDb == null) {
            throw new BizException(ExceptionEnum.LOGICAL_ERROR,"当前病人还未建档成功！");
        }
        if (zyActpatientMapper.selectCountByInpatientNo(param.getInpatientNo()) <= 0) {
            throw new BizException("当前病人不在院，请不要重复操作！");
        }
        ZyActpatient zyActpatient = zyActpatientMapper.selectByInpatientNo(ZyActpatient.ZY_ACTPATIENT, param.getInpatientNo(),null);
        List<ZyLedgerFile> zyLedgerFiles = zyLedgerFileMapper.selectZyLedgerFileByInpatientNoAndTimes(zyActpatient.getInpatientNo(), zyActpatient.getAdmissTimes());
        if (CollUtil.isNotEmpty(zyLedgerFiles) && zyLedgerFiles.stream().anyMatch(item -> item.getTotalCharge() != null && item.getTotalCharge().compareTo(BigDecimal.ZERO) > 0)) {
            throw new BizException(ExceptionEnum.LOGICAL_ERROR,"当前病人已经产生账页费用,不能删除！");
        }
        BigDecimal totalFee = zyDepositFileService.querySumDepoAmountByInpatientNo(param.getInpatientNo(), zyActpatient.getAdmissTimes());
        if (totalFee != null && totalFee.compareTo(BigDecimal.ZERO) > 0) {
            throw new BizException(ExceptionEnum.LOGICAL_ERROR,"预交金已经产生费用,不能删除,若要删除,请先预交金退费！");
        }
        BigDecimal zyTotalFee = zyDetailChargeDao.selectSumChargeFee(param.getInpatientNo(), zyActpatient.getAdmissTimes());
        if(zyTotalFee != null && totalFee.compareTo(BigDecimal.ZERO) != 0){
            throw new BizException(ExceptionEnum.LOGICAL_ERROR,"已经产生住院费用,不能删除,若要删除,请先退费！");
        }

        List<String> unreceivedDrug = zyActpatientMapper.hasUnreceivedDrugList(param.getInpatientNo(), zyActpatient.getAdmissTimes());
        if (CollUtil.isNotEmpty(unreceivedDrug)) {
            throw new BizException(dischargeErrorMessage(unreceivedDrug));
        }
        Date tmpendtime = DateUtil.parse("2999-12-31 23:59:59");
        if (zyActpatientMapper.hasUnreceivedFees(param.getInpatientNo(), zyActpatient.getAdmissTimes(), tmpendtime) > 0) {
            throw new BizException(ExceptionEnum.LOGICAL_ERROR,"此患者有未接收的费用");
        }
        if (zyActpatientMapper.hasUnSubmitDrugList(param.getInpatientNo(), zyActpatient.getAdmissTimes()) > 0) {
            throw new BizException(ExceptionEnum.LOGICAL_ERROR,"此患者有未提交的药单");
        }
        if (zyActpatientMapper.hasUnconfirmedMedicalTech(param.getInpatientNo(), zyActpatient.getAdmissTimes(), tmpendtime) > 0) {
            throw new BizException(ExceptionEnum.LOGICAL_ERROR,"此患者有未确认的医技");
        }
        int ledgerSn = zyActpatientMapper.getLedgerSn(param.getInpatientNo(), zyActpatient.getAdmissTimes());
        if (zyActpatientMapper.hasUncheckedFee(param.getInpatientNo(), zyActpatient.getAdmissTimes(), ledgerSn) > 0) {
            throw new BizException(ExceptionEnum.LOGICAL_ERROR,"此患者有未结账的费用");
        }
        String mdtrtId = zyActpatientMapper.selectMdtrtId(param.getInpatientNo(), zyActpatient.getAdmissTimes());
        if(StrUtil.isNotBlank(mdtrtId)){
            throw new BizException(ExceptionEnum.LOGICAL_ERROR,"此患者有医保登记记录,请先取消医保登记");
        }
        ZyLedgerFile zyLedgerFile = zyLedgerFileMapper.selectLastLedgerSn(param.getInpatientNo(), zyActpatient.getAdmissTimes());
        Date now = new Date();
        String delNo = ZyConfig.DEL_PREFIX + zyConfigService.getDelNo();
        for (String tableName : UPDATE__TABLE_NAMES) {
            if (tableName.equals("yj_jc_patient")) {
                zyActpatientMapper.updateYjJcPatientInpatientNo(param.getInpatientNo(), delNo);
            } else if (tableName.equals("zy_adt")) {
                zyAdtMapper.updateZyAdtForDis(delNo,now, zyActpatient.getZkWard(), zyActpatient.getDept(), zyActpatient.getBedNo(), param.getInpatientNo(), zyActpatient.getAdmissTimes());
            } else {
                zyActpatientMapper.updateInpatientNoByTable(tableName, param.getInpatientNo(), zyActpatient.getAdmissTimes(), delNo);
            }
        }
        if(zyActpatient.getAdmissTimes() !=null && zyActpatient.getAdmissTimes() > 1){
            aPatientMiDb.setLastadmissTimes(zyActpatient.getAdmissTimes() - 1);
            aPatientMiMapper.updateLastadmissTimes(aPatientMiDb);
        }else {
            aPatientMiMapper.clearInpatientNo(aPatientMiDb);
        }
        //转移住院数据到出院表 包括婴儿
        zyActpatientMapper.insertZyInActpatient(null,null,delNo,param.getInpatientNo(), zyActpatient.getAdmissTimes(), TokenUtil.getInstance().getTokenUserId());
        zyActpatientMapper.insertZyInActpatient(param.getInpatientNo()+"$1",param.getInpatientNo()+"$6",delNo,param.getInpatientNo(), zyActpatient.getAdmissTimes(), TokenUtil.getInstance().getTokenUserId());
        int num = zyActpatientMapper.deleteZyActpatient(ZyActpatient.ZY_ACTPATIENT, param.getInpatientNo(), zyActpatient.getAdmissTimes());
        zyActpatientMapper.deleteZyActpatientBaby(ZyActpatient.ZY_ACTPATIENT, param.getInpatientNo()+"$1", param.getInpatientNo()+"$6", zyActpatient.getAdmissTimes());
        //修改门诊住院申请单
        MzZyReq mzZyReq = new MzZyReq();
        mzZyReq.setPatientId(zyActpatient.getMzNo());
        mzZyReq.setConfirmId(TokenUtil.getInstance().getTokenUserId());
        mzZyReq.setConfirmDate(now);
        mzZyReq.setReqStatus(ZyReqEnum.YI_ZF.code);
        mzZyReqMapper.updateMzZyReqStatus(mzZyReq);
        zyBedMiMapper.clearZyBedMi(param.getInpatientNo(),zyActpatient.getAdmissTimes());
        //保存出院日志
        ZyWorkLog zyWorkLog = new ZyWorkLog(delNo, Long.valueOf(zyActpatient.getAdmissTimes()));
        if (zyLedgerFile ==null || SettleTypeEnum.UNBALANCED_ACCOUNT.code.equals(zyLedgerFile.getSettleType())) {
            zyWorkLog.setLedgerSn(0L);
        } else {
            zyWorkLog.setLedgerSn(Long.valueOf(zyLedgerFile.getLedgerSn()));
        }
        zyWorkLog.setOpId(TokenUtil.getInstance().getTokenUserId());
        zyWorkLog.setOpDate(now);
        zyWorkLog.setLogType("6");
        zyWorkLog.setDeptCode(zyActpatient.getDept());
        zyWorkLog.setWardCode(zyActpatient.getWard());
        zyWorkLog.setName(userCache.getUserInfoByToken().getName());
        zyActpatientMapper.insertZyWorkLog(zyWorkLog);
    }


    private String dischargeErrorMessage(List<String> messages) {
        StringBuilder str = new StringBuilder("此患者有未接收的药单" + "<br />");
        for (String message : messages) {
            str.append(message).append("<br>");
        }
        return str.toString();
    }

    public ResultVo createDoorPatient(String patNo) {
        AssertUtil.isnotBlank(patNo,"住院号不能为空");
        String doorUrl = dictDataDao.getDictValueByDictName("3.1", "door_url");
        Map<String, Object> param = new HashMap<>();
        param.put("patNo",patNo);
        ResultVo response = new ResultVo();
        if(StrUtil.isNotBlank(doorUrl)){
            try {
                String res = HttpRequest.post(doorUrl+"/thyy/api/haikang/door/createPatient")
                        .body(JSONUtil.toJsonStr(param))
                        .execute()
                        .body();
                response = JSONUtil.toBean(res,ResultVo.class);
                if(response.getCode() == 200){
                    response.setCode(ExceptionEnum.SUCCESS_AND_EL_MESSAGE.getCode());
                }else {
                    response.setCode(ExceptionEnum.LOGICAL_ERROR.getCode());
                }
            }catch (Exception e){
                response.setCode(ExceptionEnum.LOGICAL_ERROR.getCode());
                response.setMessage("创建门禁患者信息错误:"+e.getMessage());
            }
        }else {
            response.setCode(ExceptionEnum.LOGICAL_ERROR.getCode());
            response.setMessage("创建门禁患者信息未上线.....");
        }
        return response;
    }

    public ZyActpatient queryByInpatientNo(String tableName, String inpatientNo, Integer admissTimes) {
        return zyActpatientMapper.selectByInpatientNo(tableName, inpatientNo, admissTimes);
    }
    /**
     * @description: 查询预交金的 和病人的信息
     * @author: lihong
     * @date: 2025/5/12 16:04
     * @param: param
     * @return: thyyxxk.webserver.entity.inpatient.ZyActpatient
     **/
    public ZyActpatient queryAdvancePayment(PatientParam param) {
        AssertUtil.isnotBlank(param.getInpatientNo(),"住院号不能为空");
        AssertUtil.isnotBlank(param.getAdmissTimes(),"住院次数不能为空");
        AssertUtil.isnotBlank(param.getInOutFlag(),"请选择查询在院或出院病人");
        ZyActpatient zyActpatient = queryByInpatientNo(YesOrNo.NO.getCode().equals(param.getInOutFlag()) ? ZyActpatient.ZY_ACTPATIENT : ZyActpatient.ZY_INACTPATIENT, param.getInpatientNo(), param.getAdmissTimes());
        BeanUtil.trimStrFields(zyActpatient);
        if(zyActpatient != null){
            ZdUnitCode zdUnitCode = zdUnitCodeDao.selectDeptDictByCode(zyActpatient.getWard());
            zyActpatient.setWardName(zdUnitCode != null ? zdUnitCode.getName() : "");
            zyActpatient.setResponceTypeName(zyActpatientMapper.selectResponceTypeName(zyActpatient.getResponceType()));
            APatientMi aPatientMi = aPatientMiMapper.selectPatientMiByInPatientNo(param.getInpatientNo());
            zyActpatient.setPatientId(aPatientMi == null || StrUtil.isBlank(aPatientMi.getMzNo()) ? "" : aPatientMi.getMzNo());
            ZyDepositFile tempParam = ZyDepositFile.builder()
                    .inpatientNo(param.getInpatientNo())
                    .admissTimes(param.getAdmissTimes())
                    .build();
            List<ZyDepositFile> zyDepositFiles = zyDepositFileService.queryZyDepositFileByInpatientNoAndTimes(tempParam);
            if(CollUtil.isNotEmpty(zyDepositFiles)){
                List<CodeNameEntity> zdCheque = zyActpatientMapper.selectZdChequeType();
                Map<String, CodeNameEntity> zdChequeMap = zdCheque.stream().collect(Collectors.toMap(CodeNameEntity::getCode, a -> a, (k1, k2) -> k1));
                ZyLedgerFile lastZyLedgerFile = zyLedgerFileMapper.selectLastLedgerSn(param.getInpatientNo(), param.getAdmissTimes());
                AssertUtil.isnotBlank(lastZyLedgerFile,"没有账页信息");
                BigDecimal yjjHj = BigDecimal.ZERO;
                BigDecimal ztYjjHj = BigDecimal.ZERO;
                for(ZyDepositFile zyDepositFile :zyDepositFiles){
                    zyDepositFile.setOpIdName(userCache.getEmployeeName(zyDepositFile.getOpIdCode()));
                    CodeNameEntity codeNameEntity = zdChequeMap.get(zyDepositFile.getDepoType());
                    zyDepositFile.setSettleType(lastZyLedgerFile.getSettleType());
                    zyDepositFile.setReportFlag(getReportFlag(zyDepositFile));
                    zyDepositFile.setDepoTypeName(codeNameEntity == null ? "" : codeNameEntity.getName());
                    if(ZyDepositFileStatusEnum.PREPAY.code.equals(zyDepositFile.getStatus())){
                        yjjHj = yjjHj.add(zyDepositFile.getDepoAmount().setScale(2, BigDecimal.ROUND_HALF_UP));
                    }
                    else if(ZyDepositFileStatusEnum.STRAIGHT_BACK.code.equals(zyDepositFile.getStatus())){
                        ztYjjHj = ztYjjHj.add(zyDepositFile.getDepoAmount().setScale(2, BigDecimal.ROUND_HALF_UP));
                    }
                }
                zyActpatient.setYjjHj(yjjHj);
                zyActpatient.setZtYjjHj(ztYjjHj.abs());
                zyActpatient.setZyDepositFiles(zyDepositFiles);
            }
        }
        return zyActpatient;
    }

    private String getReportFlag(ZyDepositFile zyDepositFile) {
        String receiptNo = zyDepositFile.getReceiptNo();
        if(ZyDepositFileStatusEnum.PREPAY.code.equals(zyDepositFile.getStatus())){
            BigDecimal sum = zyDepositFileDao.selectSumDepoAmountByReceiptNo(receiptNo);
            if(Convert.toBigDecimal(sum,BigDecimal.ZERO).compareTo(BigDecimal.ZERO) > 0 ){
                return "0";
            }else {
                return "1";
            }
        }
        return "0";
    }


    public List<ZyActpatient> queryAdvancePaymentPatientList(PatientParam param) {
        AssertUtil.isnotBlank(param.getInpatientNo(),"请输入住院号或者门诊号进行查询");
        AssertUtil.isnotBlank(param.getInOutFlag(),"请选择在院或者出院病人");
        List<String> inpatientNos = aPatientMiMapper.selectInpatientNoByKeyWard(param.getInpatientNo());
        List<ZyActpatient> list = new ArrayList<>();
        if(CollUtil.isEmpty(inpatientNos)){
            return list;
        }
        for (String inpatientNo: inpatientNos){
            list.addAll(zyActpatientMapper.selectByInpatientNoList(YesOrNo.NO.getCode().equals(param.getInOutFlag()) ? ZyActpatient.ZY_ACTPATIENT : ZyActpatient.ZY_INACTPATIENT, inpatientNo));
        }
        return list;
    }

    public ZyDepositFile queryPrintAdvancePayment(ZyDepositFile param) {
        AssertUtil.isnotBlank(param.getInpatientNo(),"住院号不能为空");
        AssertUtil.isnotBlank(param.getReceiptNo(),"收据号不能为空");
        ZyActpatient zyActpatient = zyActpatientMapper.selectByInpatientNo(ZyActpatient.ZY_ACTPATIENT, param.getInpatientNo(), null);
        AssertUtil.isnotBlank(zyActpatient,"没在在院信息");
        ZyDepositFile zyDepositFile = zyDepositFileService.queryZyDepositFileByReceiptNo(param.getReceiptNo());
        AssertUtil.isnotBlank(zyDepositFile,"没有收据为["+param.getReceiptNo()+"]缴费记录");
        List<CodeNameEntity> zdCheque = zyActpatientMapper.selectZdChequeType();
        Map<String, CodeNameEntity> zdChequeMap = zdCheque.stream().collect(Collectors.toMap(CodeNameEntity::getCode, a -> a, (k1, k2) -> k1));
        CodeNameEntity codeNameEntity = zdChequeMap.get(zyDepositFile.getDepoType());
        zyDepositFile.setDepoTypeName(codeNameEntity == null ? "" : codeNameEntity.getName());
        zyDepositFile.setDepoAmountDx(Convert.digitToChinese(zyDepositFile.getDepoAmount()));
        zyDepositFile.setDepoAmount(zyDepositFile.getDepoAmount().setScale(2,BigDecimal.ROUND_HALF_UP));
        zyDepositFile.setOpIdCodeName(userCache.getEmployeeName(zyDepositFile.getOpIdCode()));
        ZdUnitCode zdUnitCode = zdUnitCodeDao.selectDeptDictByCode(zyActpatient.getAdmissDept());
        zyDepositFile.setAdmissDeptName(zdUnitCode == null ? "" : zdUnitCode.getName());
        zyDepositFile.setPatientId(zyActpatient.getMzNo());
        zyDepositFile.setName(zyActpatient.getName());
        return zyDepositFile;
    }
}
