package thyyxxk.webserver.service.jiekou;

import lombok.Data;
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.dao.his.jiekou.DuiWaiJieKouDao;
import thyyxxk.webserver.entity.ResultVo;
import thyyxxk.webserver.entity.datamodify.MzChargeDetail;
import thyyxxk.webserver.entity.login.UserInfo;
import thyyxxk.webserver.entity.zhuyuanyisheng.jianyanjiancha.YshYjReq;
import thyyxxk.webserver.service.inpatient.HospitalizationCostsService;
import thyyxxk.webserver.utils.ListUtil;
import thyyxxk.webserver.utils.ResultVoUtil;
import thyyxxk.webserver.utils.StringUtil;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 描述： 对外医技确费接口
 * </p>
 *
 * @author xc
 * @date 2021-07-13 08:08
 */
@Slf4j
@Service
public class MedicalTechnologyIsPaidService {

    private final DuiWaiJieKouDao dao;
    private final HospitalizationCostsService hospitalizationCostsService;

    public MedicalTechnologyIsPaidService(DuiWaiJieKouDao dao, HospitalizationCostsService hospitalizationCostsService) {
        this.dao = dao;
        this.hospitalizationCostsService = hospitalizationCostsService;
    }

    @Data
    public static class ConfirmList {
        private List<String> reqNoAndPatNoList;
        private String confirmId;
        private Boolean changePrint;
    }

    @Data
    public static class Param {
        Param(String reqStr) {
            String[] temp = reqStr.split("_");
            reqNo = Integer.parseInt(temp[0]);
            patNo = temp[1];
            times = Integer.parseInt(temp[2]);
            orderNo = new BigDecimal(temp[3]);
        }

        private Integer reqNo;
        private String patNo;
        private Integer times;
        private BigDecimal orderNo;
    }

    @Transactional(rollbackFor = Exception.class)
    public ResultVo<String> mzProject(Integer reqNo, String confirmId, String type) {
        MzChargeDetail mz = dao.getFeeInfoByReqNo(reqNo);
        if (mz == null) {
            return ResultVoUtil.fail(ExceptionEnum.INVALID_PARAM, "未查询到原申请。");
        }

        UserInfo userInfo = dao.getUserInfo(confirmId);

        if (userInfo == null) {
            return ResultVoUtil.fail(ExceptionEnum.INVALID_PARAM, "未查询到确认人数据");
        }

        //  1 确认 3 取消
        Date date = new Date();

        int yjReq = dao.confirmOutpatientYjReq(type, confirmId, userInfo.getDeptCode(), date, reqNo);
        if (yjReq == 0) {
            return ResultVoUtil.fail(ExceptionEnum.INVALID_PARAM, "确费失败，医生已撤销申请。");
        }
        int feeCount = dao.confirmOutPatientFee(type, confirmId, userInfo.getDeptCode(), date, reqNo, mz);
        if (feeCount == 0) {
            throw new BizException(ExceptionEnum.INVALID_PARAM, "更新失败请联系管理员");
        }
        return ResultVoUtil.success(ExceptionEnum.SUCCESS);
    }


    public ResultVo<String> zyProject(Integer reqNo, String confirmId) {

        YshYjReq yshYjReq = dao.selectedYshJyReqOne(reqNo);

        if (yshYjReq == null) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "未查询到申请单");
        }

        if (StringUtil.notBlank(yshYjReq.getConfirmFlag())) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "请勿重复确认");
        }

        if (dao.whetherToGenerateAConfirmationFee(yshYjReq.getActOrderNo()) == 0) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "护士未执行");
        }

        UserInfo userInfo = dao.getUserInfo(confirmId);

        if (userInfo == null) {
            return ResultVoUtil.fail(ExceptionEnum.INVALID_PARAM, "未查询到确认人数据");
        }

        int ZY_CONFIRM = 1;
        setReqFlag(userInfo, yshYjReq, ZY_CONFIRM);
        return ResultVoUtil.success(ExceptionEnum.SUCCESS);
    }

    public ResultVo<String> zyProjectCancel(Integer reqNo, String confirmId) {
        UserInfo userInfo = dao.getUserInfo(confirmId);
        if (userInfo == null) {
            return ResultVoUtil.fail(ExceptionEnum.INVALID_PARAM, "未查询到确认人数据");
        }

        YshYjReq yshYjReq = dao.selectedYshJyReqOne(reqNo);

        if (yshYjReq == null) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "未查询到申请单");
        }

        int ZY_CANCEL = 2;
        setReqFlag(userInfo, yshYjReq, ZY_CANCEL);
        hospitalizationCostsService.refundsByPatientOrder(yshYjReq.getInpatientNo(), yshYjReq.getAdmissTimes(), yshYjReq.getActOrderNo());
        return ResultVoUtil.success("操作成功。");
    }

    /**
     * 设置申请单状态
     *
     * @param userInfo 用户信息
     * @param yshYjReq 申请单的信息
     * @param flag     状态
     */
    private void setReqFlag(UserInfo userInfo, YshYjReq yshYjReq, int flag) {
        Date date = new Date();
        int yshFlag = dao.updateYshYjReqFlag(userInfo.getCode(), yshYjReq.getReqNo(), date, userInfo.getDeptCode(), flag);

        if (yshFlag == 0) {
            throw new BizException(ExceptionEnum.INVALID_PARAM, "确费失败，医嘱未执行或者医生已撤销申请。");
        }

        int feeCount = dao.confirmTheIntermediateTable(userInfo.getCode(),
                yshYjReq.getActOrderNo(),
                date,
                userInfo.getDeptCode(),
                yshYjReq.getInpatientNo(),
                yshYjReq.getAdmissTimes(), flag);

        if (feeCount == 0) {
            throw new BizException(ExceptionEnum.INVALID_PARAM, "确费失败，医嘱未执行或者医生已撤销申请。");
        }
    }

    /**
     * 批量更新数据
     * reqNo_inpatient_no_admiss_times_act_order_no
     *
     * @param reqNoList 申请号 和 patNo , times 加 医嘱号 联合 ，下滑线连接起来
     * @param confirmId 确认人的 id
     * @return 返回提示
     */
    public ResultVo<String> medConfirmList(List<String> reqNoList, String confirmId) {
        UserInfo userInfo = dao.getUserInfo(confirmId);
        if (userInfo == null) {
            return ResultVoUtil.fail(ExceptionEnum.INVALID_PARAM, "未查询到确认人数据");
        }
        // 1 确认 2 取消
        int flag = 1;
        Date now = new Date();

        ListUtil.batchList(reqNoList, DuiWaiJieKouDao.class, (mapper, item) -> {
            // 解析出来的信息
            Param p = new Param(item);
            mapper.updateYshYjReqFlag(confirmId, p.getReqNo(), now, userInfo.getDeptCode(), flag);
            mapper.confirmTheIntermediateTable(confirmId, p.getOrderNo(), now, userInfo.getDeptCode(), p.getPatNo(), p.getTimes(), flag);
        });

        return ResultVoUtil.success("确认成功。");
    }


}
