package thyyxxk.webserver.service.inpatient;

import com.alibaba.fastjson.JSON;
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.Capacity;
import thyyxxk.webserver.constants.GetDateFormat;
import thyyxxk.webserver.dao.his.inpatient.TransferInOfExpensesDao;
import thyyxxk.webserver.entity.ResultVo;
import thyyxxk.webserver.entity.datamodify.GetDropdownBox;
import thyyxxk.webserver.entity.datamodify.MzChargeDetail;
import thyyxxk.webserver.entity.datamodify.ZyDetailCharge;
import thyyxxk.webserver.entity.inpatient.ZyActpatient;
import thyyxxk.webserver.entity.medicalinsurance.inpatient.ZyPatientInfo;
import thyyxxk.webserver.service.PublicServer;
import thyyxxk.webserver.utils.DateUtil;
import thyyxxk.webserver.utils.ResultVoUtil;
import thyyxxk.webserver.utils.TokenUtil;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 描述： 门急诊费用转入
 * </p>
 *
 * @author xc
 * @date 2021-05-25 17:35
 */
@Service
@Slf4j
public class TransferInOfExpensesService {

    private final TransferInOfExpensesDao dao;
    private final PublicServer publicServer;

    @Autowired
    public TransferInOfExpensesService(TransferInOfExpensesDao dao, PublicServer publicServer) {
        this.dao = dao;
        this.publicServer = publicServer;
    }

    /**
     * 查询再远患者信息
     *
     * @param inpatientNo 住院号
     * @return 返回一个信息
     */
    public ResultVo<ZyActpatient> queryHuanZhe(String inpatientNo) {
        log.info("查询患者信息-->住院号：{}", inpatientNo);
        ZyActpatient pojo = dao.queryHuanZhe(inpatientNo);
        if (pojo != null) {
            return ResultVoUtil.success(pojo);
        }
        return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, "没有找到该患者可能已出院，╮(╯▽╰)╭");
    }

    /**
     * 通过机制号来查找信息
     *
     * @param serialNo  机制号
     * @param liShiFlag 是否查看历史 0：不查看 1：查看
     * @return 返回信息
     */
    public ResultVo<List<MzChargeDetail>> getSerialNo(Integer serialNo, Integer liShiFlag) {
        List<MzChargeDetail> list;
        if (liShiFlag == 0) {
            list = dao.getSerialNo("mz_charge_detail", "mz_receipt_serial", serialNo);
        } else {
            list = dao.getSerialNo("mz_charge_detail_b", "mz_receipt_serial_b", serialNo);
        }
        if (list.size() > 0) {
            return ResultVoUtil.success(list);
        } else {
            return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST);
        }
    }

    /**
     * 查看患者是通过门急诊转入的费用项目
     *
     * @param inpatientNo 住院号
     * @param currentPage 当前页
     * @param pageSize    页数
     * @return 返回项目
     */
    public ResultVo<Map<String, Object>> getZyJiMenZhenZhuangRuFeiYong(String inpatientNo, String chargeCodeMX, String admissTimes, long currentPage, long pageSize) {
        Integer ledgerSn = publicServer.getLedgerSn(inpatientNo, Integer.valueOf(admissTimes));
        IPage<ZyDetailCharge> page = new Page<>(currentPage, pageSize);
        // 因为我这里用的是分页 所以才会这样
        List<ZyDetailCharge> list = dao.getZyJiMenZhenZhuangRuFeiYong(page, inpatientNo, chargeCodeMX, admissTimes, ledgerSn);
        List<ZyDetailCharge> sumList = dao.sumZyFee(inpatientNo, chargeCodeMX, admissTimes, ledgerSn);
        Map<String, Object> map = new HashMap<>(Capacity.TWO);
        if (page.getTotal() > 0 || list.size() > 0) {
            BigDecimal sum = new BigDecimal(0);
            for (ZyDetailCharge zyDetailCharge : sumList) {
                sum = sum.add(zyDetailCharge.getChargeFee().multiply(zyDetailCharge.getChargeAmount()));
            }
            map.put("data", list);
            map.put("total", page.getTotal());
            map.put("sum", sum);
            return ResultVoUtil.success(map);
        }
        return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST);
    }

    /**
     * 删除病人通过急门诊转入的费用 数据
     *
     * @param param 删除的条件
     * @return 返回是否成功
     */
    public ResultVo<String> shanChuFeiYong(ZyDetailCharge param) {
        log.info("删除该患者通过急门诊转入的费用 --> 操作员：{}， 通过主键来删除数据：{}", TokenUtil.getInstance().getTokenUserId(), JSON.toJSONStringWithDateFormat(param, GetDateFormat.DATE_TIME));
        dao.shanChuFeiYong(param);
        return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE, "删除成功 ୧(๑•̀◡•́๑)૭");
    }

    /**
     * 插入 通过急门诊转入的费用
     *
     * @param param 要插入的数据
     * @return 返回通知
     */
    public ResultVo<String> baoCunHuanZheZhuYuanFeiYong(ZyActpatient param) {
        param.setStaffId(TokenUtil.getInstance().getTokenUserId());
        List<MzChargeDetail> list = param.getList();
        //查询流水号
        Integer maxDetailSn = dao.getMaxDetailSn(param.getInpatientNo(), param.getAdmissTimes());
        ZyPatientInfo patInfo = dao.getPatientHospitalStay(param.getInpatientNo());
        if (patInfo == null) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "没有找到患者信息");
        }
        if (DateUtil.shiJianDaXiao(param.getChargeDate(), patInfo.getAdmissDate(), "<")) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "费用发生时间不能小于入院时间。");
        }

        if (patInfo.getDisDate() != null) {
            if (DateUtil.shiJianDaXiao(param.getChargeDate(), patInfo.getDisDate(), ">")) {
                return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "费用发生时间不能大于出院时间，患者出院时间为:" + DateUtil.formatDatetime(param.getDisDate()));
            }
        }

        // 流水号取出这个患者流水值的最大值 在加 1
        // 同时计算 出患者的总金额 以及 费用的类型
        list.removeIf(item -> "BILL99".equals(item.getChargeCodeMx()));
        for (MzChargeDetail mzChargeDetail : list) {
            if (mzChargeDetail.getChargeFee().compareTo(BigDecimal.ZERO) == 0) {
                return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "录入费用不得为 0");
            }
            mzChargeDetail.setDetailSn(maxDetailSn += 1);
        }
        dao.insertInfoZyDetailCharge(param, list);
        log.info("急门诊费用插入 --> 操作人：{} ， 数据：{}", param.getStaffId(), JSON.toJSONStringWithDateFormat(param, GetDateFormat.DATE_TIME));
        return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE, "操作成功。");
    }

    /**
     * 远程搜索 项目名称
     *
     * @param pyCode 拼音码 大写的
     * @return 返回多个项目的名称
     */
    public ResultVo<List<GetDropdownBox>> queryEntryName(String pyCode) {
        return ResultVoUtil.success(dao.queryEntryName("%" + pyCode.toUpperCase() + "%"));
    }
}
