package View;

import Model.*;
import javafx.beans.property.ListProperty;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleListProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.event.EventType;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.util.converter.NumberStringConverter;
import java.io.IOException;

public class TreeViewController extends FXMLWindow{
    @FXML
    private TreeView<Sensor> tree;
    @FXML
    private TextField name;
    @FXML
    private Text id;
    @FXML
    private TextField temperature;
    @FXML
    private VBox vBox;
    private Button textView;
    private Button imageView;
    private TableView<Sensor> tableView;
    private Button changeToCpu;
    private Button changeToRandom;
    private ObservableList<Sensor> sensorsList;

    public TreeViewController(ObservableList<Sensor> sensorsList, String url, String title) throws IOException, IOException {
        super(url, title);
        this.sensorsList = sensorsList;
        changeToCpu = new Button("Change to CPU");
        changeToRandom = new Button("Change to Random");
        textView = new Button("See In Text View");
        imageView = new Button("See In Image View");

        TreeItem<Sensor> root = new TreeItem<>();
        tree.setRoot(root);
        tree.setShowRoot(false);
        tree.setCellFactory(capteurTreeView -> new TreeCell<>(){
            @Override
            protected void updateItem(Sensor item, boolean empty) {
                super.updateItem(item, empty);
                if (!empty) {
                    textProperty().bind(item.nameProperty());
                } else {
                    textProperty().unbind();
                    setText("");
                }
            }
        });
        for (Sensor s : sensorsList) {
            root.getChildren().add(s.accept(new TreeViewV()));
        }

        tableView = new TableView<>();
        TableColumn<Sensor, String> nameCol = new TableColumn<>("Nom");
        TableColumn<Sensor, Float> tempCol = new TableColumn<>("Température");
        nameCol.setCellValueFactory(new PropertyValueFactory<>("nom"));
        tempCol.setCellValueFactory(new PropertyValueFactory<>("temperature"));

        tableView.getColumns().addAll(nameCol, tempCol);

    }


    public void initialize() {

        tree.getSelectionModel().selectedItemProperty().addListener((observableValue, old, newV) -> {
            if (old != null) {
                name.textProperty().unbindBidirectional(old.getValue().nameProperty());
                id.textProperty().unbindBidirectional(old.getValue().idProperty());
                temperature.textProperty().unbindBidirectional(old.getValue().temperatureProperty());

                textView.setOnAction(null);
                imageView.setOnAction(null);
                vBox.getChildren().removeAll(textView, imageView);

                if (old.getValue() instanceof VirtualSensor) {
                    tableView.getItems().removeAll(((VirtualSensor) old.getValue()).getSensors().values());
                    vBox.getChildren().remove(tableView);
                } else {
                    changeToCpu.setOnAction(null);
                    changeToRandom.setOnAction(null);
                    vBox.getChildren().removeAll(changeToCpu, changeToRandom);
                }

            }
            if (newV != null) {
                name.textProperty().bindBidirectional(newV.getValue().nameProperty());
                id.textProperty().bindBidirectional(newV.getValue().idProperty());
                temperature.textProperty().bindBidirectional(newV.getValue().temperatureProperty(), new NumberStringConverter());

                EventHandler<ActionEvent> eventTextView = e -> {
                    try {
                        new TextSensorController(newV.getValue(), "/fxml/Capteur.fxml", "TextView");
                    } catch (IOException ex) {
                        throw new RuntimeException(ex);
                    }
                };

                EventHandler<ActionEvent> eventImageView = e -> {
                    try {
                        new TextSensorController(newV.getValue(), "/fxml/ImageCapteur.fxml", "TextView");
                    } catch (IOException ex) {
                        throw new RuntimeException(ex);
                    }
                };

                textView.setOnAction(eventTextView);
                imageView.setOnAction(eventImageView);

                vBox.getChildren().addAll(textView, imageView);



                if (newV.getValue() instanceof VirtualSensor) {
                    tableView.getItems().addAll(((VirtualSensor) newV.getValue()).getSensors().values());
                    vBox.getChildren().add(tableView);
                } else {
                    EventHandler<ActionEvent> eventCpu = e -> {
                        ((SimpleSensor) newV.getValue()).setStrategy(new CpuGenerator());
                    };
                    EventHandler<ActionEvent> eventRandom = e -> {
                        ((SimpleSensor) newV.getValue()).setStrategy(new RandomGenerator());
                    };
                    changeToCpu.setOnAction(eventCpu);
                    changeToRandom.setOnAction(eventRandom);
                    vBox.getChildren().addAll(changeToCpu, changeToRandom);
                }
            }
        });
    }

}
