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("work_status")
public class WorkStatusChart 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)?"a.create_by_":"a.create_org_id_";
        String defWhereId = "1".equals(flowType)?"a.proc_def_key_":"a.type_id_";
        String xPropId = "org".equals(dimension)?orgWhereId:defWhereId;
        whereSql.append(getBaseSql(xPropId));
        whereSql.append("where a.IS_DELE_ = 0 ");
        if(SQLConst.DB_ORACLE.equals(dbType)){
            whereSql.append(" AND a.STATUS_ IS NOT NULL 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{
            whereSql.append(" AND a.STATUS_ IS NOT NULL 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)));
            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("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("left join bpm_definition def on def.def_key_ = a.proc_def_key_ ");
        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,le,map);
            node.set("data",JsonUtil.toJsonNode(data));
            array.add(node);
        }
        return array;
    }

    private List<Object> getSeriesData(List<Map<String,Object>> selectList,String legend,Map<String,String> map){
        String status = getLegendCode(legend);
        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;
    }

    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;
    }

}
