package id.co.gtc.erhacam;

import javafx.animation.PauseTransition;
import javafx.application.Platform;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.util.Duration;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;

import static Config.SomeCodes.*;

public class AutoCloseAlert {

    private static Stage currentAlertStage;
    public static String shownTitle  = "";
    public static String shownContent = "";
    public static String shownHeader = "";
    public static Image shownBanner = null;
    public static Image banner_01;
    public static Image banner_02;

    public static void init(){
        String f_01 = ExtractResource("/IU photoboth-01.jpg");
        System.out.println("Banner 01 extracted as file: "+f_01);
        String f_02 = ExtractResource("/IU photoboth-02.jpg");
        System.out.println("Banner 02 extracted as file: "+f_02);
        banner_01 = LoadImage(f_01);
        if (banner_01!=null) System.out.println("Banner 01 loaded"); else System.out.println("Banner 01 not loaded");
        banner_02 = LoadImage(f_02);
        if (banner_02!=null) System.out.println("Banner 02 loaded"); else System.out.println("Banner 02 not loaded");
    }



    /**
     * Close the current alert if it is shown
     */
    public static void close(){
        Optional.ofNullable(currentAlertStage).ifPresent(Stage::close);
        currentAlertStage = null;
        clear();
    }

    /**
     * Show an alert with a title, content, and automatically close after a few seconds
     * @param title the title of the alert
     * @param content the content of the alert
     * @param seconds the number of seconds before the alert is closed, or put 0 to keep it open
     * @param onClose What to do after auto close
     */
    public static void show(String title, String content, int seconds, Consumer<String> onClose){
        Platform.runLater(()->{
            Stage alertStage = _showtext(title, "", content);
            closeAlertStage(seconds, onClose, alertStage);
        });

    }



    /**
     * Show an alert with a title, header, content, and automatically close after a few seconds
     * If called several times, the previous alert will be closed before showing a new one
     * @param title the title of the alert
     * @param header the header of the alert
     * @param content the content of the alert
     * @param seconds the number of seconds before the alert is closed, or put 0 to keep it open
     * @param onClose What to do after auto close
     */
    public static void show(String title, String header, String content, int seconds, Consumer<String> onClose) {
        Platform.runLater(()->{
            Stage alertStage = _showtext(title, header, content);
            closeAlertStage(seconds, onClose, alertStage);
        });
    }

    public static void showbanner(Image b1, int seconds, Consumer<String> onClose){
        Platform.runLater(()->{
            Stage alertStage = _showbanner(b1);
            closeAlertStage(seconds, onClose, alertStage);
        });
    }

    private static Stage _showbanner(Image image){
        close();

        Stage alertStage = new Stage();
        alertStage.initModality(Modality.APPLICATION_MODAL);
        alertStage.initStyle(StageStyle.UTILITY);
        alertStage.setAlwaysOnTop(true);
        alertStage.setResizable(false);
        //System.out.println("_showbanner creating stage");

        if (image!=null){
            ImageView imageView = new ImageView(image);
            imageView.setPreserveRatio(true);
            imageView.setFitWidth(1280);
            imageView.setSmooth(true);
            StackPane stackPane = new StackPane(imageView);
            alertStage.setScene(new Scene(stackPane, 1280, 720));
            //System.out.println("_showbanner setscene");
        } //else System.out.println("_showbanner not setscene because image is null");

        alertStage.centerOnScreen();
        alertStage.show();
        //System.out.println("_showbanner show stage");

        currentAlertStage = alertStage;
        shownBanner = image;
        shownTitle = "";
        shownContent = "";
        shownHeader = "";

        return alertStage;
    }



    /**
     * Create an alert with a title, header, and content
     * @param title the title
     * @param header the header
     * @param content the content
     * @return the alert stage
     */
    private static Stage _showtext(String title, String header, String content){
        // close previous alert before showing a new one
        close();

        Stage alertStage = new Stage();
        alertStage.initModality(Modality.APPLICATION_MODAL);
        alertStage.initStyle(StageStyle.UTILITY);
        alertStage.setAlwaysOnTop(true);
        alertStage.setResizable(false);

        double screenwidth = Screen.getPrimary().getVisualBounds().getWidth();
        double width = screenwidth/4;
        double height = width * 9 / 16;

        List<Node> children = new ArrayList<>();
        if (ValidString(header)){
            Label headerLabel = new Label(header);
            headerLabel.setStyle("-fx-font-weight: bold; -fx-font-size: 16px;");
            headerLabel.setMinHeight(height*0.25);
            children.add(headerLabel);
        }
        if (ValidString(content)){
            Label contentLabel = new Label(content);
            contentLabel.setStyle("-fx-font-size: 12px;");
            contentLabel.setMinHeight(height*0.75);
            children.add(contentLabel);
        }

        VBox root = new VBox(10, children.toArray(new Node[0]));
        root.setPrefSize(width, height);
        root.setAlignment(Pos.CENTER);

        Scene scene = new Scene(root);
        alertStage.setScene(scene);

        alertStage.setTitle(title);

        alertStage.show();
        currentAlertStage = alertStage;
        shownHeader = ValidString(header) ? header : "";
        shownContent = ValidString(content) ? content : "";
        shownTitle = ValidString(title) ? title : "";
        shownBanner = null;

        return alertStage;
    }

    /**
     * Close the alert after a few seconds
     * @param seconds the number of seconds before the alert is closed, if 0, the alert will not be closed
     * @param onClose What to do after auto close
     * @param alertStage the alert stage to be closed
     */
    private static void closeAlertStage(int seconds, Consumer<String> onClose, Stage alertStage) {
        if (seconds>0){
            PauseTransition delay = new PauseTransition(Duration.seconds(seconds));
            delay.setOnFinished(e -> {
                alertStage.close();
                if (currentAlertStage == alertStage) {
                    currentAlertStage = null;
                }
                if (onClose!=null) onClose.accept(shownTitle);
                clear();
            } );
            delay.play();
        }
    }

    private static Image LoadImage(String filename){
        if (ValidFile(filename)){
            try{
                Image mm =  new Image(Paths.get(filename).toUri().toString());
                System.out.println("Load image from "+filename);
                return mm;
            } catch (Exception e){
                System.out.println("Error loading image: " + filename+", Message: "+e.getMessage());
            }
        } else System.out.println("LoadImage: Invalid file: "+filename);
        return null;
    }

    private static void clear(){
        shownTitle = "";
        shownContent = "";
        shownHeader = "";
    }
}
