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.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

@Component("flow_status")
public class FlowStatusChart implements IChart {

    @Override
    public String getQuerySql(String flowType, String dimension, String ids, String orgIds, String startTime, String endTime, String orgType, String dbType) {
        String orgWhereId = "2".equals(orgType)?"a.create_by_":"a.create_org_id_";
        String defWhereId = "1".equals(flowType)?"a.proc_def_key_":"a.type_id_";
        StringBuilder sql = new StringBuilder();
        sql.append("select ");
        sql.append("sum(CASE a.STATUS_ WHEN 'running' THEN 1 ELSE 0 END) \"running\",");
        sql.append("sum(CASE a.STATUS_ WHEN 'draft' THEN 1 ELSE 0 END) \"draft\",");
        sql.append("sum(CASE a.STATUS_ WHEN 'end' THEN 1 ELSE 0 END) \"end\",");
        sql.append("sum(CASE a.STATUS_ WHEN 'backToStart' THEN 1 ELSE 0 END)+sum(CASE a.STATUS_ WHEN 'back' THEN 1 ELSE 0 END) \"back\",");
        sql.append("sum(CASE a.STATUS_ WHEN 'revoke' THEN 1 ELSE 0 END)+sum(CASE a.STATUS_ WHEN 'revokeToStart' THEN 1 ELSE 0 END) \"revokes\" ");
        sql.append("from bpm_pro_inst a ");
        sql.append("where a.IS_DELE_ = 0 ");
        if(SQLConst.DB_ORACLE.equals(dbType)){
            sql.append(" AND a.CREATE_TIME_ between to_date('"+startTime+"','YYYY-MM-DD HH24:MI:SS') and to_date('"+endTime+"','YYYY-MM-DD HH24:MI:SS')");
        }else{
            sql.append(" AND a.CREATE_TIME_>='"+startTime+"' AND a.CREATE_TIME_<='"+endTime+"' ");
        }
        if(StringUtil.isNotEmpty(ids)){
            String[] idArray = ids.split(",");
            String idsSql = StringUtil.convertListToSingleQuotesString(new HashSet<String>(Arrays.asList(idArray)));
            sql.append(" AND "+defWhereId+" IN ("+idsSql+")");
        }
        if (StringUtil.isNotEmpty(orgIds)){
            String[] orgIdArray = orgIds.split(",");
            String orgIdsSql = StringUtil.convertListToSingleQuotesString(new HashSet<String>(Arrays.asList(orgIdArray)));
            sql.append(" AND "+orgWhereId+" IN ("+ orgIdsSql+")");
        }
        return sql.toString();
    }

    @Override
    public String getDesc() {
        return "流程状态";
    }

    @Override
    public List<String> getLegend() {
        return Arrays.asList("草稿","运行中","完结","已退回","失效");
    }

    @Override
    public ArrayNode getSeries(List<String> legends, List<Map<String, Object>> selectList, Map<String, String> map) throws Exception {
        ArrayNode allSeries = JsonUtil.getMapper().createArrayNode();
        ObjectNode aSeries = JsonUtil.getMapper().createObjectNode();
        aSeries.put("type","pie");
        aSeries.put("name","流程状态");
        aSeries.put("radius","55%");
        aSeries.put("selectedMode","single");
        ArrayNode data = JsonUtil.getMapper().createArrayNode();
        for (String legend:legends){
            String status = getLegendCode(legend);
            ObjectNode node = JsonUtil.getMapper().createObjectNode();
            node.put("name",legend);
            node.put("value",Integer.valueOf(selectList.get(0).get(status).toString()));
            data.add(node);
        }
        aSeries.set("data",data);
        allSeries.add(aSeries);
        return allSeries;
    }

    private String getLegendCode(String desc){
        String status = "";
        switch (desc){
            case "草稿":
                status="draft";
                break;
            case "运行中":
                status = "running";
                break;
            case "已退回":
                status = "back";
                break;
            case "失效":
                status = "revokes";
                break;
            case "完结":
                status = "end";
                break;
        }
        return status;
    }
}
