package info.bukova.isspst.ui.reporting;

import info.bukova.isspst.Module;
import info.bukova.isspst.ModuleUtils;
import info.bukova.isspst.data.DataModel;
import info.bukova.isspst.reporting.Report;
import info.bukova.isspst.reporting.ReportDefinition;
import info.bukova.isspst.reporting.ReportType;
import info.bukova.isspst.services.Service;
import info.bukova.isspst.sort.ReflectionTools;
import info.bukova.isspst.ui.DocumentViewModel;
import org.zkoss.bind.annotation.BindingParam;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.ExecutionArgParam;
import org.zkoss.bind.annotation.Init;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.Sessions;
import org.zkoss.zk.ui.select.annotation.WireVariable;
import org.zkoss.zul.Window;

import javax.servlet.ServletContext;
import java.lang.reflect.InvocationTargetException;
import java.util.List;

public class ReportDialogVM extends DocumentViewModel
{
	
	private List<Report> reports;
	private Report selected;
	@WireVariable
	private ReportDefinition reportDefinition;
	private List<Object> dataList;
	private Object singleObject;
	private ServletContext ctx;
	
	@Init(superclass = true)
	public void init(@ExecutionArgParam("reports") List<Report> reports, 
			@ExecutionArgParam("data") List<Object> data,
			@ExecutionArgParam("singleObject") Object singleObject,
			@ExecutionArgParam("service") Service<Object> service) {
		this.reports = reports;
		
		if (data != null && data.size() > 0 && data.get(0).getClass() != reportDefinition.gatDataClass()) {
			reportDefinition.clear();
		}
		
		dataList = data;
		this.singleObject = singleObject;
		reportDefinition.setService(service);

		ctx = Sessions.getCurrent().getWebApp().getServletContext();
	}
	
	public List<Report> getReports() {
		return this.reports;
	}
	
	public ReportDefinition getReportDefinition() {
		return reportDefinition;
	}

	public Report getSelected() {
		return selected;
	}

	@NotifyChange({"optionsForm", "selected"})
	public void setSelected(Report selected) {
		this.selected = selected;
		reportDefinition.setReport(selected);
		if (selected.isSingleRecord()) {
			setObject(selected);
		} else {
			reportDefinition.setDataSet(dataList);
		}
	}

	private void setObject(Report report) {
		if (report.getProperty() == null) {
			reportDefinition.setSingleObject(singleObject);
		} else {
			try {
				Object o = ReflectionTools.getGetterMethod(singleObject, report.getProperty()).invoke(singleObject);
				reportDefinition.setSingleObject(o);

				if (!(o instanceof DataModel)) {
					return;
				}

				Module m = ModuleUtils.getModule((DataModel)o, ctx);

				if (m != null) {
					reportDefinition.setService((Service<Object>) ModuleUtils.getServiceInstance(m, ctx));
				}
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}
		}
	}
	
	@Command
	public void print(@BindingParam("window") Window window) {
		if (window != null) {
			window.detach();
		}
		
		Window reportWin = (Window) Executions.createComponents("/app/reporting/report.zul", null, null);
		reportWin.doModal();
	}
	
	public String getOptionsForm() {
		if (selected != null && selected.getType() == ReportType.DYNAMIC) {
			return "/app/reporting/colSelect.zul";
		} else if (selected != null && selected.isHasSettings()) {
			return "/app/reporting/" + selected.getJasperFile() + ".zul";
		} else {
			return "/app/reporting/noOptions.zul";
		}
	}

	public Object getSingleObject() {
		return singleObject;
	}

	public void setReportDefinition(ReportDefinition reportDefinition) {
		this.reportDefinition = reportDefinition;
	}

	public boolean isCanPrint() {
		if (singleObject != null) {
			return reportDefinition.getService().canPrintRecord(singleObject);
		}

		return true;
	}

}
