package com.kingdee.eas.custom.projectbonus.web.handler;

import com.kingdee.bos.BOSException;
import com.kingdee.bos.Context;
import com.kingdee.bos.metadata.entity.EntityViewInfo;
import com.kingdee.bos.metadata.entity.FilterInfo;
import com.kingdee.eas.util.app.DbUtil;
import com.kingdee.jdbc.rowset.IRowSet;
import com.kingdee.shr.base.syssetting.context.SHRContext;
import com.kingdee.shr.base.syssetting.exception.SHRWebException;
import com.kingdee.shr.base.syssetting.exception.ShrWebBizException;
import com.kingdee.shr.base.syssetting.json.GridDataEntity;
import com.kingdee.shr.base.syssetting.web.dynamic.util.ExportHelper;
import com.kingdee.shr.base.syssetting.web.handler.ListHandler;
import com.kingdee.util.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.ui.ModelMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.*;

/**
 * @Description 分配人员明细报表Handler
 * @Date 2024/5/21 18:51
 * @Created by Heyuan
 */
public class DetailListHandler extends ListHandler {
    private static Logger logger = Logger.getLogger(DetailListHandler.class);
    //上下文
    private Context ctx = SHRContext.getInstance().getContext();

    /**
     * 设置金额字段精度
     *
     * @param request
     * @param helper
     * @return
     * @throws SHRWebException
     */
    @Override
    protected Map<String, Object> initExportExcelConfig(HttpServletRequest request, ExportHelper helper) throws SHRWebException {
        Map<String, Object> excelConfig = super.initExportExcelConfig(request, helper);
        List<Map<String, Object>> columnModels = (List) excelConfig.get("columnModel");
        for (int i = 0; i < columnModels.size(); i++) {
            Map<String, Object> columnModel = columnModels.get(i);
            String name = (String) columnModel.get("name");
            if (name.contains("total")) {
                Map<String,Object> attributes = new HashMap<>();
                attributes.putAll((Map<? extends String, ?>) columnModel.get("attributes"));
                attributes.put("decimalPrecision", 6);
                columnModel.put("attributes",attributes);
            }
        }
        return excelConfig;
    }

    @Override
    protected GridDataEntity getGridRequestData(HttpServletRequest request,
                                                HttpServletResponse response,
                                                ModelMap modelMap) throws SHRWebException {
        StringBuilder filterSql = new StringBuilder();
        EntityViewInfo dataGridEntityView = (EntityViewInfo) modelMap.get("DataGridEntityView");
        FilterInfo filterInfo = dataGridEntityView.getFilter();
        String filter = filterInfo.toString();
        if (StringUtils.isEmpty(filter)) {
            filterSql.append(" bonusCycle.fid in ('')");
        } else {
            filter = filter.replace("parent.parent", "bonusCycle.fid").replace("person.id", "bDPAPD.CFPERSONID");
            filterSql.append(filter);
            String filterItems = request.getParameter("filterItems");//搜索条件
            if (!StringUtils.isEmpty(filterItems)) {
                String replace = filterItems.replace("person.name", "person.fname_l2").replace("person.number", "person.fnumber");
                filterSql.append(" and ").append(replace);
            }
        }
        try {
            Boolean isAll = (Boolean) request.getAttribute("isAll");
            if (isAll == null) {
                isAll = Boolean.valueOf(request.getParameter("isAll"));
            }
            if (isAll) {
                return exportAllToExcel(request, filterSql.toString());
            } else {
                return getGridRequestDataForPage(request, filterSql.toString());
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new ShrWebBizException(e.getMessage());
        }
    }

    /**
     * 查询汇总数据
     *
     * @return
     * @throws BOSException
     * @throws SQLException
     */
    private List<Map<String, Object>> queryData(HttpServletRequest request, String filterSql)
            throws BOSException, SQLException {
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        StringBuilder querySql = new StringBuilder();
        querySql.append("SELECT").append("\n")
                .append("    person.fname_l2 personName,").append("\n")
                .append("    person.fnumber personNumber,").append("\n")
                .append("    busDep.fname_l2 busDepName,").append("\n")
                .append("    project.fname_l2 projectName,").append("\n")
                .append("    amountData.total").append("\n")
                .append("FROM").append("\n")
                .append("    (").append("\n")
                .append("        SELECT").append("\n")
                .append("            bDPAPD.CFPERSONID,").append("\n")
                .append("            bDP.CFBusDepID,").append("\n")
                .append("            bDP.CFProjectID,").append("\n")
                .append("            sum(bDPAPD.CFApprovalAmount) as total").append("\n")
                .append("        FROM").append("\n")
                .append("            CT_PB_BonusCycle bonusCycle").append("\n")
                .append("            inner JOIN CT_PB_BonusCycleBusDepProject bDP ON bDP.FPARENTID = bonusCycle.FID").append("\n")
                .append("            inner JOIN CT_PB_BonusCAPD bDPAPD ON bDPAPD.FPARENTID = bDP.FID").append("\n")
                .append("            inner JOIN t_bd_person person ON bDPAPD.cfpersonId = person.FID").append("\n")
                .append("        WHERE").append("\n")
                .append(filterSql).append("\n")
                .append("            and bDP.cfstate = 5").append("\n")
                .append("        group by").append("\n")
                .append("            bDPAPD.CFPERSONID,").append("\n")
                .append("            bDP.CFProjectID,").append("\n")
                .append("            bDP.CFBusDepID").append("\n")
                .append("    ) amountData").append("\n")
                .append("    inner JOIN t_org_admin busDep ON busDep.fid = amountData.CFBusDepID").append("\n")
                .append("    LEFT JOIN t_org_admin project ON project.fid = amountData.CFProjectID").append("\n")
                .append("    inner JOIN T_BD_PERSON person ON amountData.CFPERSONID = person.FID").append("\n");
        querySql.append(" order by person.fnumber").append("\n");
        logger.info("querySql: " + querySql);
        IRowSet iRowSet = DbUtil.executeQuery(ctx, querySql.toString());
        Map<String, Map<String, Object>> data = new HashMap<String, Map<String, Object>>();
        Map<String, String> personData = new HashMap<String, String>();
        while (iRowSet.next()) {
            String personName = iRowSet.getString("personName");
            String personNumber = iRowSet.getString("personNumber");
            String busDepName = iRowSet.getString("busDepName");
            String projectName = iRowSet.getString("projectName");
            BigDecimal total = iRowSet.getBigDecimal("total");
            total = total == null ? BigDecimal.ZERO : total.setScale(6);
            Map<String, Object> map = null;
            if (data.containsKey(personNumber)) {
                map = data.get(personNumber);
            } else {
                map = new HashMap<String, Object>();
                data.put(personNumber, map);
                personData.put(personNumber, personName);
            }
            if (!StringUtils.isEmpty(projectName)) {
                map.put(projectName, total);
            } else {
                map.put(busDepName, total);
            }
        }
        for (String personNumber : data.keySet()) {
            Map<String, Object> map = data.get(personNumber);
            Map<String, Object> rowMap = new HashMap<>();
            rowMap.put("personNumber", personNumber);
            rowMap.put("personName", personData.get(personNumber));
            int count = 1;
            for (String field : map.keySet()) {
                BigDecimal total = (BigDecimal) map.get(field);
                String projectFiledName = "project" + count;
                String totalFiledName = "total" + count++;
                rowMap.put(projectFiledName, field);
                rowMap.put(totalFiledName, total);
            }
            list.add(rowMap);
        }
        return list;
    }

    /**
     * 页面查询
     *
     * @param request
     * @return
     * @throws SHRWebException
     * @throws SQLException
     * @throws BOSException
     */
    protected GridDataEntity getGridRequestDataForPage(HttpServletRequest request, String filterSql)
            throws SQLException, BOSException {
        Integer totalCount = getCount(ctx, request, filterSql);//汇总数据条数
        //行数
        int rows = Integer.parseInt(request.getParameter("rows"));
        //页数
        int page = Integer.parseInt(request.getParameter("page"));
        List dataList = queryData(request, filterSql);
        GridDataEntity gridDataEntity = new GridDataEntity();
        if (totalCount % rows == 0) {
            gridDataEntity.setTotal(totalCount / rows);//总页数
        } else {
            gridDataEntity.setTotal(totalCount / rows + 1);
        }
        gridDataEntity.setRows(dataList);
        gridDataEntity.setRecords(totalCount);
        gridDataEntity.setPage(page);
        return gridDataEntity;
    }

    /**
     * 导出查询
     *
     * @param request
     * @return
     * @throws SHRWebException
     * @throws SQLException
     * @throws BOSException
     */
    protected GridDataEntity exportAllToExcel(HttpServletRequest request, String filterSql)
            throws ShrWebBizException, SQLException, BOSException {
        Integer totalCount = getCount(ctx, request, filterSql);//汇总数据条数
        if (totalCount > 1000000L) {
            throw new ShrWebBizException("数据超过100万行，无法导出！");
        }
        List dataList = queryData(request, filterSql);
        GridDataEntity gridDataEntity = new GridDataEntity();
        gridDataEntity.setTotal(1);//总页数
        gridDataEntity.setRows(dataList);
        gridDataEntity.setRecords(totalCount);
        gridDataEntity.setPage(1);
        gridDataEntity.setUserdata(new HashMap<String, Object>());
        return gridDataEntity;
    }

    /**
     * 查询汇总条数
     *
     * @param ctx
     * @param request
     * @return
     * @throws BOSException
     * @throws SQLException
     */
    protected Integer getCount(Context ctx,
                               HttpServletRequest request, String filterSql) throws BOSException, SQLException {
        int count = 0;
        StringBuilder querySql = new StringBuilder();
        querySql.append("SELECT").append("\n")
                .append("    count(1) count").append("\n")
                .append("FROM").append("\n")
                .append("    (").append("\n")
                .append("        SELECT").append("\n")
                .append("            bDPAPD.CFPERSONID").append("\n")
                .append("        FROM").append("\n")
                .append("            CT_PB_BonusCycle bonusCycle").append("\n")
                .append("            inner JOIN CT_PB_BonusCycleBusDepProject bDP ON bDP.FPARENTID = bonusCycle.FID").append("\n")
                .append("            inner JOIN CT_PB_BonusCAPD bDPAPD ON bDPAPD.FPARENTID = bDP.FID").append("\n")
                .append("            inner JOIN t_bd_person person ON bDPAPD.cfpersonId = person.FID").append("\n")
                .append("        WHERE").append("\n")
                .append(filterSql).append("\n")
                .append("            and bDP.cfstate = 5").append("\n")
                .append("        group by").append("\n")
                .append("            bDPAPD.CFPERSONID").append("\n")
                .append("    ) amountData").append("\n");
        IRowSet iRowSet = DbUtil.executeQuery(ctx, querySql.toString());
        logger.info("querySql: " + querySql);
        while (iRowSet.next()) {
            count = iRowSet.getInt("count");
        }
        return count;
    }
}
