package com.cnd3b.common.data;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.cnd3b.utility.Math;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

public class Rows extends ArrayList<Row> {

    private static final long serialVersionUID = 1L;
    public int totalRows = 0;
    public int totalPage = 0;
    public String errmsg = "";

    public String getErrMsg() {
        return errmsg;
    }

    public int getTotalRows() {
        return totalRows;
    }

    public int getTotalPage() {
        return totalPage;
    }

    public Row getRow(int i) {
        if (i + 1 > this.size()) {
            return null;
        }
        return get(i);
    }

    public Row getLastRow() {
        return get(this.size() - 1);
    }

    /**
     * 获取字段合计值
     *
     * @param column
     * @return
     */
    public double sum(String column) {
        double value = 0d;
        for (Row row : this) {
            if (row.containsKey(column)) {
                value = Math.add(value, row.getDouble(column));
            }
        }
        return value;
    }

    private HashMap<String, Double> minValueMap = new HashMap<>();
    private HashMap<String, Double> maxValueMap = new HashMap<>();

    /**
     * 获取字段最小值
     *
     * @param column
     * @return
     */
    public double min(String column) {
        if (minValueMap.containsKey(column)) {
            return minValueMap.get(column);
        }
        caculate(column);
        return minValueMap.get(column);
    }

    /**
     * 获取字段最大值
     *
     * @param column
     * @return
     */
    public double max(String column) {
        if (maxValueMap.containsKey(column)) {
            return maxValueMap.get(column);
        }
        caculate(column);
        return maxValueMap.get(column);
    }

    private void caculate(String column) {
        double minvalue = 0d;
        double maxvalue = 0d;
        for (Row row : this) {
            if (row.containsKey(column)) {
                double value = row.getDouble(column);
                minvalue = java.lang.Math.min(minvalue, value);
                maxvalue = java.lang.Math.max(maxvalue, value);
            }
        }
        minValueMap.put(column, minvalue);
        maxValueMap.put(column, maxvalue);
    }

    public Rows removeColumn(String[] columns) {
        for (Row row : this) {
            for (String column : columns) {
                row.remove(column);
            }
        }
        return this;
    }

    public JSONArray toJsonArray() {
//        JSONArray array = new JSONArray();
//        for (Row row : this) {
//            JSONObject object = row.toJsonObject();
//            array.add(object);
//        }
//        return array;
        return (JSONArray) JSON.toJSON(this);
    }

    public JSONArray toJsonArray(String column) {
        JSONArray array = new JSONArray();
        for (Row row : this) {
            Object value = row.get(column);
            array.add(value);
        }
        return array;
    }

    public String[] toArray(String column) {
        return toArrayList(column).toArray(new String[0]);
    }

    public ArrayList<String> toArrayList(String column) {
        ArrayList<String> list = new ArrayList<>();
        for (Row row : this) {
            list.add(row.getString(column));
        }
        return list;
    }

    public RowsMap toRowsMap(String fieldname) {
        RowsMap map = new RowsMap();
        for (Row row : this) {
            String key = row.getString(fieldname);
            Rows subrows = null;
            if (map.containsKey(key)) {
                subrows = map.get(key);
            } else {
                subrows = new Rows();
            }
            subrows.add(row);
            map.put(key, subrows);
        }
        return map;
    }

    public RowsMap toRowsMap(String fieldnames[]) {
        RowsMap map = new RowsMap();
        for (Row row : this) {
            StringBuffer key = new StringBuffer();
            for (String fieldname : fieldnames) {
                key.append(row.getString(fieldname));
            }
            Rows subrows = null;
            if (map.containsKey(key.toString())) {
                subrows = map.get(key.toString());
            } else {
                subrows = new Rows();
            }
            subrows.add(row);
            map.put(key.toString(), subrows);
        }
        return map;
    }

    public String toXml() {
        Document document = DocumentHelper.createDocument();
        if (this.size() > 0) {
            Iterator<String> it = this.get(0).keySet().iterator();
            ArrayList<String> list = new ArrayList<>();
            while (it.hasNext()) {
                list.add(it.next());
            }
            Element root = document.addElement("rows");
            for (int i = 0; i < this.size(); i++) {
                Row row = getRow(i);
                Element element = root.addElement("row" + i);
                for (String key : list) {
                    Object value = row.get(key);
                    Element e = element.addElement(key);
                    if (value == null) {
                        e.addText("null");
                    } else {
                        e.addText(row.get(key).toString());
                    }
                }
            }
        }
        return document.asXML();
    }

}
