package thyyxxk.webserver.service.highreport;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import thyyxxk.webserver.config.exception.ExceptionEnum;
import thyyxxk.webserver.dao.his.highreport.AllStatisticsDao;
import thyyxxk.webserver.dao.his.highreport.HighReportDao;
import thyyxxk.webserver.entity.HeadInfo;
import thyyxxk.webserver.entity.ResultVo;
import thyyxxk.webserver.entity.highreport.HighReportDto;
import thyyxxk.webserver.entity.highreport.ReportBaseInfo;
import thyyxxk.webserver.utils.DecimalUtil;
import thyyxxk.webserver.utils.ExcelUtil;
import thyyxxk.webserver.utils.ReportUtil;
import thyyxxk.webserver.utils.ResultVoUtil;
import thyyxxk.webserver.utils.StringUtil;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description: 全部报表
 * @Author: hsh
 * @CreateTime: 2023-05-11  10:53
 * @Version: 1.0
 */
@Service
@Slf4j
public class AllStatisticsService {

    private final AllStatisticsDao dao;

    private final HighReportDao highReportDao;

    @Autowired
    public AllStatisticsService(AllStatisticsDao dao, HighReportDao highReportDao) {
        this.dao = dao;
        this.highReportDao = highReportDao;
    }

    /**
     * @description: 工作量统计
     * @author: hsh
     * @date: 2023/5/11 11:07
     * @param: [dto]
     * @return: ResultVo<Map<String,Object>>
     **/
    public ResultVo<Map<String, Object>> selectWorkloadStatistics(HighReportDto dto){

        Map<String, Object> results = new HashMap<>();
        String mzFlag = dto.getMzFlag();
        boolean flag = "0".equals(mzFlag);

        // 查询门诊人数
        ReportBaseInfo report_mz = highReportDao.selectReportPortalMenu(flag ? "mz_mzrs" : "mz_mzrsjz", null, null);
        report_mz.setGatherSql(report_mz.getGatherSql() + " as rs_mz, t.dept as ks_mz ");
        String sql_mz = ReportUtil.callSqlFormat(dto, report_mz.getBaseSql(), report_mz.getGatherSql(), "dept", null, "rs_mz desc");
        List<Map<String, Object>> mzrs = highReportDao.selectReportPortalData(report_mz.getReportId(), report_mz.getMenuId(), report_mz.getReportType(), sql_mz);

        // 查询急诊人数
        ReportBaseInfo report_jz = highReportDao.selectReportPortalMenu(flag ? "mz_jzrs" : "mz_jzrsjz", null, null);
        report_jz.setGatherSql(report_jz.getGatherSql() + " as rs_jz, t.dept as ks_jz ");
        String sql_jz = ReportUtil.callSqlFormat(dto, report_jz.getBaseSql(), report_jz.getGatherSql(), "dept", null, "rs_jz desc");
        List<Map<String, Object>> jzrs = highReportDao.selectReportPortalData(report_jz.getReportId(), report_jz.getMenuId(), report_jz.getReportType(), sql_jz);

        // 查询退号人数
        ReportBaseInfo report_th = highReportDao.selectReportPortalMenu(flag ? "mz_thrs" : "mz_thrsjz", null, null);
        report_th.setGatherSql(report_th.getGatherSql() + " as rs_th, t.dept as ks_th ");
        String sql_th = ReportUtil.callSqlFormat(dto, report_th.getBaseSql(), report_th.getGatherSql(), "dept", null, "rs_th desc");
        List<Map<String, Object>> thrs = highReportDao.selectReportPortalData(report_th.getReportId(), report_th.getMenuId(), report_th.getReportType(), sql_th);

        // 查询入院人数
        ReportBaseInfo report_ry = highReportDao.selectReportPortalMenu("cy_ryrs", null, null);
        report_ry.setGatherSql(report_ry.getGatherSql() + " as rs_ry, t.dept as ks_ry ");
        String sql_ry = ReportUtil.callSqlFormat(dto, report_ry.getBaseSql(), report_ry.getGatherSql(), "dept", null, "rs_ry desc");
        List<Map<String, Object>> ryrs = highReportDao.selectReportPortalData(report_ry.getReportId(), report_ry.getMenuId(), report_ry.getReportType(), sql_ry);

        // 查询出院人数
        ReportBaseInfo report_cy = highReportDao.selectReportPortalMenu("cy_cyrs", null, null);
        report_cy.setGatherSql(report_cy.getGatherSql() + " as rs_cy, t.dept as ks_cy ");
        String sql_cy = ReportUtil.callSqlFormat(dto, report_cy.getBaseSql(), report_cy.getGatherSql(), "dept", null, "rs_cy desc");
        List<Map<String, Object>> cyrs = highReportDao.selectReportPortalData(report_cy.getReportId(), report_cy.getMenuId(), report_cy.getReportType(), sql_cy);

        // 在院人数
        ReportBaseInfo report_zy = highReportDao.selectReportPortalMenu("zy_zyrs", null, null);
        report_zy.setGatherSql(report_zy.getGatherSql() + " as rs_zy, t.dept as ks_zy ");
        String sql_zy = ReportUtil.callSqlFormat(dto, report_zy.getBaseSql(), report_zy.getGatherSql(), "dept", null, "rs_zy desc");
        List<Map<String, Object>> zyrs = highReportDao.selectReportPortalData(report_zy.getReportId(), report_zy.getMenuId(), report_zy.getReportType(), sql_zy);

        List<Map<String, Object>> list = new ArrayList<>();
        int count = Math.max(mzrs.size(), jzrs.size());

        if(count < thrs.size()){
            count = thrs.size();
        }

        if(count < ryrs.size()){
            count = ryrs.size();
        }

        if(count < cyrs.size()){
            count = cyrs.size();
        }

        if(count < zyrs.size()){
            count = zyrs.size();
        }

        int mzHj = 0;
        int jzHj = 0;
        int thHj = 0;
        int ryHj = 0;
        int cyHj = 0;
        int zyHj = 0;
        for (int i = 0; i < count; i++) {
            Map<String, Object> m = new HashMap<>();
            if(mzrs.size() > i){
                m.putAll(mzrs.get(i));
                mzHj = mzHj + Integer.parseInt(mzrs.get(i).get("rs_mz") == null ? "0" : String.valueOf(mzrs.get(i).get("rs_mz")));
            }
            if(jzrs.size() > i){
                m.putAll(jzrs.get(i));
                jzHj = jzHj + Integer.parseInt(jzrs.get(i).get("rs_jz") == null ? "0" : String.valueOf(jzrs.get(i).get("rs_jz")));
            }
            if(thrs.size() > i){
                m.putAll(thrs.get(i));
                thHj = thHj + Integer.parseInt(thrs.get(i).get("rs_th") == null ? "0" : String.valueOf(thrs.get(i).get("rs_th")));
            }
            if(ryrs.size() > i){
                m.putAll(ryrs.get(i));
                ryHj = ryHj + Integer.parseInt(ryrs.get(i).get("rs_ry") == null ? "0" : String.valueOf(ryrs.get(i).get("rs_ry")));
            }
            if(cyrs.size() > i){
                m.putAll(cyrs.get(i));
                cyHj = cyHj + Integer.parseInt(cyrs.get(i).get("rs_cy") == null ? "0" : String.valueOf(cyrs.get(i).get("rs_cy")));
            }
            if(zyrs.size() > i){
                m.putAll(zyrs.get(i));
                zyHj = zyHj + Integer.parseInt(zyrs.get(i).get("rs_zy") == null ? "0" : String.valueOf(zyrs.get(i).get("rs_zy")));
            }
            list.add(m);
        }

        // 添加合计
        Map<String, Object> hjm = new HashMap<>();
        hjm.put("ks_mz", "合计");
        hjm.put("rs_mz", mzHj);
        Map<String, Object> hj = new HashMap<>(hjm);

        hjm = new HashMap<>();
        hjm.put("ks_jz", "合计");
        hjm.put("rs_jz", jzHj);
        hj.putAll(hjm);

        hjm = new HashMap<>();
        hjm.put("ks_th", "合计");
        hjm.put("rs_th", thHj);
        hj.putAll(hjm);

        hjm = new HashMap<>();
        hjm.put("ks_ry", "合计");
        hjm.put("rs_ry", ryHj);
        hj.putAll(hjm);

        hjm = new HashMap<>();
        hjm.put("ks_cy", "合计");
        hjm.put("rs_cy", cyHj);
        hj.putAll(hjm);

        hjm = new HashMap<>();
        hjm.put("ks_zy", "合计");
        hjm.put("rs_zy", zyHj);
        hj.putAll(hjm);

        results.put("resultData", list);
        results.put("totalMap", hj);

        return ResultVoUtil.success(results);
    }

    /**
     * @description: 收入量统计
     * @author: hsh
     * @date: 2023/5/12 11:36
     * @param: [dto]
     * @return: ResultVo<Map<String,Object>>
     **/
    public ResultVo<Map<String, Object>> selectIncomeStatistics(HighReportDto dto) {

        Map<String, Object> results = new HashMap<>();

        // 查询门诊收入
        ReportBaseInfo report_mzsr = highReportDao.selectReportPortalMenu("mz_mzzsr", null, null);
        report_mzsr.setGatherSql(report_mzsr.getGatherSql() + " as mz_sr, t.dept as ks_sr ");
        String sql_mz_sr = ReportUtil.callSqlFormat(dto, report_mzsr.getBaseSql(), report_mzsr.getGatherSql(), "dept", null, "mz_sr desc");
        List<Map<String, Object>> mzSr = highReportDao.selectReportPortalData(report_mzsr.getReportId(), report_mzsr.getMenuId(), report_mzsr.getReportType(), sql_mz_sr);

        // 查询门诊药占比
        ReportBaseInfo report_mz_yzb = highReportDao.selectReportPortalMenu("mz_mzypfzb", null, null);
        report_mz_yzb.setGatherSql(report_mz_yzb.getGatherSql() + " as mz_yzb, sum(t.fy) as mz_zfy, sum(t.ypf) as mz_ypf, t.dept as ks_yzb ");
        String sql_mz_yzb = ReportUtil.callSqlFormat(dto, report_mz_yzb.getBaseSql(), report_mz_yzb.getGatherSql(), "dept", null, "mz_ypf desc");
        List<Map<String, Object>> mzYzb = highReportDao.selectReportPortalData(report_mz_yzb.getReportId(), report_mz_yzb.getMenuId(), report_mz_yzb.getReportType(), sql_mz_yzb);

        // 查询门诊耗占比
        ReportBaseInfo report_mz_hzb = highReportDao.selectReportPortalMenu("mz_mzclfzb", null, null);
        report_mz_hzb.setGatherSql(report_mz_hzb.getGatherSql() + " as mz_hzb, sum(t.fy) as mz_zfy, sum(t.clf) as mz_hcf, t.dept as ks_hzb ");
        String sql_mz_hzb = ReportUtil.callSqlFormat(dto, report_mz_hzb.getBaseSql(), report_mz_hzb.getGatherSql(), "dept", null, "mz_hcf desc");
        List<Map<String, Object>> mzHzb = highReportDao.selectReportPortalData(report_mz_hzb.getReportId(), report_mz_hzb.getMenuId(), report_mz_hzb.getReportType(), sql_mz_hzb);

        // 查询住院收入
        ReportBaseInfo report_zy_sr = highReportDao.selectReportPortalMenu("zy_zyzsr", null, null);
        report_zy_sr.setGatherSql(report_zy_sr.getGatherSql() + " as zy_sr, t.dept as ks_sr ");
        String sql_zy_sr = ReportUtil.callSqlFormat(dto, report_zy_sr.getBaseSql(), report_zy_sr.getGatherSql(), "dept", null, "zy_sr desc");
        List<Map<String, Object>> zySr = highReportDao.selectReportPortalData(report_zy_sr.getReportId(), report_zy_sr.getMenuId(), report_zy_sr.getReportType(), sql_zy_sr);

        // 查询住院药品费
        ReportBaseInfo report_zy_yzb = highReportDao.selectReportPortalMenu("zy_zyzypfzb", null, null);
        report_zy_yzb.setGatherSql(report_zy_yzb.getGatherSql() + " as zy_yzb, sum(t.zfy) as zy_zfy, sum(t.ypf) as zy_ypf, t.dept as ks_yzb ");
        String sql_zy_yzb = ReportUtil.callSqlFormat(dto, report_zy_yzb.getBaseSql(), report_zy_yzb.getGatherSql(), "dept", null, "zy_ypf desc");
        List<Map<String, Object>> zyYzb = highReportDao.selectReportPortalData(report_zy_yzb.getReportId(), report_zy_yzb.getMenuId(), report_zy_yzb.getReportType(), sql_zy_yzb);

        // 查询住院耗材费
        ReportBaseInfo report_zy_hzb = highReportDao.selectReportPortalMenu("zy_zyzclfzb", null, null);
        report_zy_hzb.setGatherSql(report_zy_hzb.getGatherSql() + " as zy_hzb, sum(t.zfy) as zy_zfy, sum(t.clf) as zy_hcf, t.dept as ks_hzb ");
        String sql_zy_hzb = ReportUtil.callSqlFormat(dto, report_zy_hzb.getBaseSql(), report_zy_hzb.getGatherSql(), "dept", null, "zy_hcf desc");
        List<Map<String, Object>> zyHzb = highReportDao.selectReportPortalData(report_zy_hzb.getReportId(), report_zy_hzb.getMenuId(), report_zy_hzb.getReportType(), sql_zy_hzb);

        // 整理收入数据: 各科室收入（分三种门诊+住院、门诊、住院）
        List<Map<String, Object>> ksSrList = new ArrayList<>();
        for(Map<String, Object> m1 : mzSr){
            String dept1 = String.valueOf(m1.get("ks_sr"));
            String mz_sr = String.valueOf(m1.get("mz_sr"));
            String all_sr = "0";
            boolean flag = true;
            for(Map<String, Object> m2 : zySr){
                String dept2 = String.valueOf(m2.get("ks_sr"));
                String zy_sr = String.valueOf(m2.get("zy_sr"));
                if(dept2.equals(dept1)){
                    m1.put("zy_sr", m2.get("zy_sr"));
                    all_sr = DecimalUtil.add(mz_sr, zy_sr);
                    flag = false;
                    break;
                }
            }
            if(flag){
                m1.put("all_sr", mz_sr);
                m1.put("zy_sr", 0);
            } else {
                m1.put("all_sr", all_sr);
            }
            ksSrList.add(m1);
        }

        for(Map<String, Object> m1 : zySr){
            String dept1 = String.valueOf(m1.get("ks_sr"));
            boolean flag = true;
            for(Map<String, Object> m2 : mzSr){
                String dept2 = String.valueOf(m2.get("ks_sr"));
                if(dept2.equals(dept1)){
                    flag = false;
                }
            }
            // 住院收入有而门诊收入没有的科室也要加上
            if(flag){
                String zy_sr = String.valueOf(m1.get("zy_sr"));
                m1.put("all_sr", zy_sr);
                m1.put("mz_sr", 0);
                ksSrList.add(m1);
            }
        }

        // 整理药占比数据: 各科室药占比（分三种门诊+住院、门诊、住院）
        List<Map<String, Object>> yzbList = new ArrayList<>();
        for(Map<String, Object> m1 : mzYzb){
            String dept1 = String.valueOf(m1.get("ks_yzb"));
            String mz_ypf = String.valueOf(m1.get("mz_ypf"));
            String mz_zfy = String.valueOf(m1.get("mz_zfy"));
            String all_yzb = "0";
            boolean flag = true;
            for(Map<String, Object> m2 : zyYzb){
                String dept2 = String.valueOf(m2.get("ks_yzb"));
                String zy_ypf = String.valueOf(m2.get("zy_ypf"));
                String zy_zfy = String.valueOf(m2.get("zy_zfy"));
                String zy_yzb = String.valueOf(m2.get("zy_yzb"));
                if(dept2.equals(dept1)){
                    m1.put("zy_yzb", zy_yzb);
                    // 这里特指统计药品费的科室总费用
                    m1.put("yp_zfy", zy_zfy);
                    m1.put("zy_ypf", zy_ypf);
                    all_yzb = DecimalUtil.multiply(new BigDecimal(DecimalUtil.divide(DecimalUtil.add(mz_ypf, zy_ypf), DecimalUtil.add(mz_zfy, zy_zfy), 4)), new BigDecimal(100)) + "";
                    flag = false;
                    break;
                }
            }
            if(flag){
                String mz_yzb = String.valueOf(m1.get("mz_yzb"));
                m1.put("all_yzb", mz_yzb);
                m1.put("zy_yzb", 0);
            } else {
                m1.put("all_yzb", all_yzb);
            }
            yzbList.add(m1);
        }

        for(Map<String, Object> m1 : zyYzb){
            String dept1 = String.valueOf(m1.get("ks_yzb"));
            boolean flag = true;
            for(Map<String, Object> m2 : mzYzb){
                String dept2 = String.valueOf(m2.get("ks_yzb"));
                if(dept2.equals(dept1)){
                    flag = false;
                }
            }
            // 住院药占比有而门诊药占比没有的科室也要加上
            if(flag){
                String zy_yzb = String.valueOf(m1.get("zy_yzb"));
                String zy_zfy = String.valueOf(m1.get("zy_zfy"));
                m1.put("yp_zfy", zy_zfy);
                m1.put("all_yzb", zy_yzb);
                m1.put("mz_yzb", 0);
                yzbList.add(m1);
            }
        }

        // 整理耗占比数据: 各科室耗占比（分三种门诊+住院、门诊、住院）
        List<Map<String, Object>> hzbList = new ArrayList<>();
        for(Map<String, Object> m1 : mzHzb){
            String dept1 = String.valueOf(m1.get("ks_hzb"));
            String mz_hcf = String.valueOf(m1.get("mz_hcf"));
            String mz_zfy = String.valueOf(m1.get("mz_zfy"));
            String all_hzb = "0";
            boolean flag = true;
            for(Map<String, Object> m2 : zyHzb){
                String dept2 = String.valueOf(m2.get("ks_hzb"));
                String zy_hcf = String.valueOf(m2.get("zy_hcf"));
                String zy_zfy = String.valueOf(m2.get("zy_zfy"));
                String zy_hzb = String.valueOf(m2.get("zy_hzb"));
                if(dept2.equals(dept1)){
                    m1.put("zy_hzb", zy_hzb);
                    // 这里特指统计耗材费的科室总费用
                    m1.put("hc_zfy", zy_zfy);
                    m1.put("zy_hcf", zy_hcf);
                    all_hzb = DecimalUtil.multiply(new BigDecimal(DecimalUtil.divide(DecimalUtil.add(mz_hcf, zy_hcf), DecimalUtil.add(mz_zfy, zy_zfy), 4)), new BigDecimal(100)) + "";
                    flag = false;
                    break;
                }
            }
            if(flag){
                String mz_hzb = String.valueOf(m1.get("mz_hzb"));
                m1.put("all_hzb", mz_hzb);
                m1.put("zy_hzb", 0);
            } else {
                m1.put("all_hzb", all_hzb);
            }
            hzbList.add(m1);
        }

        for(Map<String, Object> m1 : zyHzb){
            String dept1 = String.valueOf(m1.get("ks_hzb"));
            boolean flag = true;
            for(Map<String, Object> m2 : mzHzb){
                String dept2 = String.valueOf(m2.get("ks_hzb"));
                if(dept2.equals(dept1)){
                    flag = false;
                }
            }
            // 住院药占比有而门诊药占比没有的科室也要加上
            if(flag){
                String zy_hzb = String.valueOf(m1.get("zy_hzb"));
                String zy_zfy = String.valueOf(m1.get("zy_zfy"));
                m1.put("hc_zfy", zy_zfy);
                m1.put("all_hzb", zy_hzb);
                m1.put("mz_hzb", 0);
                hzbList.add(m1);
            }
        }

        List<Map<String, Object>> list = new ArrayList<>();
        int count = Math.max(ksSrList.size(), yzbList.size());

        if(count < hzbList.size()){
            count = hzbList.size();
        }

        for(int i = 0; i < count; i++){
            Map<String, Object> m = new HashMap<>();
            if(ksSrList.size() > i){
                m.putAll(ksSrList.get(i));
            }
            if(yzbList.size() > i){
                m.putAll(yzbList.get(i));
            }
            if(hzbList.size() > i){
                m.putAll(hzbList.get(i));
            }
            list.add(m);
        }

        results.put("resultData", list);

        return ResultVoUtil.success(results);
    }

    /**
     * @Description 住院（申请/执行）科室核算收入报表
     * @Author hsh
     * @param dto 查询条件
     * @return map
     * @Date 2024/6/11 16:01
     */
    public ResultVo<Map<String, Object>> selectInpatientDeptAccountingReport(HighReportDto dto){
        Map<String, Object> results = new HashMap<>();
        List<Map<String, Object>> list;
        /*
         * 老系统查询方式（时间条件口径）：
         * 住院
         * 1.是否勾选按录入日期：勾选取zy_detail_charge表charge_date值（收费时间）查询；未勾选取zy_detail_charge表gen_time值（系统时间？）查询
         * 2.结账和应收二选一：选结账，上述时间查询取zy_ledger_file表cash_date值；选应收，按1的方式选择
         * 3.结账和应收二选一：zy_detail_charge表charge_status值选结账取3（结算），选应收取2（上账）
         * 门诊
         * 4.收费基准时间选择mz_receipt_serial表的charge_date字段值；结账基准时间选择mz_receipt_serial表的dcount_date字段值
         * 5.结算基准要求mz_receipt_serial的 isnull(dcount_no, 0) = 1 条件成立，收费基准不做要求
         */
        if("1".equals(dto.getType())){
            list = dao.selectInpatientDeptAccountingReportZyExecDept(dto.getStartTime(), dto.getEndTime());
        } else if("2".equals(dto.getType())){
            list = dao.selectInpatientDeptAccountingReportZyWardCode(dto.getStartTime(), dto.getEndTime());
        } else if("3".equals(dto.getType())){
            list = dao.selectInpatientDeptAccountingReportMzExecDept(dto.getStartTime(), dto.getEndTime());
        } else {
            list = dao.selectInpatientDeptAccountingReportMzWardDept(dto.getStartTime(), dto.getEndTime());
        }
        List<Map<String, Object>> dataList = new ArrayList<>();
        List<HeadInfo> headList = new ArrayList<>();
        Map<String, Map<String, List<Map<String, Object>>>> map =
                list.stream().collect(Collectors.groupingBy(m -> (String) m.get("flm"), Collectors.groupingBy(m -> (String) m.get("hsm"))));
        // 拼接列表表头
        HeadInfo info = new HeadInfo();
        info.setName("flm");
        info.setDisplay("父类码");
        info.setSort(1);
        headList.add(info);
        info = new HeadInfo();
        info.setName("hsm");
        info.setDisplay("核算码");
        info.setSort(2);
        headList.add(info);
        List<Map<String, Object>> listHead = list.stream().sorted(Comparator.comparing(e -> String.valueOf(e.get("ksid")))).collect(Collectors.toList());
        Map<String, List<Map<String, Object>>> mapHead = listHead.stream().collect(Collectors.groupingBy(m -> (String) m.get("ksid")));
        int index = 3;
        for (Map.Entry<String, List<Map<String, Object>>> entryHead : mapHead.entrySet()) {
            HeadInfo info1 = new HeadInfo();
            String o = entryHead.getKey();
            List<Map<String, Object>> l = entryHead.getValue();
            info1.setName(o);
            info1.setDisplay((String) l.get(0).get("ksmc"));
            info1.setSort(index);
            headList.add(info1);
            index++;
        }
        // 拼接列表数据（还要计算小计！！！）
        for (Map.Entry<String, Map<String, List<Map<String, Object>>>> entry1 : map.entrySet()) {
            String key1 = entry1.getKey();
            Map<String, List<Map<String, Object>>> map1 = entry1.getValue();
            Map<String, Object> mapHj = new HashMap<>();
            mapHj.put("flm", "小计：");
            mapHj.put("hsm", "");
            for (Map.Entry<String, List<Map<String, Object>>> entry2 : map1.entrySet()) {
                Map<String, Object> m = new HashMap<>();
                String key2 = entry2.getKey();
                List<Map<String, Object>> l = entry2.getValue();
                if(!l.isEmpty()){
                    m.put("flm", l.get(0).get("flmc"));
                    m.put("hsm", l.get(0).get("hsmc"));
                    for(Map<String, Object> map2 : l){
                        String ksId = (String) map2.get("ksid");
                        m.put(ksId, map2.get("totalCharge"));
                        Object k = mapHj.get(ksId);
                        if(null == k){
                            mapHj.put(ksId, DecimalUtil.add(BigDecimal.ZERO, (BigDecimal) map2.get("totalCharge")));
                        } else {
                            mapHj.put(ksId, DecimalUtil.add((BigDecimal) mapHj.get(ksId), (BigDecimal) map2.get("totalCharge")));
                        }
                    }
                    dataList.add(m);
                }
            }
            dataList.add(mapHj);
        }
        results.put("headList", headList);
        results.put("dataList", dataList);
        return ResultVoUtil.success(results);
    }

    /**
     * @Description 住院（申请/执行）科室核算收入报表导出
     * @Author hsh
     * @param dto 条件
     * @Date 2024/6/14 13:51
     */
    public void exportInpatientDeptAccountingReport(HttpServletResponse response, HighReportDto dto){
        Map<String, Object> map = new HashMap<>();
        ResultVo<Map<String, Object>> resultVo = selectInpatientDeptAccountingReport(dto);
        Map<String, Object> report = resultVo.getData();
        if(null == report){
            return;
        }

        // 数据
        List<Map<String, Object>> list = (List<Map<String, Object>>) report.get("dataList");
        // 导出标题
        String exportName = dto.getExportName();
        // 组装表头
        List<HeadInfo> headInfoList = (List<HeadInfo>) report.get("headList");
        List<HeadInfo> sortHeadInfo = headInfoList.stream().sorted(Comparator.comparing(HeadInfo::getSort)).collect(Collectors.toList());

        // 导出
        ExcelUtil.exportExcelReport(response, list, sortHeadInfo, exportName);
    }

    /**
     * @Description 查询住院工作量统计
     * @Author hsh
     * @param dto 查询条件
     * @return map 住院工作量统计
     * @Date 2024/8/20 11:26
     */
    public ResultVo<Map<String, Object>> selectWorkFeeStatistics(HighReportDto dto) {
        Map<String, Object> results = new HashMap<>();
        if(StringUtil.isBlank(dto.getReportId())){
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "没有配置报表id，请检查！");
        }
        // 查询费用相关信息
        ReportBaseInfo report = highReportDao.selectReportPortalMenu(dto.getReportId(), null, null);
        String sql = ReportUtil.sqlFormat(dto, report.getBaseSql());
        List<Map<String, Object>> list = dao.executeSqlByZb(sql);
        if(list.isEmpty()){
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "查询不到相应的报表数据，请检查！");
        }
        List<Map<String, Object>> zyInDaysList = dao.selectZyInDays(dto.getStartTime(), dto.getEndTime(), dto.getDept());
        Map<String, List<Map<String, Object>>> doctorNameMap = list.stream().collect(Collectors.groupingBy(f->String.valueOf(f.get("doctorName"))));
        Map<String, List<Map<String, Object>>> inDaysMap = zyInDaysList.stream().collect(Collectors.groupingBy(f->String.valueOf(f.get("doctorName"))));
        // 拼接数据展示内容
        List<HeadInfo> headList = new ArrayList<>();
        List<Map<String, Object>> resultList = new ArrayList<>();

        List<Map<String, Object>> listHead = list.stream().sorted(Comparator.comparing(e -> String.valueOf(e.get("code")))).collect(Collectors.toList());
        Map<String, List<Map<String, Object>>> mapHead = listHead.stream().collect(Collectors.groupingBy(m -> (String) m.get("code")));
        // 拼接列表表头
        HeadInfo info = new HeadInfo();
        info.setName("doctorName");
        info.setDisplay("医生姓名");
        info.setSort(1);
        headList.add(info);
        int index = 2;
        for (Map.Entry<String, List<Map<String, Object>>> entryHead : mapHead.entrySet()) {
            HeadInfo info1 = new HeadInfo();
            String o = entryHead.getKey();
            List<Map<String, Object>> l = entryHead.getValue();
            info1.setName(o);
            info1.setDisplay((String) l.get(0).get("name"));
            info1.setSort(index);
            headList.add(info1);
            index++;
        }
        info = new HeadInfo();
        info.setName("inDays");
        info.setDisplay("管床天数");
        info.setSort(index + 1);
        headList.add(info);
        // 拼接列表数据
        for(Map.Entry<String, List<Map<String, Object>>> entry : doctorNameMap.entrySet()){
            String key = entry.getKey();
            List<Map<String, Object>> dataList = entry.getValue();
            Map<String, Object> m1 = new HashMap<>();
            if(StringUtil.notBlank(key) && !"null".equals(key)){
                m1.put("doctorName", key);
            } else {
                m1.put("doctorName", "其他");
            }
            for(Map<String, Object> m : dataList){
                m1.put(String.valueOf(m.get("code")), m.get("fee"));
            }
            //拼接医生的管床天数
            if(!inDaysMap.isEmpty()){
                if(StringUtil.isBlank(key) || "null".equals(key)){
                    if(null != inDaysMap.get(key)){
                        List<Map<String, Object>> inDays = inDaysMap.get(key);
                        int day = 0;
                        for (Map<String, Object> m2 : inDays) {
                            String d = String.valueOf(m2.get("day"));
                            day = day + Integer.parseInt(d);
                        }
                        m1.put("inDays", day);
                    }
                } else if(null != inDaysMap.get(key)){
                    List<Map<String, Object>> inDays = inDaysMap.get(key);
                    m1.put("inDays", inDays.get(0).get("day"));
                }
            }
            resultList.add(m1);
        }

        results.put("headList", headList);
        results.put("resultList", resultList);
        return ResultVoUtil.success(results);
    }

    /**
     * @Description 住院工作量统计导出
     * @Author hsh
     * @param dto 导出条件
     * @return map
     * @Date 2024/8/20 11:27
     */
    public ResultVo<Map<String, Object>> exportWorkFeeStatisticsInfo(HttpServletResponse response, HighReportDto dto) {
        Map<String, Object> map = new HashMap<>();
        ResultVo<Map<String, Object>> resultVo = selectWorkFeeStatistics(dto);
        Map<String, Object> data = resultVo.getData();
        // 数据
        List<Map<String, Object>> list = (List<Map<String, Object>>) data.get("resultList");
        list.add(dto.getTotal());

        // 导出标题
        String exportName = dto.getExportName();

        // 组装表头
        List<HeadInfo> headInfoList = (List<HeadInfo>) data.get("headList");
        List<HeadInfo> sortHeadInfo = headInfoList.stream().sorted(Comparator.comparing(HeadInfo::getSort)).collect(Collectors.toList());

        // 导出
        ExcelUtil.exportExcelReport(response, list, sortHeadInfo, exportName);

        map.put("code", 0);
        map.put("massage", "导出成功！");
        return ResultVoUtil.success(map);
    }
}
