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.DeptBusinessDao;
import thyyxxk.webserver.dao.his.medicalinsurance.costcontrol.YbUtilDao;
import thyyxxk.webserver.entity.ResultVo;
import thyyxxk.webserver.entity.highreport.DeptReportResult;
import thyyxxk.webserver.entity.highreport.HighReportDto;
import thyyxxk.webserver.entity.highreport.ReportBaseInfo;
import thyyxxk.webserver.entity.login.UserInfo;
import thyyxxk.webserver.service.hutoolcache.UserCache;
import thyyxxk.webserver.utils.ReportUtil;
import thyyxxk.webserver.utils.ResultVoUtil;
import thyyxxk.webserver.utils.StringUtil;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName DeptBusinessService
 * @Author hsh
 * @Date 2025/4/2 15:41
 * @Version 1.0
 * @Description 科室经营报表
 **/
@Service
@Slf4j
public class DeptBusinessService {

    private final DeptBusinessDao dao;


    private final YbUtilDao ybDao;

    private final UserCache userCache;

    @Autowired
    public DeptBusinessService(DeptBusinessDao dao, YbUtilDao ybDao, UserCache userCache) {
        this.dao = dao;
        this.ybDao = ybDao;
        this.userCache = userCache;
    }

    /**
     * @Description 查询报表范围以及权限
     * @Author hsh
     * @param flag 报表类型分类（1: 科室经营分析月报表）
     * @return map
     * @Date 2025/4/16 0016 12:53
     */
    public ResultVo<Map<String, Object>> selectReportTypeList(String flag) {
        Map<String, Object> map = new HashMap<>();
        // 获取指标类型
        List<Map<String, Object>> reportTypeList = dao.selectReportTypeList(flag);
        UserInfo user = userCache.getUserInfoByToken();
        String s = ybDao.selectDeptYbbQxByRole("ybbQx");
        boolean index = true;
        if (null != s) {
            List<Integer> roles = user.getRoles();
            for (Integer role : roles) {
                String[] st = s.split(",");
                for (String qx : st) {
                    String bs = String.valueOf(role);
                    if (qx.equals(bs)) {
                        index = false;
                        break;
                    }
                }
                if (!index) {
                    break;
                }
            }
        }
        if (index) {
            // 有科室权限控制，只能查询一个科室的数据
            map.put("qx", 0);
        } else {
            // 不限制科室，可以查询全院数据
            map.put("qx", 1);
        }
        map.put("reportTypeList", reportTypeList);
        return ResultVoUtil.success(map);
    }

    /**
     * @param dto 查询条件
     * @return list 科室分析报表数据
     * @Description 根据科室分析报表类型查询报表数据
     * @Author hsh
     * @Date 2025/4/11 0011 16:00
     */
    private List<DeptReportResult> callReportResultData(Map<String, Object> m, HighReportDto dto, List<ReportBaseInfo> rl) {
        List<DeptReportResult> list = new ArrayList<>();
        String name = (String) m.get("reportLabel");
        String code = (String) m.get("reportCode");
        for (ReportBaseInfo report : rl) {
            String sql = ReportUtil.callSqlFormat(dto, report.getBaseSql(), report.getGatherSql(), null, null, null);
            List<DeptReportResult> dl = dao.selectDeptBusinessReportData(sql);
            if (null == dl || dl.isEmpty()) {
                continue;
            }
            boolean r_f = false;
            for (DeptReportResult result : dl) {
                if (null == result) {
                    continue;
                }
                if (!r_f) {
                    r_f = true;
                }
                result.setName(name);
                result.setCode(code);
                result.setReportId(report.getReportId());
                result.setReportName(report.getReportName());
                result.setReportType(report.getReportType());
            }
            if (r_f) {
                list.addAll(dl);
            }
        }
        return list;
    }

    /**
     * @Description 根据条件查询科室经营分析月报表数据
     * @Author hsh
     * @param dto 报表参数
     * @return map
     * @Date 2025/4/17 0017 16:55
     */
    public ResultVo<Map<String, Object>> selectDeptReportList(HighReportDto dto) {
        Map<String, Object> map = new HashMap<>();
        String flag = dto.getYbbFlag();
        List<String> codeList = dto.getReportTypeList();
        // 获取指标类型
        List<Map<String, Object>> reportTypeList;
        StringBuilder codes = new StringBuilder("'");
        if (null == codeList || codeList.isEmpty()) {
            reportTypeList = dao.selectReportTypeList(flag);
        } else {
            if (codeList.size() == 1) {
                codes.append(codeList.get(0)).append("'");
            } else {
                for (int i = 0; i < codeList.size(); i++) {
                    if (i == codeList.size() - 1) {
                        codes.append(codeList.get(i)).append("'");
                    } else {
                        codes.append(codeList.get(i)).append("','");
                    }
                }
            }
            // 获取指标类型
            reportTypeList = dao.selectReportTypeListByCodes(flag, codes.toString());
        }
        // 获取需要计算的指标
        List<ReportBaseInfo> reportList;
        if (null == codeList || codeList.isEmpty()) {
            // 科室的条件存在与否影响查询sql的取值
            if (StringUtil.isBlank(dto.getDept())) {
                // 当科室条件不存在的时候，查询全院数据需要查询指标id以 "_all" 结尾的指标
                reportList = dao.selectReportList(flag, "_all");
            } else {
                // 当科室条件不存在的时候，查询全院数据需要查询指标id以 "_dept" 结尾的指标
                reportList = dao.selectReportList(flag, "_dept");
            }
        } else {
            reportList = dao.selectReportListByCodes(flag, codes.toString());
        }
        if (null == reportList || reportList.isEmpty()) {
            return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "没有查询到科室经营分析月报表相关的指标。");
        }
        // 按照指标类型分组
        Map<String, List<ReportBaseInfo>> m1 = reportList.stream().collect(Collectors.groupingBy(ReportBaseInfo::getReportType));
        List<DeptReportResult> deptLeft = new ArrayList<>();
        List<DeptReportResult> deptRight = new ArrayList<>();
        for (Map<String, Object> m : reportTypeList) {
            String reportType = (String) m.get("reportType");
            String layoutFlag = (String) m.get("layoutFlag");
            List<ReportBaseInfo> rl = m1.get(reportType);
            if (null == rl || rl.isEmpty()) {
                continue;
            }
            m.put("reportCount", rl.size());
            m.put("layoutFlag", layoutFlag);
            List<DeptReportResult> s = callReportResultData(m, dto, rl);
            if (!s.isEmpty()) {
                if ("0".equals(layoutFlag)) {
                    deptLeft.addAll(s);
                } else {
                    deptRight.addAll(s);
                }
            }
        }
        map.put("reportTypeList", reportTypeList);
        map.put("reportList", reportList);
        map.put("deptLeft", deptLeft);
        map.put("deptRight", deptRight);
        return ResultVoUtil.success(map);
    }

}
