package thyyxxk.webserver.service.datamodify;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import thyyxxk.webserver.config.exception.ExceptionEnum;
import thyyxxk.webserver.constants.GetDateFormat;
import thyyxxk.webserver.constants.Message;
import thyyxxk.webserver.dao.his.datamodify.YzActOrderModifyVerifyDao;
import thyyxxk.webserver.entity.ResultVo;
import thyyxxk.webserver.entity.datamodify.TYzActOrderModify;
import thyyxxk.webserver.http.websocket.SocketV2;
import thyyxxk.webserver.http.websocket.dto.WebSocketByUserCode;
import thyyxxk.webserver.utils.*;

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

/**
 * <p>
 * 描述 医嘱修改审核
 * </p>
 *
 * @author xc
 * @date 2021-04-09 08:40
 */
@Service
@Slf4j
public class YzActOrderModifyVerifyService {

    private static final int YZ_APPROVED = 2;
    private static final int YZ_REJECT = 3;
    private static final int YZ_WITHDRAW = 4;
    private final YzActOrderModifyVerifyDao dao;
    private final SocketV2 socket;

    @Autowired
    public YzActOrderModifyVerifyService(YzActOrderModifyVerifyDao dao, SocketV2 socket) {
        this.dao = dao;
        this.socket = socket;
    }

    /**
     * 根据医嘱号或者住院号 还有审核的状态来获取 需要审核的信息
     *
     * @param param 查询的条件
     * @return 返回审核的信息
     */
    public ResultVo<IPage<TYzActOrderModify>> chaKanZhuangTai(TYzActOrderModify param) {
        QueryWrapper<TYzActOrderModify> qw = new QueryWrapper<>();
        qw.select("inpatient_no,act_order_no,order_name,audit_flag");
        if (param.getActOrderNo() != null) {
            qw.eq("act_order_no", param.getActOrderNo());
        }
        if (StringUtil.notBlank(param.getInpatientNo())) {
            qw.eq("inpatient_no", param.getInpatientNo());
        }
        if (param.getAuditFlag() == 0) {
            qw.in("audit_flag", 1, 2, 3, 4);
        } else {
            qw.eq("audit_flag", param.getAuditFlag());
        }
        IPage<TYzActOrderModify> page = new Page<>(param.getCurrentPage(), param.getPageSize());
        dao.selectPage(page, qw);
        if (page.getTotal() > 0) {
            return ResultVoUtil.success(page);
        }
        return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, "没有找到对应的申请记录  ╮(﹀_﹀”)╭");
    }

    /**
     * 根据医嘱号来获取一些详细的信息 这个是在是在医嘱申请表中查询的数据
     *
     * @param actOrderNo 医嘱号
     * @return 返回指定的
     */
    public ResultVo<TYzActOrderModify> shenHeXinXi(BigDecimal actOrderNo) {
        return ResultVoUtil.success(yzActOrderQuery(actOrderNo));
    }

    /**
     * 把通过医嘱号查询的封装起来 别的地方还要用
     *
     * @param actOrderNo 医嘱号
     * @return 返回对应的数据
     */
    public TYzActOrderModify yzActOrderQuery(BigDecimal actOrderNo) {
        QueryWrapper<TYzActOrderModify> qw = new QueryWrapper<>();
        qw.select("act_order_no,inpatient_no,start_time,end_time,new_start_time," +
                  "new_end_time,audit_flag,proposer,proposer_name=(select name from a_employee_mi where code=proposer),propose_time," +
                  "audit_staff,audit_time,audit_remark,propose_remark," +
                  "patient_name,frequ_code,ward_code,order_name");
        qw.eq("act_order_no", actOrderNo);
        return dao.selectOne(qw);
    }


    /**
     * 审核判断要执行哪些动作
     *
     * @param auditFlag   1-未审核 2-通过 3-不通过 4-数据回撤到最近一次的修改
     * @param actOrderNo  医嘱号，任任何操作都是根据医嘱号来的
     * @param auditRemark 一些审核的备注信息
     * @return 返回
     */
    public ResultVo<Boolean> shenHePanDuan(Integer auditFlag, BigDecimal actOrderNo, String auditRemark) {
        //根据医嘱号 在申请表中 获取数据
        TYzActOrderModify pojo = yzActOrderQuery(actOrderNo);
        JSONObject obj = new JSONObject();
        if (auditFlag == YZ_APPROVED) {
            Date admissDate = dao.huanZaiRuYuanShiJian(pojo.getInpatientNo());
            // 开始时间不能小于于入院时间
            if (DateUtil.shiJianDaXiao(pojo.getNewStartTime(), admissDate, "<")) {
                dao.shenHeZhuangTaiGaiBian(YZ_REJECT, TokenUtil.getInstance().getTokenUserId(), actOrderNo, "开始时间不能在入院时间之前。");
                obj.put("type", "error");
                obj.put("message", String.format("用户【%s】，医嘱号为【%s】已驳回，<br>驳回原因：%s", pojo.getProposerName(), actOrderNo, "开始时间不能在入院时间之前。"));
                return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "开始时间不能在入院时间之前,已自动驳回。");
            }
            if (judgeTheTime(pojo)) {
                dao.shenHeZhuangTaiGaiBian(YZ_REJECT, TokenUtil.getInstance().getTokenUserId(), actOrderNo, "结束时间不能在开始时间前面。");
                obj.put("type", "error");
                obj.put("message", String.format("用户【%s】，医嘱号为【%s】已驳回，<br>驳回原因：%s", pojo.getProposerName(), actOrderNo, "结束时间不能在开始时间前面。"));
                return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "结束时间不能在开始时间前面,已自动驳回。");
            } else {
                dao.yzActOrderModify(pojo.getNewStartTime(), pojo.getNewEndTime(), pojo.getActOrderNo());
                dao.shenHeZhuangTaiGaiBian(auditFlag, TokenUtil.getInstance().getTokenUserId(), actOrderNo, auditRemark);
                obj.put("type", "success");
                obj.put("message", String.format("用户【%s】，医嘱号为【%s】已通过审核。", pojo.getProposerName(), actOrderNo));
                log.info("医嘱修改成功 --> 审核人：{}，数据：{}",
                        TokenUtil.getInstance().getTokenUserId(), JSON.toJSONStringWithDateFormat(pojo, GetDateFormat.DATE_TIME));
            }
        } else if (auditFlag == YZ_REJECT) {
            dao.shenHeZhuangTaiGaiBian(auditFlag, TokenUtil.getInstance().getTokenUserId(), actOrderNo, auditRemark);
            obj.put("message", String.format("用户【%s】，医嘱号为【%s】已驳回，<br>驳回原因：%s。", pojo.getProposerName(), actOrderNo, auditRemark));
            obj.put("type", "error");
            log.info("医嘱修改审核 --> 操作：{驳回},操作员：{},驳回医嘱号：{}", TokenUtil.getInstance().getTokenUserId(), pojo.getActOrderNo());
        } else if (auditFlag == YZ_WITHDRAW) {
            //数据回撤
            dao.shuJuHuiChe(pojo.getStartTime(), pojo.getEndTime(), pojo.getActOrderNo());
            dao.shenHeZhuangTaiGaiBian(auditFlag, TokenUtil.getInstance().getTokenUserId(), actOrderNo, auditRemark);
            obj.put("message", String.format("用户【%s】，医嘱号为【%s】数据撤回，<br >撤回原因：%s。", pojo.getProposerName(), actOrderNo, auditRemark));
            obj.put("type", "error");
            log.info("医嘱修改审核 --> 操作：{数据撤回成功},操作人员：{},数据：{}", TokenUtil.getInstance().getTokenUserId(), JSON.toJSONStringWithDateFormat(pojo, GetDateFormat.DATE_TIME));
        }
        String message = SocketMsg.socketVo(Message.SYSTEM_NOTIFICATION, obj);
        WebSocketByUserCode webSocketBySid = new WebSocketByUserCode(pojo.getProposer(), message);
        socket.sendMessageByUserCode(webSocketBySid);
        return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE, "审核成功，已通知申请人员。");
    }

    public Boolean judgeTheTime(TYzActOrderModify pojo) {
        if (pojo.getNewEndTime() != null) {
            if (pojo.getNewStartTime() != null) {
                return pojo.getNewEndTime().getTime() < pojo.getNewStartTime().getTime();
            } else {
                return pojo.getNewEndTime().getTime() < pojo.getStartTime().getTime();
            }
        }
        return false;
    }
}
