package thyyxxk.webserver.service.zhuyuanyisheng;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import thyyxxk.webserver.config.exception.ExceptionEnum;
import thyyxxk.webserver.dao.his.zhuyuanyisheng.HuiZhenShenQingDao;
import thyyxxk.webserver.dao.his.zhuyuanyisheng.YiZhuLuRuDao;
import thyyxxk.webserver.entity.ResultVo;
import thyyxxk.webserver.entity.casefrontsheet.YshHzRecord;
import thyyxxk.webserver.entity.datamodify.GetDropdownBox;
import thyyxxk.webserver.entity.inpatient.inpatientcost.ZyDetailChargeTable;
import thyyxxk.webserver.entity.login.UserInfo;
import thyyxxk.webserver.entity.zhuyuanyisheng.yizhuluru.XinZhenYiZhu;
import thyyxxk.webserver.service.PublicServer;
import thyyxxk.webserver.service.hutoolcache.UserCache;
import thyyxxk.webserver.service.inpatient.HospitalizationCostsService;
import thyyxxk.webserver.utils.ListUtil;
import thyyxxk.webserver.utils.ResultVoUtil;
import thyyxxk.webserver.utils.StringUtil;
import thyyxxk.webserver.utils.TokenUtil;

import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 * 描述： 会诊申请
 * </p>
 *
 * @author xc
 * @date 2021-05-07 11:01
 */
@Service
@Slf4j
public class HuiZhenShenQingService {
    private final HuiZhenShenQingDao dao;
    private final PublicServer publicServer;
    private final YiZhuLuRuDao yiZhuLuRuDao;
    private final HospitalizationCostsService refundService;
    private final UserCache userCache;

    public HuiZhenShenQingService(HuiZhenShenQingDao dao, PublicServer publicServer, YiZhuLuRuDao yiZhuLuRuDao, HospitalizationCostsService h, UserCache userCache) {
        this.dao = dao;
        this.publicServer = publicServer;
        this.yiZhuLuRuDao = yiZhuLuRuDao;
        this.refundService = h;
        this.userCache = userCache;
    }

    /**
     * @return 返回会诊级别
     */
    public ResultVo<List<GetDropdownBox>> huiZhenLeiBie() {
        return ResultVoUtil.success(dao.getYshZdHzLevel());
    }

    /**
     * 远程搜索科室
     *
     * @param code 模糊查询
     * @return 返回科室
     */
    public ResultVo<List<GetDropdownBox>> queryDept(String code) {
        return ResultVoUtil.success(dao.getZdUnitCode(StringUtil.isContainChinese(code)));
    }

    /**
     * 会诊申请
     *
     * @param param 申请需要插入的数据
     * @return 返回状态
     */
    public ResultVo<String> submitHuiZhenShenQing(YshHzRecord param, String userCode) {
        log.info("会诊申请====>申请人：{}，数据：{}", userCode, JSON.toJSONString(param));
        publicServer.huanZheJieSuan(param.getInpatientNo(), param.getAdmissTimes());
        //下面是给申请次数 加一
        param.setReqTimes(dao.getMaxReqTimes(param.getInpatientNo(), param.getAdmissTimes()) + 1);
        param.setInputDate(new Date());
        if (param.getEmergencyFlag() != null && param.getEmergencyFlag().trim().equals("0")) {
            param.setEmergencyFlag(null);
        }
        if (param.getYbSelfFlag() != null && param.getYbSelfFlag().trim().equals("0")) {
            param.setYbSelfFlag(null);
        }
        param.setActOrderNo(publicServer.getActOrderNo());
        param.setInputId(userCode);
        param.setReqDate(param.getInputDate());
        param.setOrderCode(getOrderCode("00" + param.getHzType()));
        param.setOrderName(String.format("请%s进行院内会诊", param.getReqDeptName()));
        XinZhenYiZhu patientInfo = yiZhuLuRuDao.queryPatientInfo(param.getInpatientNo(), param.getAdmissTimes());
        // 生成会诊和医嘱
        generateConsultation(param, patientInfo);
        log.info("插入数据：{}", JSON.toJSONString(param));
        UserInfo userInfo = userCache.getUserInfoByToken();

        String msg = String.format("患者：【%s】，住院号：【%s】，<br />请%s进行院内会诊。<br />会诊目的：<span style='color: red '>【%s】</span><br />申请人：【%s】，申请科室：【%s】",
                patientInfo.getName(), param.getInpatientNo(), param.getReqDeptName(), param.getHzMd(), userInfo.getName(), userInfo.getDeptName());

        if (StringUtil.notBlank(param.getHzDoctor1())) {
            publicServer.sendDoctorNotification(patientInfo, msg, "新增会诊申请", userCode, Collections.singletonList(param.getHzDoctor1()));
        } else {
            publicServer.sendDoctorNotification(patientInfo, msg, "新增会诊申请", userCode, dao.obtainDepartmentDoctor(param.getReqDept1()));
        }
        return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE, "会诊申请成功，正在通知会诊医生。");
    }

    public void generateConsultation(YshHzRecord param, XinZhenYiZhu patInfo) {
        //插入会诊申请
        dao.chaRuHuiZhenShenQing(param);
        // 坑爹的医嘱系统的 医嘱变更单，都用的是病房，这两个字段，而患者信息表中 deptCode 记录的是病房
        param.setWardCode(patInfo.getDeptCode());
        param.setDeptCode(patInfo.getDeptCode());
        //申请成功了就还需要插入一条医嘱，
        dao.chaRuYiZhu(param);
    }


    /**
     * 查询会诊的信息
     *
     * @param inpatientNo 住院号
     * @param admissTimes 住院次数
     * @return 返回
     */
    public ResultVo<List<YshHzRecord>> chaKanHuiZhenShenQing(String inpatientNo, int admissTimes) {
        return ResultVoUtil.success(dao.chaKanHuiZhenShenQing(inpatientNo, admissTimes, null));
    }

    /**
     * 删除会诊申请 要同时删除 会诊申请 和 一条医嘱
     *
     * @param inpatientNo 住院号
     * @param admissTimes 住院次数
     * @param actOrderNo  医嘱号
     * @param reqTimes    申请次数
     * @return 返回
     */
    public ResultVo<Boolean> shanChuHuiZhenShenQing(String inpatientNo, int admissTimes, BigDecimal actOrderNo, int reqTimes) {
        List<YshHzRecord> huiZhenXinXi = dao.chaKanHuiZhenShenQing(inpatientNo, admissTimes, actOrderNo);
        if (ListUtil.isBlank(huiZhenXinXi)) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "没有查询到原来的会诊信息。");
        }
        if (StringUtil.notBlank(huiZhenXinXi.get(0).getStatusFlag()) && "2".equals(huiZhenXinXi.get(0).getStatusFlag().trim())) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "该会诊已经完成了无法删除。");
        }

        List<ZyDetailChargeTable> zy = dao.selectChargeByOrderNo(inpatientNo, admissTimes, actOrderNo);
        int count = 0;

        if (ListUtil.notBlank(zy)) {
            HospitalizationCostsService.RefundParam param = new HospitalizationCostsService.RefundParam();
            param.setPatNo(inpatientNo);
            param.setTimes(admissTimes);
            param.setFeeList(zy);
            count = refundService.thereAreNoRestrictionsOnRefunds(param);
        }

        //会诊申请是根据 住院号，住院次数，申请次数 来获取到 一条
        dao.shanChuShenQing(inpatientNo, admissTimes, reqTimes);
        //医嘱 只要根据医嘱号来删除
        dao.shanChuYiZhu(actOrderNo);
        dao.deletePatientFee(inpatientNo, admissTimes, actOrderNo);
        log.info("删除会诊申请==》操作人：{}，数据：{}", TokenUtil.getInstance().getTokenUserId(), JSON.toJSONString(huiZhenXinXi.get(0)));
        String message = count > 0 ? "删除成功，会诊费用已退费。" : "删除成功";
        return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE, message);
    }

    /**
     * 查询会诊的医生
     *
     * @param deptCode 科室的code
     * @param hzType   会诊的级别
     * @return 返回 医生的code 和 name
     */
    public ResultVo<List<GetDropdownBox>> huiZhenYiSheng(String deptCode, String hzType) {
        String temp = "2";
        if ("1".equals(hzType)) {
            temp = "3";
        }
        if ("3".equals(hzType)) {
            temp = "1";
        }
        return ResultVoUtil.success(dao.huiZhenYiSheng(deptCode, "00" + temp));
    }

    /**
     * 获取会诊医生的信息
     *
     * @param searchCondition 查询条件 医生姓名 拼音 五笔
     * @return
     */
    public ResultVo<List<UserInfo>> getConsultingDoctorInfo(String searchCondition) {
        return ResultVoUtil.success(dao.getConsultingDoctorInfo(StringUtil.isContainChinese(searchCondition)));
    }

    /**
     * 获取患者的主诊断
     *
     * @param patNo 住院号
     * @param times 住院次数
     * @return 对应数据
     */
    public ResultVo<JSONArray> huoQuHuanZheZhuYaoZhenDuan(String patNo, Integer times) {
        JSONObject diag = dao.getPatientEmrDiag(patNo, times);
        if (diag == null) {
            return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST);
        }
        JSONObject data = diag.getJSONObject("data_element");
        if (data == null) {
            return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST);
        }
        JSONArray diagList = data.getJSONArray("入院诊断");
        if (diagList == null) {
            return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST);
        }
        return ResultVoUtil.success(diagList);
    }


    /**
     * 用来获取 order_code 这个是写死的
     *
     * @param hzType 会诊的级别
     * @return 返回 order_code
     */
    public static String getOrderCode(String hzType) {
        switch (hzType) {
            case "001":
                return "01427";
            case "002":
                return "01426";
            case "003":
                return "01425";
            default:
                return "500";
        }
    }
}
