import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;

/**
 * Contiene la vista y funcionalidad de la lista de tareas pendientes del usuario
 */
public class ToDoList extends Widget {

    /**
     * Constructor de ToDoList
     * @param icono Ubicación de la imagen que actúa como ícono para abrir y cerrar el ToDoList
     */
    public ToDoList(String icono){
        super(icono);
        view = new VBox();
        super.createAnimation(view);
        taskCount = 0;
        view.getStyleClass().add("todo");
        newTask = new TextField();
        newTask.setPromptText("Ej: Estudiar para ELO329");
        Button btnNewTask = new Button("Agregar tarea");
        btnNewTask.setOnAction(e-> {
            addTask();
        });
        view.getChildren().addAll(newTask, btnNewTask);
        loadPrevTasks();
    }

    /**
     * Event Listener para agregar una tarea con la tecla Enter del teclado
     * @param e Evento KeyEvent.KEY_PRESSED
     */
    public void addTaskEnter(KeyEvent e){
        if(e.getCode().equals(KeyCode.ENTER)){
            addTask();
        }
    }

    /**
     * Agrega una nueva tarea pendiente a partir del TextField.
     * Emite una alerta si se agregan más de 10 tareas.
     */
    private void addTask(){
        if(taskCount >= 10){
            Alert alert = new Alert(Alert.AlertType.WARNING);
            alert.setTitle("No te sobreexijas");
            alert.setContentText(String.format("Parece que tienes muchas cosas por hacer, te recomendamos que termines algunas para a\u00f1adir m\u00e1s tareas. No te sobreexijas, cu\u00eddate."));
            alert.showAndWait();
            return;
        }
        if(newTask.getLength() > 0){
            view.getChildren().add(new Task(newTask.getText(), this, false));
            taskCount++;
            newTask.setText("");
            newTask.requestFocus();
            return;
        }
    }

    /**
     * Agrega una tarea a partir de sus parámetros de entrada.
     * Útil para regenerar la lista de tareas de una sesión anterior (todo.txt).
     * @param state Estado (pendiente/realizado) con el que se crea la tera.
     * @param task Texto que describe la tarea
     */
    private void addTask(Boolean state, String task){
        view.getChildren().add(new Task(task,this, state));
        taskCount++;
    }

    /**
     * Elimina una tarea de la lista
     * @param task Tarea a eliminar
     */
    public void removeTask(Task task){
        view.getChildren().remove(task);
        taskCount--;
    }

    /**
     * Lee el archivo todo.txt para regenerar la lista de tareas de la
     * sesión anterior
     */
    private void loadPrevTasks(){
        try {
            Scanner prev = new Scanner(new File("todo.txt"));
            prev.useDelimiter(";");
            while (prev.hasNextBoolean()){
                Boolean b = prev.nextBoolean();
                String s = prev.nextLine();
                addTask(b, s.substring(1));
            }
        } catch (FileNotFoundException e) {
            System.out.println("No existe el archivo todo");
            return;
        }
    }

    /**
     * Guarda la lista de tareas en el archivo todo.txt
     * @param save true para guardar la lista, false para guardar el archivo vacío
     */
    public void saveTasksToFile(Boolean save){
        try {
            FileWriter file = new FileWriter("todo.txt");
            if(!save){
                file.close();
                return;
            }
            ObservableList<Node> list = view.getChildren();
            for(int i=0; i<list.size(); i++){
                if (list.get(i) instanceof Task){
                    Boolean state = ((CheckBox) ((Task) list.get(i)).getChildren().get(0)).isSelected();
                    String task = ((Text) ((Task) list.get(i)).getChildren().get(1)).getText();
                    file.write(state + ";" + task + "\n");
                }
            }
            file.close();
        } catch (IOException e) {
            System.out.println("Ocurrió un error al intentar guardar las tareas pendientes.");
        }
    }
    private TextField newTask;
    private short taskCount;
    private VBox view;
}
