package thyyxxk.webserver.service.inpatient.makedbzfees;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import thyyxxk.webserver.config.exception.ExceptionEnum;
import thyyxxk.webserver.constants.Capacity;
import thyyxxk.webserver.dao.his.inpatient.makedbzfees.MakeDbzFeesDao;
import thyyxxk.webserver.entity.ResultVo;
import thyyxxk.webserver.entity.makedbzfees.*;
import thyyxxk.webserver.service.externalhttp.ThmzSystem;
import thyyxxk.webserver.utils.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author dj
 */
@Slf4j
@Service
public class MakeDbzFeesService {
    private final MakeDbzFeesDao dao;
    private final static int PATIENT_ID = 2;
    private final ThmzSystem thmz;
    @Value("${thmz-api-url}")
    private String thmzApiUrl;

    @Autowired
    public MakeDbzFeesService(MakeDbzFeesDao dao, ThmzSystem thmz) {
        this.dao = dao;
        this.thmz = thmz;
    }

    public ResultVo<Map<String, Object>> getReceipts(GetMzFeesParam param) {
        String patientId = param.getCardNo();
        if (1 == param.getCardType()) {
            patientId = dao.getPatientId(param.getCardNo());
        }
        if (StringUtil.isBlank(patientId)) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "没有找到门诊id！");
        }
        JSONObject obj = new JSONObject();
        obj.put("patCardType", 21);
        obj.put("patCardNo", patientId);
        obj.put("hisOrdNum", null);
        Map<String, Object> hrgRes = thmz.getMzChargeDetailForUnPaid(thmzApiUrl, obj);
        if (null == hrgRes) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "网络服务错误！");
        }
        if ((int) hrgRes.get("resultCode") != 0) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, hrgRes.get("resultMessage").toString());
        }
        List<Map<String, String>> hisOrdNums = FilterUtil.cast(hrgRes.get("data"));
        Map<String, Object> resultMap = new HashMap<>(Capacity.TWO);
        Map<String, Object> receiptMap = new HashMap<>(hisOrdNums.size());
        for (Map<String, String> item : hisOrdNums) {
            String hisOrdNum = item.get("hisOrdNum");
            List<Map<String, String>> receipts = new ArrayList<>();
            String[] str = hisOrdNum.split("_");
            JSONObject p = new JSONObject();
            p.put("patientId", str[0]);
            p.put("times", str[1]);
            p.put("receiptNo", str[2]);
            Map<String, Object> hrgResponse = thmz.unPaidToFullChargeDetail(thmzApiUrl, p);
            if (null == hrgResponse) {
                return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "网络服务错误！");
            }
            if ((int) hrgResponse.get("resultCode") != 0) {
                return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, hrgResponse.get("resultMessage").toString());
            }
            List<Map<String, String>> details = FilterUtil.cast(hrgResponse.get("data"));
            for (Map<String, String> pojo : details) {
                if (!"TC".equals(pojo.get("billItemCode")) && "5".equals(pojo.get("payMark")) && !"舍尾金额".equals(pojo.get("tcName"))) {
                    pojo.replace("priceTime", DateUtil.formatPriceTime(pojo.get("priceTime")));
                    // groupNo：00-项目；其他-药品
                    if ("00".equals(pojo.get("groupNo"))) {
                        pojo.put("drugUnit", dao.selectXmChargeUnit(pojo.get("chargeItemCode")));
                    } else {
                        if (null != pojo.get("serial")) {
                            pojo.put("specification", dao.selectSpecification(pojo.get("chargeItemCode"), pojo.get("serial")));
                        }
                        if (null != pojo.get("supplyCode")) {
                            pojo.put("supplyName", dao.selectSupplyName(pojo.get("supplyCode")));
                        }
                        if (null != pojo.get("drugUnit")) {
                            pojo.put("drugUnit", dao.selectDrugUnit(pojo.get("drugUnit")));
                        }
                    }
                    receipts.add(pojo);
                }
            }
            receiptMap.put(hisOrdNum, receipts);
        }
        resultMap.put("hisOrdNums", hisOrdNums);
        resultMap.put("receipts", receiptMap);
        return ResultVoUtil.success(resultMap);
    }

    @Transactional(rollbackFor = Exception.class)
    public ResultVo<String> saveToZyFees(SaveZyFeesParam param) {
        String inpatientNo = param.getCardNo();
        if (param.getCardType() == PATIENT_ID) {
            inpatientNo = dao.getInpatientNo(param.getCardNo());
        }
        if (StringUtil.isBlank(inpatientNo)) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "没有找到此患者的住院号！请确认患者有住院身份。");
        }
        InpatientInfo inpatientInfo = dao.getInpatientInfo(inpatientNo);
        if (null == inpatientInfo) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "没有找到此患者的在院信息！请确认此患者已经办理住院。");
        }
        if ("1090000".equals(inpatientInfo.getDeptCode())) {
            inpatientInfo.setWardCode("1090000");
        }
        inpatientInfo.setStaffId(TokenUtil.getInstance().getTokenUserId());
        AtomicInteger detailSn = new AtomicInteger(inpatientInfo.getMaxDetailSn());
        List<ZyDetailCharge> zyFees = new ArrayList<>();
        for (MzChargeDetail mzFee : param.getReceipts()) {
            if ("TC".equalsIgnoreCase(mzFee.getBillItemCode())) {
                continue;
            }
            ZyDetailCharge zyFee = new ZyDetailCharge();
            zyFee.setChargeCodeMx(mzFee.getChargeItemCode());
            if ("00".equals(mzFee.getGroupNo())) {
                zyFee.setChargeCode(mzFee.getChargeItemCode());
            } else if ("81".equals(mzFee.getGroupNo()) || "82".equals(mzFee.getGroupNo()) || "83".equals(mzFee.getGroupNo())) {
                zyFee.setChargeCode("BILL01");
            } else {
                zyFee.setChargeCode("BILL02");
            }
            zyFee.setDetailSn(detailSn.incrementAndGet());
            zyFee.setChargeFee(mzFee.getChargeFee());
            zyFee.setChargeAmount(mzFee.getQuantity());
            zyFee.setSerial(mzFee.getSerial());
            zyFee.setDoctorCode(mzFee.getDoctorCode());
            zyFee.setExecDept(mzFee.getExecDept());
            zyFees.add(zyFee);
        }
        batchIntoZyDetailCharge(zyFees, inpatientInfo);
        JSONObject pay = new JSONObject();
        pay.put("patientId", param.getHisOrdNum().split("_")[0]);
        pay.put("times", param.getHisOrdNum().split("_")[1]);
        pay.put("receiptNo", param.getHisOrdNum().split("_")[2]);
        Map<String, Object> hrgResponse = thmz.payChargeDetailFormDbzsf(thmzApiUrl, pay);
        log.info("保存单病种缴费：{}", hrgResponse);
        if (null == hrgResponse) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "网络服务错误！");
        }
        if ((int) hrgResponse.get("resultCode") != 0) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, hrgResponse.get("resultMessage").toString());
        }
        return ResultVoUtil.success();
    }

    private void batchIntoZyDetailCharge(List<ZyDetailCharge> zyFees, InpatientInfo inpatientInfo) {
        if (zyFees.size() <= Capacity.TWENTY) {
            dao.insertZyDetailChargeForSingleDisease(inpatientInfo, zyFees);
        } else {
            List<ZyDetailCharge> tempList = new ArrayList<>();
            for (ZyDetailCharge item : zyFees) {
                tempList.add(item);
                if (tempList.size() == 20) {
                    dao.insertZyDetailChargeForSingleDisease(inpatientInfo, tempList);
                    tempList.clear();
                }
            }
            if (!tempList.isEmpty()) {
                dao.insertZyDetailChargeForSingleDisease(inpatientInfo, tempList);
            }
        }
    }
}
