package com.alexanderlogistics;

import java.io.Serializable;
import java.util.logging.Logger;

import org.imixs.workflow.faces.data.WorkflowController;

import jakarta.enterprise.context.ConversationScoped;
import jakarta.enterprise.event.Event;
import jakarta.inject.Inject;
import jakarta.inject.Named;

/**
 * The AnalyticController is a conversationScoped controller that provides
 * values for the analytic-custom parts.
 * <p>
 * A custom implementation can react on AnalyticEvent to compute values and
 * datasets.
 * <p>
 * The controller implements a caching mechanism to avoid repeated calls for new
 * analytic values. If the analytic value is already stored in the current
 * workitem, no new value will be fired.
 * 
 * 
 * @author rsoika
 *
 */
@Named
@ConversationScoped
public class AnalyticController implements Serializable {

	private static final long serialVersionUID = 1L;
	private static Logger logger = Logger.getLogger(AnalyticController.class.getName());

	@Inject
	protected Event<AnalyticEvent> analyticEvents;

	@Inject
	protected WorkflowController workflowController;

	/**
	 * Returns a analytic value as a String for a given key.
	 * 
	 * @param key
	 * @return
	 */
	public String getAsString(String key) {
		computeValue(key);
		return workflowController.getWorkitem().getItemValueString("analytic." + key);
	}

	/**
	 * Returns a analytic value as a Double for a given key.
	 * 
	 * @param key
	 * @return
	 */
	public double getAsDouble(String key) {
		computeValue(key);
		return workflowController.getWorkitem().getItemValueDouble("analytic." + key);
	}

	/**
	 * Returns the analytic label for a given key
	 * 
	 * @param key
	 * @return
	 */
	public String getLabel(String key) {
		computeValue(key);
		return workflowController.getWorkitem().getItemValueString("analytic." + key + ".label");
	}

	/**
	 * Returns the analytic description for a given key
	 * 
	 * @param key
	 * @return
	 */
	public String getDescription(String key) {
		computeValue(key);
		return workflowController.getWorkitem().getItemValueString("analytic." + key + ".description");
	}

	/**
	 * Computes am analytic value. The method cache the value in the item
	 * 'analytic.KEY' to avoid feierring repeated AnalyticEvents.
	 * 
	 * @param key
	 * @return
	 */
	protected void computeValue(String key) {
		if (workflowController.getWorkitem() != null) {
			// try to fetch value from cache
			if (!workflowController.getWorkitem().hasItem("analytic." + key)) {
				logger.info("fire analytic event for key '" + key + "'");
				// Fire the Analytics Event for this key
				AnalyticEvent event = new AnalyticEvent(key, workflowController.getWorkitem());
				if (analyticEvents != null) {

					analyticEvents.fire(event);
					workflowController.getWorkitem().setItemValue("analytic." + key, event.getValue());
					workflowController.getWorkitem().setItemValue("analytic." + key + ".label", event.getLabel());
					workflowController.getWorkitem().setItemValue("analytic." + key + ".description",
							event.getDescription());
				}

				if (event.getValue() == null) {
					// set dummy value
					workflowController.getWorkitem().setItemValue("analytic." + key, "");
					workflowController.getWorkitem().setItemValue("analytic." + key + ".label", "- undefined -");
					workflowController.getWorkitem().setItemValue("analytic." + key + ".description",
							"No data available");
				}
			}
		} else {
			// analytic value is already cached!
		}
	}

}
