package fr.insa.clavardator.client.ui.users;

import com.jfoenix.controls.JFXButton;
import fr.insa.clavardator.client.ui.ButtonPressEvent;
import fr.insa.clavardator.client.users.PeerUser;
import fr.insa.clavardator.lib.users.UserState;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;

import java.beans.PropertyChangeEvent;
import java.net.URL;
import java.util.ResourceBundle;

public class UserListItemController implements Initializable {

	@FXML
	private JFXButton button;
	@FXML
	private UserActiveIndicatorController indicatorController;

	private ButtonPressEvent listener;
	private PeerUser user;
	private boolean selected;

	public void setOnPressListener(ButtonPressEvent listener) {
		this.listener = listener;
	}

	public void onPress() {
		if (listener != null) {
			listener.onPress();
		}
	}

	/**
	 * Sets the current item selection state
	 *
	 * @param selected True to select the item, false otherwise
	 */
	public void setSelected(boolean selected) {
		this.selected = selected;
		if (selected)
			setBackgroundSelected();
		else
			resetBackground(this.user.isActive());
	}

	/**
	 * Updates shown username and item color when user changes
	 *
	 * @param propertyChangeEvent The change event
	 */
	private void onUsernameChange(PropertyChangeEvent propertyChangeEvent) {
		final String propName = propertyChangeEvent.getPropertyName();
		if (propName.equals("username")) {
			final String newUsername = (String) propertyChangeEvent.getNewValue();
			Platform.runLater(() -> button.setText(newUsername));
		} else if (propName.equals("state") && !selected) {
			final UserState newState = (UserState) propertyChangeEvent.getNewValue();
			Platform.runLater(() -> resetBackground(newState == UserState.CONNECTED));
		}
	}

	/**
	 * Sets the user to subscribe to for this item.
	 *
	 * @param user The user to subscribe to
	 */
	public void setUser(PeerUser user) {
		if (this.user == null || !this.user.equals(user)) {
			if (this.user != null) {
				// remove old observer before setting new user
				this.user.removeObserver(this::onUsernameChange);
			}
			this.user = user;
			user.addObserver(this::onUsernameChange);
			indicatorController.setUser(user);
			button.setText(user.getUsername());
			setSelected(false);
		}
	}

	/**
	 * Sets the background color to active or inactive
	 */
	private void resetBackground(boolean isActive) {
		clearBackground();
		if (isActive) {
			button.getStyleClass().add("active-user-item");
		} else {
			button.getStyleClass().add("inactive-user-item");
		}
	}

	/**
	 * Sets the background color in selected mode
	 */
	private void setBackgroundSelected() {
		clearBackground();
		button.getStyleClass().add("selected-user-item");
	}

	/**
	 * Clears the background of any color class
	 */
	private void clearBackground() {
		button.getStyleClass().remove("inactive-user-item");
		button.getStyleClass().remove("active-user-item");
		button.getStyleClass().remove("selected-user-item");
	}

	@Override
	public void initialize(URL location, ResourceBundle resources) {
	}
}
