package com.artfess.bpm.chart.impl;

import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.artfess.base.constants.SQLConst;
import com.artfess.base.util.JsonUtil;
import com.artfess.base.util.StringUtil;
import com.artfess.bpm.chart.IChart;
import org.springframework.stereotype.Component;

import java.util.*;

@Component("task_num")
public class TaskNumChart implements IChart {
    @Override
    public String getQuerySql(String flowType, String dimension, String ids, String orgIds, String startTime, String endTime, String orgType, String dbType) {
        StringBuilder whereSql = new StringBuilder();
        String orgWhereId = "2".equals(orgType)?"task.OWNER_ID_":"inst.CREATE_ORG_ID_";
        String defWhereId = "1".equals(flowType)?"def.DEF_KEY_":"task.TYPE_ID_";
        String xPropId = "org".equals(dimension)?orgWhereId:defWhereId;
        whereSql.append(getBaseSql(xPropId));
        whereSql.append("where task.IS_DELE_ = 0 ");
        if(SQLConst.DB_ORACLE.equals(dbType)){
            whereSql.append(" AND task.CREATE_TIME_ between to_date('"+startTime+"','YYYY-MM-DD HH24:MI:SS') and to_date('"+endTime+"','YYYY-MM-DD HH24:MI:SS')");
        }else{
            whereSql.append(" AND task.CREATE_TIME_>='"+startTime+"' AND task.CREATE_TIME_<='"+endTime+"' ");
        }
        if(StringUtil.isNotEmpty(ids)){
            String[] idArray = ids.split(",");
            String idsSql = StringUtil.convertListToSingleQuotesString(new HashSet<String>(Arrays.asList(idArray)));
            whereSql.append(" AND "+defWhereId+" IN ("+idsSql+")");
        }
        if (StringUtil.isNotEmpty(orgIds)){
            String[] orgIdArray = orgIds.split(",");
            String orgIdsSql = StringUtil.convertListToSingleQuotesString(new HashSet<String>(Arrays.asList(orgIdArray)));
            whereSql.append(" AND "+orgWhereId+" IN ("+ orgIdsSql+")");
        }
        whereSql.append("group by " + xPropId);
        return whereSql.toString();
    }

    private String getBaseSql(String xPropId){
        StringBuilder sql = new StringBuilder("select ");
        sql.append(xPropId+" \"id\",");
        sql.append("COUNT(1) \"count\" ");
        sql.append("FROM bpm_task task ");
        sql.append("left join bpm_definition def on def.DEF_KEY_ = task.PROC_DEF_KEY_ ");
        sql.append("left join bpm_pro_inst inst on inst.ID_ = task.PROC_INST_ID_ ");
        return sql.toString();
    }

    @Override
    public String getDesc() {
        return "任务量";
    }

    @Override
    public List<String> getLegend() {
        return Arrays.asList("任务量");
    }

    @Override
    public ArrayNode getSeries(List<String> legend, List<Map<String, Object>> selectList, Map<String, String> map) throws Exception {
        ArrayNode array = JsonUtil.getMapper().createArrayNode();
        String defType = "bar";
        for (String le : legend) {
            ObjectNode node = JsonUtil.getMapper().createObjectNode();
            node.put("name",le);
            node.put("type",defType);
            List<Object> data;
            data = getSeriesData(selectList,map);
            node.set("data",JsonUtil.toJsonNode(data));
            array.add(node);
        }
        return array;
    }

    private List<Object> getSeriesData(List<Map<String, Object>> selectList, Map<String, String> map){
        String status = "count";
        List<Object> data = new ArrayList<>();
        for (String key : map.keySet()) {
            int length = data.size();
            for (Map<String,Object> select:selectList){
                if (key.equals(select.get("id").toString())){
                    data.add(Integer.valueOf(select.get(status).toString()));
                }
            }
            if (data.size()==length){
                data.add(0);
            }
        }
        return data;
    }
}
