package thyyxxk.webserver.service.zhuyuanyiji;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import thyyxxk.webserver.config.exception.ExceptionEnum;
import thyyxxk.webserver.dao.his.zhuyuanyiji.MenZhengXiangMuDao;
import thyyxxk.webserver.entity.ResultVo;
import thyyxxk.webserver.entity.datamodify.MzChargeDetail;
import thyyxxk.webserver.utils.*;

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

/**
 * <p>
 * 描述： 门诊项目确认或取消
 * </p>
 *
 * @author xc
 * @date 2021-10-09 15:16
 */
@Service
@Slf4j
@Data
public class MenZhengXiangMuServer {
    private final MenZhengXiangMuDao dao;

    public MenZhengXiangMuServer(MenZhengXiangMuDao dao) {
        this.dao = dao;
    }

    public ResultVo<List<MzChargeDetail>> kuaiSuChaZhao(String startTime, String endTime, String execDept) {
        if (StringUtil.isBlank(startTime) || StringUtil.isBlank(endTime) || StringUtil.isBlank(execDept)) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "请选择日期范围。");
        }
        log.info("快速查找：开始：{}，结束：{}，科室：{}", startTime, endTime, execDept);
        return ResultVoUtil.success(dao.kuaiSuChaZhao(startTime, endTime, execDept));
    }

    // 0 - 未确认 1 - 确认 3 -  取消
    public ResultVo<MzChargeDetail> getMzPatient(String patientId, Integer xiangMuZhuangTai, String startTime, String endTime, String dept) {
        if (StringUtil.isBlank(patientId)) {
            return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "门诊号不能为空 <(￣ ﹌ ￣)>  ");
        }
        if (StringUtil.isBlank(startTime) || StringUtil.isBlank(endTime)) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "请选择日期范围。");
        }
        MzChargeDetail mz = dao.getMzPatient(patientId);
        log.info("查询门诊项目确认 门诊id：{}，项目状态：{}，开始时间：{}，结束时间：{}", patientId, xiangMuZhuangTai, startTime, endTime);
        if (mz == null) {
            return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST);
        }
        mz.setList(dao.huoQuMenZhenQueRenShuJu(patientId, startTime, endTime, xiangMuZhuangTai));
        return ResultVoUtil.success(mz);
    }

    public ResultVo<Map<String, List<MzChargeDetail>>> getFeiYongXinXi(Integer realNo, String patientId, Integer times, Integer xiangMuZhuangTai) {
        log.info("流水号：{},门诊号：{}，次数：{} ", realNo, patientId, times);
        if (realNo == null || StringUtil.isBlank(patientId) || times == null) {
            return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER);
        }
        List<MzChargeDetail> feiYongXinXi = dao.feiYongXinXi(realNo, patientId, times, xiangMuZhuangTai);
        List<MzChargeDetail> yaoPinXinxi = dao.yaoPinXinxi(realNo, patientId, times);
        if (ListUtil.isBlank(feiYongXinXi) && ListUtil.isBlank(yaoPinXinxi)) {
            return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST);
        }
        //   父节点 根据  patient_id times receipt_no order_no charge_item_code
        //   子节点 根据  patient_id times receipt_no order_no tc_no
        List<MzChargeDetail> treeFeiYongXinXi = tcTree(feiYongXinXi);
        Map<String, List<MzChargeDetail>> map = new HashMap<>();
        map.put("f", treeFeiYongXinXi);
        map.put("y", yaoPinXinxi);
        return ResultVoUtil.success(map);
    }

    public ResultVo<JSONObject> getReqDetailsByNo(String patientId, Integer reqNo) {
        return ResultVoUtil.success(dao.getReqDetailsByNo(patientId ,reqNo ));
    }

    public List<MzChargeDetail> tcTree(List<MzChargeDetail> tempList) {
        if (ListUtil.isBlank(tempList)) {
            return new ArrayList<>();
        }
        List<MzChargeDetail> resultList = new ArrayList<>();
        Map<String, MzChargeDetail> treeMap = new HashMap<>(tempList.size());

        for (MzChargeDetail item : tempList) {
            String key = item.getPatientId() + item.getTimes() + item.getReceiptNo() + item.getOrderNo() + item.getChargeItemCode();
            treeMap.put(key, item);
            if (BigUtils.bigDaYu(item.getUnitPrice(), BigDecimal.ZERO)) {
                item.setChargeFeeNew(item.getUnitPrice().multiply(item.getQuantity()).multiply(item.getDrugWin()));
            }
            if ("TC".equals(item.getBillItemCode())) {
                item.setChargeName(item.getTcName() + "（套餐）");
                resultList.add(item);
            }
        }

        for (MzChargeDetail item : tempList) {
            String key = item.getPatientId() + item.getTimes() + item.getReceiptNo() + item.getOrderNo() + item.getTcNo();
            MzChargeDetail template = treeMap.get(key);
            if (template != null) {
                if (template.getList() == null) {
                    template.setList(new ArrayList<>());
                }
                if (template.getChargeFeeNew() == null) {
                    template.setChargeFeeNew(BigDecimal.ZERO);
                }
                template.setChargeFeeNew(template.getChargeFeeNew().add(item.getUnitPrice().multiply(item.getQuantity()).multiply(item.getDrugWin())));
                template.getList().add(item);
            } else if (!resultList.contains(item)) {
                resultList.add(item);
            }
        }

        return resultList;
    }

    public ResultVo<List<MzChargeDetail>> getMingXi(MzChargeDetail param) {
        log.info("门诊信息：{}", JSON.toJSONString(param));
        List<MzChargeDetail> list = new ArrayList<>();
        if (param.getReqNo() > 0) {
            list.addAll(dao.getMingXi(param.getPatientId(), param.getTimes(), param.getReqNo()));
        }
        return ResultVoUtil.success(list);
    }

    /**
     * -- 0 不操作 1 确认 3 取消
     *
     * @param mz 需要执行的数据
     * @return 返回提示
     */
    @Transactional(rollbackFor = Exception.class)
    public ResultVo<String> menZhenXiangMuQueXiaoHuoQueRen(MzChargeDetail mz) {
        if (ListUtil.notBlank(mz.getList()) && mz.getList().size() > 100) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "一次性操作不能大于 100 条，且不能为空。");
        }
        List<MzChargeDetail> confirmationFee = mz.getList();
        List<MzChargeDetail> flatData = new ArrayList<>();
        for (MzChargeDetail parentNode : confirmationFee) {
            Integer confirmationSign = parentNode.getConfirmFlag();
            List<MzChargeDetail> childNode = parentNode.getList();
            parentNode.setList(null);
            if (confirmationSign != null && confirmationSign != 0) {
                flatData.add(parentNode);
                if (ListUtil.notBlank(childNode)) {
                    childNode.forEach(item -> {
                        item.setConfirmFlag(confirmationSign);
                        flatData.add(item);
                    });
                }
            }
        }
        if (ListUtil.notBlank(flatData)) {
            dao.xiangMuQueRenHuoQuXiao(flatData, TokenUtil.getInstance().getTokenUserId(), mz.getExecDept());
            dao.xiangMuQueRenYjReq(flatData, TokenUtil.getInstance().getTokenUserId(), mz.getExecDept());
            return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE);
        }
        return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "请选择需要操作的数据");
    }

}
