package thyyxxk.webserver.service.inpatient;

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 thyyxxk.webserver.config.exception.ExceptionEnum;
import thyyxxk.webserver.constants.sidicts.MedType;
import thyyxxk.webserver.dao.his.inpatient.ChargeListDao;
import thyyxxk.webserver.entity.ResultVo;
import thyyxxk.webserver.entity.inpatient.chargelist.BriefPatInfo;
import thyyxxk.webserver.entity.inpatient.chargelist.ChargeItem;
import thyyxxk.webserver.entity.inpatient.chargelist.PatOverview;
import thyyxxk.webserver.service.externalhttp.SiZySrvc;
import thyyxxk.webserver.service.redislike.RedisLikeService;
import thyyxxk.webserver.utils.ResultVoUtil;

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

@Slf4j
@Service
public class ChargeListService {
    private final ChargeListDao dao;
    private final RedisLikeService redis;
    private final SiZySrvc zySrvc;
    @Value("${si-zy-fee-url}")
    private String siZyFeeUrl;

    @Autowired
    public ChargeListService(ChargeListDao dao, RedisLikeService redis, SiZySrvc zySrvc) {
        this.dao = dao;
        this.redis = redis;
        this.zySrvc = zySrvc;
    }

    public List<PatOverview> selectPatOverviews(String patNo) {
        return dao.selectPatOverviews(patNo);
    }

    public BriefPatInfo selectBriefPatInfo(PatOverview overview) {
        BriefPatInfo briefPatInfo = dao.selectBriefPatInfo(overview.getPatNo(), overview.getTimes(), "zy_actpatient");
        if (null == briefPatInfo) {
            briefPatInfo = dao.selectBriefPatInfo(overview.getPatNo(), overview.getTimes(), "zy_inactpatient");
        }
        if (null != briefPatInfo) {
            briefPatInfo.setMedtype(MedType.getName(briefPatInfo.getMedtype()));
            briefPatInfo.setDept(redis.getDeptName(briefPatInfo.getDept()));
            if (briefPatInfo.getDays() < 1) {
                briefPatInfo.setDays(1);
            }
        }
        return briefPatInfo;
    }

    public Map<String, Object> selectChargeList(PatOverview overview) {
        List<ChargeItem> chargeList = dao.selectChargeList(overview.getPatNo(), overview.getTimes());
        Map<String, List<ChargeItem>> chargeListMap = new HashMap<>();
        Map<String, BigDecimal> sumsTempMap = new HashMap<>();
        sumsTempMap.put("总计", BigDecimal.ZERO);
        for (ChargeItem chargeItem : chargeList) {
            String mapKey = chargeItem.getBillItemName();
            sumsTempMap.replace("总计", sumsTempMap.get("总计").add(chargeItem.getCost()));
            if (chargeListMap.containsKey(mapKey)) {
                chargeListMap.get(mapKey).add(chargeItem);
                sumsTempMap.replace(mapKey, sumsTempMap.get(mapKey).add(chargeItem.getCost()));
            } else {
                List<ChargeItem> tempList = new ArrayList<>();
                tempList.add(chargeItem);
                chargeListMap.put(mapKey, tempList);
                sumsTempMap.put(mapKey, chargeItem.getCost());
            }
        }
        Map<String, String> sumsMap = new HashMap<>();
        for (Map.Entry<String, BigDecimal> entry : sumsTempMap.entrySet()) {
            sumsMap.put(entry.getKey(), entry.getValue().setScale(2, RoundingMode.HALF_DOWN).toString());
        }
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("chargeList", chargeListMap);
        resultMap.put("sumsMap", sumsMap);
        return resultMap;
    }

    public ResultVo<String> executeSelfpayUpload(BriefPatInfo patInfo) {
        String patNo = patInfo.getPatNo();
        int times = patInfo.getTimes();
        int inhospCount = dao.selectInhospCount(patNo, times);
        if (inhospCount > 0) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "此患者本次住院没有出院，不允许上传自费费用。");
        }
        List<Integer> siLedgers = dao.selectSiLedgers(patNo, times);
        List<Integer> allLedgers = dao.selectAllLedgers(patNo, times);
        allLedgers.removeIf(siLedgers::contains);
        if (allLedgers.isEmpty()) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "此患者本次住院不是自费住院，不允许上传自费费用。");
        }
        StringBuilder message = new StringBuilder();
        for (int ledgerSn : allLedgers) {
            patInfo.setLedgerSn(ledgerSn);
            JSONObject uploadResult = zySrvc.uploadSelfpayFees(siZyFeeUrl, patInfo);
            if (null != uploadResult && null != uploadResult.getInteger("code") && uploadResult.getInteger("code") == 0) {
                message.append("【账页").append(ledgerSn).append("】上传成功。");
            } else {
                message.append("【账页").append(ledgerSn).append("】上传失败。");
            }
        }
        return ResultVoUtil.success(message.toString());
    }

}
