/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.ht.ui.energy.sum;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javafx.beans.property.SimpleStringProperty;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ht.data.TagInfoManager;
import com.ht.tags.model.index.IndexTreeNode;
import com.ht.ui.MainApplication;
import com.ht.ui.chart.CustomBarChart;
import com.ht.ui.chart.CustomLineChart;
import com.ht.ui.chart.CustomPieChart;
import com.ht.ui.chart.DataDisplayType;
import com.ht.ui.controls.calendar.FXCalendar;
import com.ht.ui.energy.EnergyManageView;
import com.ht.ui.energy.ReportViewer;
import com.ht.ui.energy.sum.TopPanel.AreaType;
import com.ht.ui.energy.sum.TopPanel.CmpType;
import com.ht.ui.energy.sum.TopPanel.IAreaTypeChangeListener;
import com.ht.ui.energy.sum.TopPanel.ICmpTypeChangeListener;
import com.ht.ui.energy.util.EnergyConverterUtil;
import com.ht.ui.util.HessianResponseTask;
import com.ht.ui.util.MessageConstants;
import com.ht.ui.util.UserSecurityUtil;
import com.ht.util.DateType;
import com.ht.util.UserSession;
import com.ht.web.hessian.HessianFactoryManger;
import com.ht.web.mongo.domain.EnergyStatisticData;
import com.ht.web.mongo.domain.EnergyStatisticDataID;
import com.ht.web.mongo.domain.User;
import com.ht.web.remoting.HessianResponse;

/**
 * 统计汇总视图
 * 
 * @author Administrator
 */
public class EnergySumView extends HBox {

	private static final Logger log = LoggerFactory
			.getLogger(EnergySumView.class);

	// private TagIndexViewer tagIndexViewer;
	// private HBox hbox;
	private MainChartViewer mainChartViewer;

	private CustomBarChart barChart;
	private CustomLineChart areaChart;
	private CustomPieChart pieChart;
	private ReportViewer reportViewer;

	private Date date = new Date();
	private DateType dateType = DateType.DAILY;
	private DataDisplayType displayType = DataDisplayType.NORMAL;

//	private IndexTreeNode energyIndexNode;
//	private Map<String, IndexTreeNode> normalIndexMap = new HashMap<String, IndexTreeNode>();
//	private LinkedList<IndexTreeNode> cmpCategoryNode = new LinkedList<IndexTreeNode>();

	private SimpleDateFormat dailyDateFormat = new SimpleDateFormat(
			"yyyy年MM月dd日");
	private SimpleDateFormat monthlyDateFormat = new SimpleDateFormat(
			"yyyy年MM月");
	private SimpleDateFormat yearlyDateFormat = new SimpleDateFormat("yyyy年");

	private DecimalFormat timeDF = new DecimalFormat("00");

	private final SimpleDateFormat chartDailyDateFormat = new SimpleDateFormat(
			"HH:00");
	private final SimpleDateFormat chartMonthlyDateFormat = new SimpleDateFormat(
			"dd日");
	private final SimpleDateFormat chartYearlyDateFormat = new SimpleDateFormat(
			"MM月");

	private EnergySumTable table;

	private YMHistoryDataViewer ymHistoryViewer;;
	private EnergyManageView parentView;

	public EnergySumView(EnergyManageView parent) {
		super(20);

		setId("EnergySumView");
		setAlignment(Pos.TOP_LEFT);

		this.parentView = parent;
		// setStyle("-fx-padding: 15px;");
		timeDF.setPositiveSuffix(":00");

		createMiddle();
		createRight();

	}

	public EnergyManageView getParentView() {
		return parentView;
	}

	/**
	 * 生成默认图表，默认为一级用电分项多建筑对比
	 */
	public void generateDefaultChart() {
		if (TagInfoManager.INSTANCE.getBuildingIndexNode() == null
				|| TagInfoManager.INSTANCE.getBuildingIndexNode().getChildren().isEmpty()) {
			log.warn("建筑列表为空");
			return;
		}
		if (TagInfoManager.INSTANCE.getPowerIndexNode() == null
				|| TagInfoManager.INSTANCE.getPowerIndexNode().getChildren().isEmpty()) {
			log.warn("用电分项列表为空");
			return;
		}

		IndexTreeNode build = TagInfoManager.INSTANCE.getBuildingIndexNode().getChildren()
				.get(0);
		addIndexPath(build);
		// normalIndexMap.put(build.getName(), build);

		for (IndexTreeNode node : TagInfoManager.INSTANCE.getPowerIndexNode().getChildren()) {
			addIndexPath(node);
		}

	}
	private IndexNodeManager indexNodeManage = new IndexNodeManager() {
		
		@Override
		void updateTableHeaderTitle() {
			String prefix = "";
			switch (dateType) {
			case DAILY:
				prefix = "当天";
				break;
			case MONTHLY:
				prefix = "当月";
				break;
			case YEARLY:
				prefix = "年度";
				break;
			default:
				break;
			}

			if (!indexNodeManage.isEnergyIndexEmpty()) {
				StringBuilder sb = new StringBuilder(prefix).append("总能耗(");
				sb.append(
						EnergyConverterUtil.getEnergyUnit(indexNodeManage.getEnergyIndexNode().getPath()))
						.append(")");
				table.setSumColText(sb.toString());
				// sumCol.setText(sb.toString());
			} else {
				table.setSumColText(prefix + "总能耗");
				// sumCol.setText(prefix + "总能耗");
			}
		}
		
		@Override
		void updateChart() {
			log.debug("计算统计数据");

			final List<String> normalIndexList = indexNodeManage.getNormalPathList();

			final List<IndexTreeNode> normalIndexNodeList = new ArrayList<IndexTreeNode>(
					indexNodeManage.getNormalIndexMap().values());
			final IndexTreeNode energyNode = indexNodeManage.getEnergyIndexNode();
			final IndexTreeNode cmpNode = indexNodeManage.cmpCategoryNode.getLast();

			UserSecurityUtil.verifyUserAuthority(new Runnable() {

				@Override
				public void run() {
					User user = UserSession.INSTANCE.getUser();
					if (!user.getGroup().getEnergyStatistic()) {
						parentView.showMessage("您没有权限执行该操作, 请重新登录.");
						return;
					}

					if (energyNode == null) {
						parentView.showMessage("请选择一项能耗分项");
						return;
					} else if (indexNodeManage.isNormalIndexEmpty()) {
						parentView.showMessage("请选择一项常规分类");
						return;
					}

					updateChartTitle(cmpNode, energyNode, normalIndexNodeList);

					new HessianResponseTask() {

						@Override
						protected HessianResponse call() throws Exception {
							try {
								HessianResponse resp = HessianFactoryManger.INSTANCE
										.getTagVarService().getYMStatisticData(
												dateType, energyNode.getPath(),
												normalIndexList, date);
								return resp;
							} catch (Exception e) {
								e.printStackTrace();
							}
							return null;
						}

						@Override
						public void successResponse(HessianResponse resp) {
							@SuppressWarnings("unchecked")
							List<EnergyStatisticData> data = (List<EnergyStatisticData>) resp
									.getData();
							parseResponse(data, energyNode, cmpNode,
									normalIndexNodeList);
						}

						@Override
						public void nullResponse() {
							parentView.showMessage("应用程序错误");
						}

						@Override
						public void failureResponse(HessianResponse resp) {
							parentView.showMessage(resp.getMsg());
						}

					}.start();
				}
			});
		}
		
		@Override
		void setCmpType(CmpType type) {
			topBar.setCmpType(type);
		}
		
		@Override
		boolean isEnergyCmp() {
			return topBar.getCmpType().equals(CmpType.ENERGY);
		}
		
		@Override
		void clearChartAndTableData() {
			EnergySumView.this.clearChartAndTableData();
		}
		
		@Override
		void newNormalIndexNodeAdded(IndexTreeNode indexNode) {
			EnergySumView.this.addNewNormalIndexNode(indexNode);
		}
	};

	public void showHistoryViewer() {
		log.debug("计算统计数据");
		UserSecurityUtil.verifyUserAuthority(new Runnable() {
			public void run() {

				User user = UserSession.INSTANCE.getUser();
				if (!user.getGroup().getEnergyStatistic()) {
					parentView.showMessage("您所在的用户组没有权限执行该操作.");
				} else {

					if (indexNodeManage.isEnergyIndexEmpty()) {
						parentView.showMessage("请选择一项能耗分项");
						return;
					} else if (indexNodeManage.isNormalIndexEmpty()) {
						parentView.showMessage("请选择一项常规分类");
						return;
						// } else {

					}

					if (ymHistoryViewer == null) {
						ymHistoryViewer = new YMHistoryDataViewer();
					}
					ymHistoryViewer.init(dateType, indexNodeManage.getEnergyIndexNode(), indexNodeManage.getNormalIndexMap());
					MainApplication.getMainApp().showModalMessage(ymHistoryViewer);
				}
			}
		});
	}

	public synchronized void showReportViewer() {
		// StringBuilder sb = new StringBuilder("http://127.0.0.1/reports/aa");
		// if (cmpCategoryNode == null) {
		if (indexNodeManage.isCmpIndexEmpty()) {
			log.debug("未设置查询条件");
			return;
		}

		if (indexNodeManage.isEnergyIndexEmpty()) {

			log.debug("未选择能耗分项");
			return;
		}

		if (reportViewer == null) {
			reportViewer = new ReportViewer();
		}

		try {

			StringBuilder sb = new StringBuilder();

			HessianResponse resp = null;

//			if (cmpCategoryNode.getLast().getIndexName()
//					.equals(energyIndexNode.getIndexName())) {// 能耗分项对比
			
			if (indexNodeManage.isEnergyCmp()) {// 能耗分项对比

				sb.append("energy");

				resp = HessianFactoryManger.INSTANCE.getReportService()
						.energyCmp(dateType, "", date, indexNodeManage.getNormalPathList(), indexNodeManage.getCmpPathList());
			} else {// 常规对比

				sb.append("normal");
				resp = HessianFactoryManger.INSTANCE.getReportService()
						.normalCmp(dateType, "", date, indexNodeManage.getCmpPathList(), indexNodeManage.getNormalPathList(),
								indexNodeManage.getEnergyIndexNode().getPath());

			}
			sb.append("_").append(dateType.toString().toLowerCase())
					.append(".rptdesign");

			if (resp != null) {

				if (resp.isSuccessful()) {

					MainApplication.getMainApp().showModalMessage(reportViewer);

					String reportFileName = sb.toString();
					
					StringBuilder sb2 = new StringBuilder();
					sb2.append("http://")
							.append(MainApplication.getMainApp().hostProperty().getValue())
							.append("/reports/show");
					sb2.append(";jsessionid=").append(
							MainApplication.getCookieManager().getCookieStore()
									.getCookies().get(0).getValue());
					sb2.append("?filename=").append(reportFileName);

					// System.out.println(sb2.toString());
					reportViewer.showHTML(sb2.toString(), reportFileName);
				} else {

					MainApplication.getMainApp()
							.showMessage(resp.getMsg());
				}
			} else {
				parentView.showMessage(MessageConstants.ERROR_APP_ERROR);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	private void createMiddle() {
		table = new EnergySumTable();
		table.setPrefHeight(300);

		VBox vb = new VBox();
		vb.getStyleClass().add("window");

		barChart = new CustomBarChart();
		pieChart = new CustomPieChart();
		areaChart = new CustomLineChart();
		mainChartViewer = new MainChartViewer(this, areaChart, pieChart,
				barChart);
		mainChartViewer.setDateTitle(dailyDateFormat.format(date));
		vb.getChildren().addAll(createTop(), mainChartViewer, table);

		getChildren().add(vb);
	}

	private HBox createTop() {

		EventHandler<ActionEvent> handler = new EventHandler<ActionEvent>() {

			@Override
			public void handle(ActionEvent event) {
				String text = ((Button) event.getTarget()).getText();
				if (text.equals("重置")) {
					resetAllData();
				} else if (text.equals("报表")) {
					showReportViewer();
				} else if (text.equals("历史数据")) {
					showHistoryViewer();
				}

			}
		};
		topBar = new TopPanel(handler);
		// HBox hbox = new HBox(5);
		topBar.setPadding(new Insets(0, 20, 0, 20));

		topBar.onCmpTypeChanged(new ICmpTypeChangeListener() {

			@Override
			public boolean changed(CmpType cmpType) {
				if (indexNodeManage.isEnergyIndexEmpty()) {
					parentView.showMessage("请选择一项能耗分项");
					return false;
				} else if (indexNodeManage.isNormalIndexEmpty()) {
					parentView.showMessage("请选择一项常规分类");
					return false;
				}

				if (cmpType.equals(CmpType.ENERGY)) {
					log.debug("能耗分项对比");
					IndexTreeNode indexRoot = TagInfoManager.INSTANCE.getEnergyIndexMap()
							.get(indexNodeManage.getEnergyIndexNode().getIndexName());
					if (!indexRoot.getChildren().isEmpty()) {// 带有能耗分项,
																// 进行能耗分项对比

						indexNodeManage.doEnergyCmp();

					} else {
						parentView.showMessage(indexNodeManage.getEnergyIndexNode().getName()
								+ "未设置能耗分项");
						return false;
					}

				} else {
					log.debug("多建筑对比");
						indexNodeManage.doNormalCmp();
				}
				return true;
			}
		});

		topBar.onAreaTypeChanged(new IAreaTypeChangeListener() {

			@Override
			public boolean changed(AreaType areaType) {
				if (areaType == null) {
					log.debug("显示总能耗数据");
					showNormal();
				} else if (areaType.equals(AreaType.AREA)) {// 单位建筑面积能耗
					log.debug("显示单位面积能耗数据");
					return showArea();
				} else if (areaType.equals(AreaType.AIR_AREA)) {// 单位空调面积能耗
					return showAirArea();
				} else if (areaType.equals(AreaType.HEATING_AREA)) {// 单位采暖面积能耗
					return showHeatingArea();
				}
				return true;
			}
		});

		return topBar;
	}

	public DateType getDateType() {
		return dateType;
	}

	private void createRight() {

		final FXCalendar fxCalendar = new FXCalendar();
		fxCalendar.setStyle("-fx-font-size:14px;");
		fxCalendar.setTranslateY(-50);
		fxCalendar.setOnDateSelected(new Runnable() {

			@Override
			public void run() {
				date = fxCalendar.getValue();
				dateType = fxCalendar.getDateTypeButton().getDateType();

				switch (dateType) {
				case DAILY:
					mainChartViewer.setDateTitle(dailyDateFormat.format(date));

					timeDF.setPositiveSuffix(":00");

					break;
				case MONTHLY:
					mainChartViewer.setDateTitle(monthlyDateFormat.format(date));

					timeDF.setPositiveSuffix("日");

					break;
				case YEARLY:
					mainChartViewer.setDateTitle(yearlyDateFormat.format(date));

					timeDF.setPositiveSuffix("月");

					break;
				default:
					break;
				}

				mainChartViewer.clearData();
				table.clearData();

//				updateTableHeaderTitle();
				mainChartViewer.showTitle();

				indexNodeManage.doCmpRefresh();// 刷新对比显示
			}
		});

		VBox vb = new VBox();
		Region spacer = new Region();
		VBox.setVgrow(spacer, Priority.ALWAYS);
		vb.getChildren().addAll(fxCalendar, spacer);
		fxCalendar.toFront();
		getChildren().add(vb);
	}

	/**
	 * 清除数据
	 */
	private void resetAllData() {
		indexNodeManage.clear();
		clearChartAndTableData();

		table.removeAllNormalCols();
	}

	private void clearChartAndTableData() {
		barChart.clearData();
		pieChart.clearData();
		areaChart.clearData();
		table.clearData();
	}

	private boolean showAirArea() {
		for (IndexTreeNode node : indexNodeManage.getCmpCategoryNode()) {
			if (node.getAirConditionArea() == null) {
				parentView.showMessage(node.getName() + "未设置空调面积");
				return false;
			}
		}

		displayType = DataDisplayType.AIR_AREA;
		barChart.showAsAirConditionAreaData();
		pieChart.showAsAirConditionAreaData();
		areaChart.showAsAirConditionAreaData();
		return true;
	}

	private boolean showHeatingArea() {
		for (IndexTreeNode node : indexNodeManage.getCmpCategoryNode()) {
			if (node.getHeatingArea() == null) {
				parentView.showMessage(node.getName() + "未设置采暖面积");
				return false;
			}
		}

		displayType = DataDisplayType.HEATING_AREA;
		barChart.showAsHeatingAreaData();
		pieChart.showAsHeatingAreaData();
		areaChart.showAsHeatingAreaData();
		return true;
	}

	private boolean showArea() {
		for (IndexTreeNode node : indexNodeManage.getCmpCategoryNode()) {
			if (node.getArea() == null) {
				parentView.showMessage(node.getName() + "未设置总建筑面积");
				return false;
			}
		}

		displayType = DataDisplayType.AREA;
		barChart.showAsAreaData();
		pieChart.showAsAreaData();
		areaChart.showAsAreaData();
		return true;
	}

	private void showNormal() {
		displayType = DataDisplayType.NORMAL;
		barChart.showAsNormalData();
		pieChart.showAsNormalData();
		areaChart.showAsNormalData();
	}

	public void addIndexPath(final IndexTreeNode indexNode) {
		log.debug("添加分项: {}, {}", indexNode.getIndexName(), indexNode.getPath());
		indexNodeManage.addIndexPath(indexNode);


	}

	/**
	 * 更新或增加了新的常规分类条件
	 * 
	 * @param normalNode
	 */
	private void addNewNormalIndexNode(final IndexTreeNode normalNode) {
		IndexTreeNode oldNode = indexNodeManage.normalIndexMap.put(
				normalNode.getIndexName(), normalNode);
		final String colText = normalNode.getIndexName();
		if (oldNode == null) {
			table.addNewNormalCol(colText);
		} else {
			table.updateNormalCol(colText);
		}
	}

	private void updateChartTitle(IndexTreeNode cmpIndexNode,
			IndexTreeNode energyIndexNode,
			Collection<IndexTreeNode> normalIndexNodeList) {
		if (indexNodeManage.isCmpIndexEmpty()) {
			return;
		}

		if (cmpIndexNode.getIndexName().equals(energyIndexNode.getIndexName())) {// 能耗对比

			StringBuilder sb = new StringBuilder(" ");
			for (IndexTreeNode node : normalIndexNodeList) {
				sb.append(node.getName());
			}
			sb.append(" ");
			// 常规分类名称
			mainChartViewer.setPreTitle(sb.toString());

			sb = new StringBuilder(" ").append(EnergyConverterUtil
					.getEnergyTitle(energyIndexNode.getIndexName()));
			// 能耗分项名称
			if (energyIndexNode.getPath().contains("/")) {// 能耗分项对比
				sb.append("分项对比 ");
			} else {// 能耗分类对比
				sb.append("能耗对比 ");
			}
			mainChartViewer.setSufTitle(sb.toString());

		} else {// 建筑对比

			StringBuilder pre = new StringBuilder(" ");

			for (IndexTreeNode node : normalIndexNodeList) {
				if (!node.getIndexName().equals(cmpIndexNode.getIndexName())) {
					pre.append(node.getName());
				}
			}

			pre.append(" ");

			if (energyIndexNode.getPath().contains("/")) {// 能耗分项
				pre.append(energyIndexNode.getName());
			} else {
				pre.append(EnergyConverterUtil.getEnergyTitle(energyIndexNode
						.getIndexName()));// 能耗分类
			}

			pre.append(" ");

			// 能耗分项名称
			mainChartViewer.setPreTitle(pre.toString());

			// 常规分类名称
			mainChartViewer.setSufTitle(cmpIndexNode.getIndexName() + "对比 ");

		}

		mainChartViewer.showTitle();
	}


	private TopPanel topBar;

	private void parseResponse(List<EnergyStatisticData> data,
			IndexTreeNode energyNode, IndexTreeNode cmpNode,
			Collection<IndexTreeNode> normalIndexNodeList) {

		EnergyData energyData = table.getData(cmpNode);
		if (energyData == null) {
			energyData = new EnergyData();
			energyData.getEnergyCategory().setValue(energyNode.getName());
			for (IndexTreeNode node : normalIndexNodeList) {
				energyData.getNormalCategoryMap().put(node.getIndexName(),
						new SimpleStringProperty(node.getName()));
			}
			table.putData(cmpNode, energyData);
		}

		if (!data.isEmpty()) {
			Collections.sort(data, new Comparator<EnergyStatisticData>() {
				@Override
				public int compare(EnergyStatisticData o1,
						EnergyStatisticData o2) {
					return o1.getValue().getDatetime()
							.compareTo(o2.getValue().getDatetime());
				}
			});
		} else {
			parentView.showMessage("部分条目未查询到符合条件的数据!");
			return;
		}

		List<XYChart.Data<String, Number>> values = new ArrayList<XYChart.Data<String, Number>>();

		double sum = 0, avg = 0, max = 0, min = Double.NaN;

		for (EnergyStatisticData obj : data) {

			double value = obj.getValue().getValue().doubleValue();

			String label = "";
			switch (dateType) {
			case DAILY:
				label = chartDailyDateFormat.format(obj.getValue()
						.getDatetime());
				break;
			case MONTHLY:
				label = chartMonthlyDateFormat.format(obj.getValue()
						.getDatetime());
				break;
			case YEARLY:
				label = chartYearlyDateFormat.format(obj.getValue()
						.getDatetime());
				break;
			default:
				break;
			}
			XYChart.Data<String, Number> chartdata = new XYChart.Data<String, Number>(
					label, value, value);

			values.add(chartdata);
			sum += value;
			if (max < value) {
				max = value;
			}
			if (Double.isNaN(min) || min > value) {
				min = value;
			}
		}
		avg = sum / data.size();

		// 补偿确实的数据
		EnergyStatisticDataID id = data.get(0).getId();
		switch (dateType) {
		case DAILY:
			int start = id.getH();
			if (start > 0) {
				for (int i = 0; i < start; i++) {
					XYChart.Data<String, Number> chartdata = new XYChart.Data<String, Number>(
							i + ":00", 0, 0);

					values.add(i, chartdata);
				}
			}
			break;
		case MONTHLY:
			start = id.getD();
			if (start > 1) {
				for (int i = 1; i < start; i++) {
					XYChart.Data<String, Number> chartdata = new XYChart.Data<String, Number>(
							i + "日", 0, 0);

					values.add(i - 1, chartdata);
				}
			}
			break;
		case YEARLY:
			start = id.getM() + 1;
			if (start > 1) {
				for (int i = 1; i < start; i++) {
					XYChart.Data<String, Number> chartdata = new XYChart.Data<String, Number>(
							i + "月", 0, 0);

					values.add(i - 1, chartdata);
				}
			}
			break;
		default:
			break;
		}

		// 多建筑同分项对比图
		// barChartWrapper.addOrUpdateValue(cmpCategoryNode.getLast(), sum, max,
		// min, avg);
		barChart.addOrUpdateValue(cmpNode, sum);

		// 同建筑多分项对比图
		pieChart.addOrUpdateValue(cmpNode, sum);

		// 同建筑多分项对比图
		areaChart.addOrUpdateValue(cmpNode, values);

		energyData.getMax().set(max);
		energyData.getMin().set(min);
		energyData.getAvg().set(avg);
		energyData.getSum().set(sum);
		double convert = EnergyConverterUtil.convert(energyNode.getPath(), sum);
		if (convert >= 0) {
			energyData.getConvertSum().set(convert);
		}

	}

	public Map<String, IndexTreeNode> getNormalIndexMap() {
		return indexNodeManage.normalIndexMap;
	}

	public IndexTreeNode getEnergyIndexNode() {
		return indexNodeManage.energyIndexNode;
	}
}
