package thyyxxk.webserver.service.medicalinsurance;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import thyyxxk.webserver.dao.his.medicalinsurance.SiChargeLimitDao;
import thyyxxk.webserver.entity.medicalinsurance.inpatient.BriefChargeInfo;
import thyyxxk.webserver.entity.medicalinsurance.inpatient.SiLimitRequest;
import thyyxxk.webserver.entity.medicalinsurance.inpatient.ZdChargeLimitation;
import thyyxxk.webserver.utils.ListUtil;
import thyyxxk.webserver.utils.StringUtil;

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

@Service
public class SiChargeLimitService {
    private final SiChargeLimitDao dao;

    @Autowired
    public SiChargeLimitService(SiChargeLimitDao dao) {
        this.dao = dao;
    }

    public String analyzeSiChargeLimit(SiLimitRequest request) {
        String paramsError = checkRequestParams(request);
        if (null != paramsError) {
            return paramsError;
        }
        List<ZdChargeLimitation> limitations = dao.getChargeLimitations(request.getChargeList());
        if (limitations.isEmpty()) {
            return "OK";
        }
        StringBuilder builder = new StringBuilder();
        for (ZdChargeLimitation limit : limitations) {
            request.setCurrentCode(limit.getChargeCode());
            LinkedList<BriefChargeInfo> chargeList = dao.getChargeInfos(request);
            LinkedList<BriefChargeInfo> tempList = new LinkedList<>(chargeList);
            for (BriefChargeInfo charge : tempList) {
                Integer oriSn = charge.getOriSn();
                if (null != oriSn && oriSn != -1) {
                    chargeList.remove(charge);
                    chargeList.removeIf(ch -> Objects.equals(ch.getSn(), oriSn));
                }
            }
            tempList = new LinkedList<>(chargeList);
            for (BriefChargeInfo charge : tempList) {
                if (charge.getAmount().compareTo(BigDecimal.ZERO) < 0) {
                    Integer oriSn = getPairedOriSn(chargeList, charge);
                    if (null == oriSn) {
                        chargeList.remove(charge);
                    } else {
                        request.setOriSn(oriSn);
                        request.setSn(charge.getSn());
                        dao.updatePairSn(request);
                        chargeList.remove(charge);
                        chargeList.removeIf(ch -> Objects.equals(ch.getSn(), oriSn));
                    }
                }
            }

            List<String> dateList = new ArrayList<>();
            for (BriefChargeInfo charge: chargeList) {
                String date = charge.getDate();
                if (!dateList.contains(date)) {
                    dateList.add(date);
                }
            }
            if (dateList.size() >= limit.getLimitDay()) {
                String type = limit.getChargeCode().length() == 5 ? "药品【" : "项目【";
                String fact = dateList.size() == limit.getLimitDay() ? "即将超期支付（已支付" : "已经超期支付（已支付";
                builder.append(type)
                        .append(limit.getChargeName())
                        .append("（")
                        .append(limit.getChargeCode())
                        .append("）】限定支付")
                        .append(limit.getLimitDay())
                        .append("天，")
                        .append(fact)
                        .append(dateList.size())
                        .append("天）。")
                        .append("\r\n");
            }
        }

        if (builder.length() == 0) {
            return "OK";
        }
        return builder.toString();
    }

    private String checkRequestParams(SiLimitRequest request) {
        if (StringUtil.isBlank(request.getPatNo())) {
            return "参数错误：住院号不能为空！";
        }
        if (null == request.getTimes()) {
            return "参数错误：住院次数不能为空！";
        }
        if (null == request.getLedgerSn()) {
            return "参数错误：账页号不能为空！";
        }
        if (ListUtil.isBlank(request.getChargeList())) {
            return "参数错误：收费列表不能为空！";
        }
        return null;
    }

    private Integer getPairedOriSn(LinkedList<BriefChargeInfo> list, BriefChargeInfo charge) {
        for (BriefChargeInfo item : list) {
            BigDecimal sum = item.getAmount().add(charge.getAmount());
            if (sum.compareTo(BigDecimal.ZERO) == 0) {
                return item.getSn();
            }
        }
        return null;
    }

}
