package be.kdg.labyrinth.JavaFX.view;

import be.kdg.labyrinth.JavaFX.model.GameModel;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.input.KeyCode;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Duration;

import javax.print.attribute.standard.Media;
import java.io.File;
import java.util.*;

public class GamePresenter {
    private GameModel model;
    private GameView view;
    private Timeline timer;
    private long startTime;
    private Stage stage;
    private List<Long> highscores;

    public GamePresenter(GameModel model, GameView view, Stage stage) {
        this.model = model;
        this.view = view;
        this.stage = stage;
        this.highscores = new ArrayList<>();

        startGameLoop();
        addEventHandlers();

        Platform.runLater(() -> {
            view.setFocusTraversable(true);
            view.requestFocus();
        });

        stage.getScene().setOnMouseClicked(event -> view.requestFocus());
    }

    private void startGameLoop() {
        startTime = System.currentTimeMillis();
        timer = new Timeline(new KeyFrame(Duration.seconds(0.1), e -> updateView()));
        timer.setCycleCount(Timeline.INDEFINITE);
        timer.play();
    }

    private void updateView() {
        char[][] labyrinth = model.getLabyrinth();
        int playerRow = model.getPlayerRow();
        int playerCol = model.getPlayerCol();

        for (int row = 0; row < labyrinth.length; row++) {
            for (int col = 0; col < labyrinth[row].length; col++) {
                Color color = getColorForTile(labyrinth[row][col]);
                view.drawTile(row, col, color);
            }
        }

        for (int[] pos : model.getTrail()) {
            if (labyrinth[pos[0]][pos[1]] != 'O') {
                view.drawTrail(pos[0], pos[1]);
            }
        }

        view.drawPlayer(playerRow, playerCol);
        view.updateTime(getElapsedTime());
        view.updatePlayerPosition(playerRow, playerCol);

        if (labyrinth[playerRow][playerCol] == 'E') {
            timer.stop(); // Stop de timer
            long elapsedTime = System.currentTimeMillis() - startTime;
            model.saveHighscore(elapsedTime);
            Platform.runLater(this::showEndGameAlert);
        }
    }

    private void addEventHandlers() {
        view.setOnKeyPressed(event -> {
            KeyCode keyCode = event.getCode();

            if (keyCode == KeyCode.Z || keyCode == KeyCode.UP) {
                model.movePlayer(-1, 0);
            } else if (keyCode == KeyCode.S || keyCode == KeyCode.DOWN) {
                model.movePlayer(1, 0);
            } else if (keyCode == KeyCode.Q || keyCode == KeyCode.LEFT) {
                model.movePlayer(0, -1);
            } else if (keyCode == KeyCode.D || keyCode == KeyCode.RIGHT) {
                model.movePlayer(0, 1);
            }

            view.requestFocus();
        });
    }

    private String getElapsedTime() {
        long elapsedTime = System.currentTimeMillis() - startTime;
        return formatTime(elapsedTime);
    }

    private String formatTime(long millis) {
        int seconds = (int) (millis / 1000) % 60;
        int minutes = (int) ((millis / (1000 * 60)) % 60);
        int hours = (int) ((millis / (1000 * 60 * 60)) % 24);
        return String.format("%02d:%02d:%02d", hours, minutes, seconds);
    }

    private Color getColorForTile(char tile) {
        switch (tile) {
            case '#': return GameView.WALL_COLOR;
            case '.': return GameView.PATH_COLOR;
            case 'S': return GameView.START_COLOR;
            case 'O': return GameView.SECRET_COLOR;
            case 'E': return GameView.EXIT_COLOR;
            default: return GameView.PATH_COLOR;
        }
    }

    private void showEndGameAlert() {
        Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
        alert.setTitle("Gewonnen!");
        alert.setHeaderText("Je hebt het einde bereikt!");
        alert.setContentText("Wil je opnieuw spelen?");

        ButtonType buttonTypeYes = new ButtonType("Ja");
        ButtonType buttonTypeNo = new ButtonType("Nee");

        alert.getButtonTypes().setAll(buttonTypeYes, buttonTypeNo);

        Optional<ButtonType> result = alert.showAndWait();
        if (result.isPresent() && result.get() == buttonTypeYes) {
            model.reset();
            startGameLoop();
        } else {
            StartView startView = new StartView();
            new StartPresenter(new GameModel("src/be/kdg/labyrinth/LabyrinthEasy.csv", "Easy"), startView, stage);
            Scene scene = new Scene(startView, 1000, 800);
            stage.setScene(scene);
            stage.setFullScreen(false);
            stage.setResizable(true);
        }
    }
}
