package thyyxxk.webserver.service.reports;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import thyyxxk.webserver.config.exception.ExceptionEnum;
import thyyxxk.webserver.dao.his.reports.KeShiShouRuDao;
import thyyxxk.webserver.entity.ResultVo;
import thyyxxk.webserver.entity.datamodify.GetDropdownBox;
import thyyxxk.webserver.entity.querydata.KeShiFeiiYongTongJi;
import thyyxxk.webserver.entity.querydata.QueryDrugsAndProjects;
import thyyxxk.webserver.service.PublicServer;
import thyyxxk.webserver.utils.DateUtil;
import thyyxxk.webserver.utils.ExcelUtil;
import thyyxxk.webserver.utils.ResultVoUtil;
import thyyxxk.webserver.utils.StringUtil;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 描述： 各个科室收入的情况
 * </p>
 *
 * @author xc
 * @date 2021-10-19 14:50
 */
@Service
@Slf4j
public class KeShiShouRuServer {

    private final KeShiShouRuDao dao;

    private final PublicServer publicServer;

    public KeShiShouRuServer(KeShiShouRuDao dao, PublicServer publicServer) {
        this.dao = dao;
        this.publicServer = publicServer;
    }


    public ResultVo<KeShiFeiiYongTongJi> getKeShouFei(QueryDrugsAndProjects param) {
        if (StringUtil.isBlank(param.getStartTime()) || StringUtil.isBlank(param.getEndTime())) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "开始时间和结束时间为空 ∑(っ°Д°;)っ");
        }

        KeShiFeiiYongTongJi qp = new KeShiFeiiYongTongJi();
        log.info("查询科室收费统计 ==> 执行科室：{},开始{},结束：{}。项目编码：{}，录入人：{}，申请科室：{},总数：{}，当前页：{}，页大小：{}",
                param.getExecUnitList(), param.getStartTime(), param.getEndTime(),
                param.getChargeCodeMx(), param.getOpId(), param.getReqDeptCode(), param.getTotal(), param.getCurrentPage(), param.getPageSize());
        List<String> keShiLieBiao = publicServer.getKeShiLieBiaoList(param.getExecUnitList());
        GetDropdownBox renHuanCodeHeCodeRs = new GetDropdownBox();
        if (StringUtil.notBlank(param.getOpId())) {
            renHuanCodeHeCodeRs = dao.huoQuRenYuanDeCodeHeCodeRs(param.getOpId());
        }
        String huanZheBiao = "zy_patient";
        Page<KeShiFeiiYongTongJi> page;
        if (param.getTotal() > 0) {
            page = new Page<>(param.getCurrentPage(), param.getPageSize(), false);
        } else {
            page = new Page<>(param.getCurrentPage(), param.getPageSize());
        }
        if (param.getLaiYuan() == 0) {
            switch (param.getFenLei()) {
                case 0:
                    qp.setData(dao.getZhuYuanFeiYongXiangMuFenLei(page, keShiLieBiao, param.getStartTime(),
                            param.getEndTime(), param.getChargeCodeMx(), renHuanCodeHeCodeRs.getCode(), renHuanCodeHeCodeRs.getCodeRs(),
                            param.getReqDeptCode(), "CONVERT(varchar(100), charge_date, 23) charge_date_string"));
                    qp.setTotal(page.getTotal());
                    break;
                case 1:
                    qp.setData(dao.getZhuYuanFeiYongXiangMuFenLei(page, keShiLieBiao, param.getStartTime(),
                            param.getEndTime(), param.getChargeCodeMx(), renHuanCodeHeCodeRs.getCode(), renHuanCodeHeCodeRs.getCodeRs(),
                            param.getReqDeptCode(), "op_id_code"));
                    qp.setTotal(page.getTotal());
                    break;
                case 2:
                    qp.setData(dao.getZhuYuanFeiYongXiangMuFenLei(page, keShiLieBiao, param.getStartTime(),
                            param.getEndTime(), param.getChargeCodeMx(), renHuanCodeHeCodeRs.getCode(), renHuanCodeHeCodeRs.getCodeRs(),
                            param.getReqDeptCode(), "charge_code_mx"));
                    qp.setTotal(page.getTotal());
                    break;
                default:
                    if (param.getTotal() == 0) {
                        qp = dao.getKeShiFeiYongZhuYuanTotal(keShiLieBiao, param.getStartTime(), param.getEndTime(),
                                param.getChargeCodeMx(), renHuanCodeHeCodeRs.getCode(), renHuanCodeHeCodeRs.getCodeRs(), param.getReqDeptCode());
                    }
                    qp.setData(dao.getKeShiFeiYongZhuYuan(param.getCurrentPage(), param.getPageSize(), keShiLieBiao, param.getStartTime(), param.getEndTime(),
                            param.getChargeCodeMx(), renHuanCodeHeCodeRs.getCode(), renHuanCodeHeCodeRs.getCodeRs(), param.getReqDeptCode()));
                    break;
            }
        } else {
            huanZheBiao = "mz_patient_mi";
            switch (param.getFenLei()) {
                case 0:
                    qp.setData(dao.getMenZhenFeiYongXiangMuFenLei(page, keShiLieBiao, param.getStartTime(), param.getEndTime(),
                            param.getChargeCodeMx(), renHuanCodeHeCodeRs.getCode(), renHuanCodeHeCodeRs.getCodeRs(), param.getReqDeptCode(), "CONVERT(varchar(100),charge_date, 23)"));
                    qp.setTotal(page.getTotal());
                    break;
                case 1:
                    qp.setData(dao.getMenZhenFeiYongXiangMuFenLei(page, keShiLieBiao, param.getStartTime(), param.getEndTime(),
                            param.getChargeCodeMx(), renHuanCodeHeCodeRs.getCode(), renHuanCodeHeCodeRs.getCodeRs(), param.getReqDeptCode(), "confirm_id"));
                    qp.setTotal(page.getTotal());
                    break;
                case 2:
                    qp.setData(dao.getMenZhenFeiYongXiangMuFenLei(page, keShiLieBiao, param.getStartTime(), param.getEndTime(),
                            param.getChargeCodeMx(), renHuanCodeHeCodeRs.getCode(), renHuanCodeHeCodeRs.getCodeRs(), param.getReqDeptCode(), "charge_item_code"));
                    qp.setTotal(page.getTotal());
                    break;
                default:
                    if (param.getTotal() == 0) {
                        qp = dao.getMenZhenFeiYongTotal(keShiLieBiao, param.getStartTime(), param.getEndTime(),
                                param.getChargeCodeMx(), renHuanCodeHeCodeRs.getCode(), renHuanCodeHeCodeRs.getCodeRs(), param.getReqDeptCode());
                    }
                    qp.setData(dao.getMenZhenFeiYong(param.getCurrentPage(), param.getPageSize(), keShiLieBiao, param.getStartTime(), param.getEndTime(),
                            param.getChargeCodeMx(), renHuanCodeHeCodeRs.getCode(), renHuanCodeHeCodeRs.getCodeRs(), param.getReqDeptCode()));
                    break;
            }
        }
        pingJieZiDuanMingChen(qp, huanZheBiao);
        return ResultVoUtil.success(qp);
    }

    private void pingJieZiDuanMingChen(KeShiFeiiYongTongJi qp, String huanZheBiao) {
        if (qp.getData() != null && !qp.getData().isEmpty()) {
            Set<String> huanZheHaoSet = new HashSet<>();
            Set<String> keShiSet = new HashSet<>();
            Set<String> xiangMuSet = new HashSet<>();
            Set<String> luRuRenSet = new HashSet<>();

            qp.getData().forEach(item -> {
                huanZheHaoSet.add(item.getPatient());
                keShiSet.add(item.getExecUnit());
                keShiSet.add(item.getWardCode());
                xiangMuSet.add(item.getChargeCodeMx());
                luRuRenSet.add(item.getOpIdCode());
            });


            Map<String, String> huanZheXingMingMap = dao.huanZheXingMing(huanZheHaoSet, huanZheBiao)
                    .stream()
                    .collect(Collectors.toMap(GetDropdownBox::getCode, GetDropdownBox::getName, (key1, key2) -> key1));
            Map<String, String> xiangMuMingChenMap = dao.xiangMuMingChen(xiangMuSet)
                    .stream()
                    .collect(Collectors.toMap(GetDropdownBox::getCode, GetDropdownBox::getName, (key1, key2) -> key1));

            Map<String, String> huoQuKeShiMap = dao.huoQuKeShiHuoRenYuan(keShiSet, "zd_unit_code")
                    .stream()
                    .collect(Collectors.toMap(GetDropdownBox::getCode, GetDropdownBox::getName, (key1, key2) -> key1));

            // 获取人员信息
            List<GetDropdownBox> RenYuan = dao.huoQuKeShiHuoRenYuan(luRuRenSet, "a_employee_mi");
            // 第一次用 code 匹配
            Map<String, String> luRuRenXingMingMap = RenYuan
                    .stream()
                    .collect(Collectors.toMap(GetDropdownBox::getCode, GetDropdownBox::getName, (key1, key2) -> key1));

            // 第二次用 code_rs 匹配
            Map<String, String> luRuRenXingMingRenShiMap = RenYuan
                    .stream()
                    .collect(Collectors.toMap(GetDropdownBox::getCodeRs, GetDropdownBox::getName, (key1, key2) -> key1));

            qp.getData().forEach(item -> {
                if (huanZheXingMingMap.containsKey(item.getPatient())) {
                    item.setPatientName(huanZheXingMingMap.get(item.getPatient()));
                }
                if (xiangMuMingChenMap.containsKey(item.getChargeCodeMx())) {
                    item.setChargeCodeName(xiangMuMingChenMap.get(item.getChargeCodeMx()));
                }
                if (huoQuKeShiMap.containsKey(item.getExecUnit())) {
                    item.setExecUnitName(huoQuKeShiMap.get(item.getExecUnit()));
                }
                if (huoQuKeShiMap.containsKey(item.getWardCode())) {
                    item.setWardCodeName(huoQuKeShiMap.get(item.getWardCode()));
                }
                if (luRuRenXingMingMap.containsKey(item.getOpIdCode())) {
                    item.setOpName(luRuRenXingMingMap.get(item.getOpIdCode()));
                } else if (luRuRenXingMingRenShiMap.containsKey(item.getOpIdCode())) {
                    item.setOpName(luRuRenXingMingRenShiMap.get(item.getOpIdCode()));
                } else {
                    item.setOpName(item.getOpIdCode());
                }
            });
        }
    }

    public void exportExcel(HttpServletResponse response, QueryDrugsAndProjects param) {
        double pageSize = 1000;
        double currentPage = param.getTotal() / pageSize;
        int fenDuan = (int) Math.ceil(currentPage);
        List<KeShiFeiiYongTongJi> keShiFeiiYongTongJisList = new ArrayList<>();
        param.setPageSize(1000);
        for (long i = 0; i < fenDuan; i++) {
            param.setCurrentPage(i + 1);
            keShiFeiiYongTongJisList.addAll(getKeShouFei(param).getData().getData());
        }

        String[] title;
        if (param.getFenLei() == 3) {
            title = new String[]{"患者姓名", "住院/门诊号", "次数", "项目编码", "项目名称", "收费日期", "录入人", "执行科室", "申请科室", "金额", "数量", "来源"};
        } else {
            title = new String[]{param.getFenLei() == 0 ? "日期" : param.getFenLei() == 1 ? "录入人" : "项目编码", "金额", "数量", "来源"};
        }
        String[][] content = new String[keShiFeiiYongTongJisList.size()][];
        for (int i = 0; i < keShiFeiiYongTongJisList.size(); i++) {
            content[i] = new String[title.length];
            KeShiFeiiYongTongJi pojo = keShiFeiiYongTongJisList.get(i);
            if (param.getFenLei() == 3) {
                content[i][0] = pojo.getPatientName();
                content[i][1] = pojo.getPatient();
                content[i][2] = pojo.getTimes().toString();
                content[i][3] = pojo.getChargeCodeMx();
                content[i][4] = pojo.getChargeCodeName();
                content[i][5] = DateUtil.formatDatetime(pojo.getChargeDate());
                content[i][6] = pojo.getOpName();
                content[i][7] = pojo.getExecUnitName();
                content[i][8] = pojo.getWardCodeName();
                content[i][9] = pojo.getChargeFee().toString();
                content[i][10] = pojo.getChargeAmount().toString();
                content[i][11] = pojo.getSource();
            } else {
                content[i][0] = param.getFenLei() == 0 ? pojo.getChargeDateString() : param.getFenLei() == 1 ? pojo.getOpName() : pojo.getChargeCodeName();
                content[i][1] = pojo.getChargeFee().toString();
                content[i][2] = pojo.getChargeAmount().toString();
                content[i][3] = pojo.getSource();
            }
        }
        ExcelUtil.exportExcel(response, title, content);
    }


}
