package info.bukova.isspst.ui.tripbill;

import info.bukova.isspst.StringUtils;
import info.bukova.isspst.data.RequirementState;
import info.bukova.isspst.data.TripBill;
import info.bukova.isspst.data.TripBillApproval;
import info.bukova.isspst.services.requirement.TripRequirementService;
import info.bukova.isspst.services.tripbill.TripBillApprovalService;
import info.bukova.isspst.services.tripbill.TripBillService;
import info.bukova.isspst.services.users.UserService;
import info.bukova.isspst.ui.requirement.RequirementSubpage;
import org.zkoss.bind.BindUtils;
import org.zkoss.bind.annotation.BindingParam;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.ExecutionArgParam;
import org.zkoss.bind.annotation.GlobalCommand;
import org.zkoss.bind.annotation.Init;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.select.annotation.WireVariable;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.Window;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Pepa Rokos
 */
public class TripBillSummaryVM extends RequirementSubpage<TripBillApproval> {

	@WireVariable
	private TripBillApprovalService tripBillApprovalService;
	@WireVariable
	private TripBillService tripBillService;
	@WireVariable
	private TripRequirementService tripRequirementService;
	@WireVariable
	private UserService userService;
	private TripBill bill;
	private Map<Integer, Boolean> selTab;

	@Init(superclass = true)
	public void initBillSummary(@ExecutionArgParam("bill") TripBill bill) {
		service = tripBillApprovalService;
		selTab = new HashMap<Integer, Boolean>();

		if (bill.getApproval() != null) {
			setDataBean(bill.getApproval());
		}

		this.bill = bill;
	}

	public TripBill getBill() {
		return bill;
	}

	@Command
	@NotifyChange({"bill", "dataBean", "canApprove"})
	public void setBill(@BindingParam("bill") TripBill bill) {
		this.bill = bill;
		setDataBean(bill.getApproval());

		for (Integer i : selTab.keySet()) {
			selTab.put(i, false);
		}

		selTab.put(bill.getId(), true);
	}

	public List<TripBill> getBills() {
		List<TripBill> bills = new ArrayList<TripBill>();
		boolean isSelectedTad = false;

		bills.add(this.bill);

		if (selectTab(bill)) {
			isSelectedTad = true;
		}

		for (TripBill b : tripRequirementService.getBills(bill.getRequirement())) {
			if (b.getId() != bill.getId()) {
				tripBillService.loadLazyData(b);
				bills.add(b);

				if (!isSelectedTad && selectTab(b)) {
					isSelectedTad = true;
				}
			}
		}

		if (!isSelectedTad) {
			selTab.put(bill.getId(), true);
		}

		return bills;
	}

	private boolean selectTab(TripBill bill) {
		if (bill.getApproval() != null
				&& bill.getApproval().getState() != RequirementState.APPROVED
				&& tripBillApprovalService.getNextApprover(bill.getApproval()).contains(userService.getCurrent())) {
			setBill(bill);
			return true;
		} else {
			selTab.put(bill.getId(), false);
		}

		return false;
	}

	@Command
	public void showBill(@BindingParam("bill") TripBill bill) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("selected", bill);
		Window win = (Window) Executions.createComponents("tripBill.zul", null, params);
		win.doModal();
	}

	@Override
	@GlobalCommand
	@NotifyChange("dataBean")
	public void reload() {
		if (bill.getApproval() != null) {
			setDataBean(tripBillApprovalService.getById(bill.getApproval().getId()));
		}
	}

	public Map<Integer, Boolean> getSelTab() {
		return selTab;
	}

	@Command
	public void cancelApproval() {
		Messagebox.show(StringUtils.localize("TripBillCancelApprovalQuestion"), StringUtils.localize("TripBillCancelApprovalTitle"), Messagebox.YES
				| Messagebox.NO, Messagebox.QUESTION, new EventListener<Event>() {
			@Override
			public void onEvent(Event event) throws Exception {
				if (((Integer) event.getData()).intValue() == Messagebox.YES) {
					tripBillApprovalService.cancelApproval(bill);
					setDataBean(null);
					BindUtils.postNotifyChange(null, null, TripBillSummaryVM.this, "bill");
					BindUtils.postNotifyChange(null, null, TripBillSummaryVM.this, "dataBean");
					BindUtils.postNotifyChange(null, null, TripBillSummaryVM.this, "canApprove");
				}
			}
		});
	}
}
