package eu.oschl.gui;

import eu.oschl.schmorn.Setup;
import eu.oschl.textadventure.Game;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.Event;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javafx.scene.text.Font;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

import java.io.IOException;
import java.io.InputStream;
import java.util.Objects;
import java.util.Optional;

/**
 * Main session class for managing the game state and launching the GUI.
 *
 * @author Ondřej Schlaichert
 */
public class Session extends Application {
    private static Game game;
    private static ActionProcessor actionProcessor;

    public static Game getGame() {
        return game;
    }

    public static ActionProcessor getActionProcessor() {
        return actionProcessor;
    }

    public static void launchGui(String[] args)
    {
        createNewGame();

        Session.actionProcessor = ActionProcessor.create(game);

        Application.launch(Session.class, args);
    }

    private static void createNewGame() {
        Session.game = Setup.createGame();

        if (Session.actionProcessor != null) {
            Session.actionProcessor.changeGame(Session.game);
        } else {
            Session.actionProcessor = ActionProcessor.create(Session.game);
        }

        Session.actionProcessor.sendEvent();
    }

    @Override
    public void start(Stage stage) throws IOException {
        FXMLLoader fxmlLoader = new FXMLLoader(Session.class.getResource("game.fxml"));
        Scene scene = new Scene(fxmlLoader.load(), 1280, 720);

        try (InputStream fontStream = Session.class.getResourceAsStream("fonts/Iosevka-Slab-01.ttf")) {
            Font.loadFont(fontStream, 10);
        } catch (IOException _) {
        }

        var cssPath = Objects.requireNonNull(Session.class.getResource("css/style.css")).toExternalForm();
        scene.getStylesheets().add(cssPath);

        stage.setTitle("Schmorn");
        stage.setScene(scene);

        stage.setOnCloseRequest(event -> handleCloseRequest(stage, event));

        KeyCombination restartKeyCombination = new KeyCodeCombination(KeyCode.R, KeyCombination.CONTROL_DOWN);
        scene.getAccelerators().put(restartKeyCombination, () -> handleRestartRequest(stage));

        KeyCombination helpKeyCombination = new KeyCodeCombination(KeyCode.F1);
        scene.getAccelerators().put(helpKeyCombination, this::handleHelpRequest);

        stage.show();
    }

    private void handleCloseRequest(Stage stage, Event event) {
        Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
        alert.initOwner(stage);
        alert.setTitle("Quit Game");
        alert.setHeaderText("You are about to quit playing.");
        alert.setContentText("Are you sure you want to quit?");

        Optional<ButtonType> result = alert.showAndWait();

        if (result.isPresent() && result.get() == ButtonType.OK) {
            Platform.exit();
        } else {
            event.consume();
        }
    }

    private void handleRestartRequest(Stage stage) {
        Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
        alert.initOwner(stage);
        alert.setTitle("Restart Game");
        alert.setHeaderText("You are about to restart the game.");
        alert.setContentText("Are you sure you want to restart?");

        Optional<ButtonType> result = alert.showAndWait();

        if (result.isPresent() && result.get() == ButtonType.OK) {
            createNewGame();

            Output.clear();
            Output.print(game.getPrologue());
        }
    }

    private void handleHelpRequest() {
        var helpStage = new Stage();
        WebView webView = new WebView();

        Scene helpScene = new Scene(webView);

        helpStage.setScene(helpScene);
        helpStage.setTitle("Schmorn Help");
        helpStage.show();

        var helpPath = Objects.requireNonNull(Session.class.getResource("help.html")).toExternalForm();

        webView.getEngine().load(helpPath);

        helpStage.setWidth(1280);
        helpStage.setHeight(720);
    }
}
