package hsr.dsa.view.templates;

import java.io.IOException;
import java.security.InvalidKeyException;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;

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

import hsr.dsa.controller.ChatController;
import hsr.dsa.controller.ControllerManager;
import hsr.dsa.data.models.ChatMessage;
import hsr.dsa.data.models.Group;
import hsr.dsa.data.models.LocalUser;
import hsr.dsa.data.models.TextMessage;
import hsr.dsa.data.models.User;
import hsr.dsa.utils.Observable;
import hsr.dsa.utils.ObservableList;
import hsr.dsa.utils.Observer;
import hsr.dsa.view.FXController;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextArea;
import javafx.scene.layout.VBox;

@SuppressWarnings("restriction")
public class GroupChatPaneController implements FXTemplate<Group>, Observer {
	private static final Logger log = LoggerFactory.getLogger(GroupChatPaneController.class);
	private final ChatController chatController;

	private Group group;
	private ObservableList<ChatMessage> chatMessages;

	@FXML
	private VBox messages;
	@FXML
	private ScrollPane messagesScroll;
	@FXML
	private TextArea message;

	public GroupChatPaneController() throws IOException {
		this.chatController = ControllerManager.getChatController();
	}

	@FXML
	public void initialize() {
		this.messages.heightProperty().addListener(new ChangeListener<Number>() {
			@Override
			public void changed(ObservableValue<? extends Number> observable, Number oldvalue, Number newValue) {
				messagesScroll.setVvalue(1.0);
			}
		});
		if (group != null) {
			this.loadChatHistory();
		}
	}

	private void loadChatHistory() {
		this.messages.getChildren().clear();
		for (ChatMessage message : chatMessages) {
			if (message instanceof TextMessage) {
				TextMessage textMessage = (TextMessage) message;
				if (textMessage.getSender() instanceof LocalUser) {
					showMessage(textMessage, "/fxml/chatWindow/templates/userMessage.fxml");
				} else {
					showMessage(textMessage, "/fxml/chatWindow/templates/foreignMessage.fxml");
				}
			}
		}
	}

	@Override
	public void setControler(FXController controller) {
	}

	@Override
	public void setData(Group group) {
		this.group = group;
		this.chatMessages = this.group.getChatMessages();
		this.chatMessages.addObserver(this);
		if (this.messages != null) {
			this.loadChatHistory();
		}
	}

	public void send() throws IOException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
		String message = this.message.getText().trim();
		if (message.length() > 0) {
			this.message.setText("");
			User user = this.chatController.getProfile();
			this.chatController.getClient().writeGroupMessage(user, this.group, message);
		}
	}

	@SuppressWarnings("unchecked")
	private void showMessage(TextMessage message, String view) {
		try {
			this.message.setText("");
			FXMLLoader loader = new FXMLLoader();
			Parent messageView = (Parent) loader.load(getClass().getResourceAsStream(view));
			FXTemplate<TextMessage> templateControler = (FXTemplate<TextMessage>) loader.getController();
			templateControler.setData(message);
			this.messages.getChildren().add(messageView);
		} catch (IOException e) {
			log.error("unable to process message", e);
		}
	}

	@Override
	public void onChange(Observable observable) {
		Platform.runLater(() -> {
			this.loadChatHistory();
		});
	}
}
