package top.r3944realms.docchecktoolrefactored.ui;

import javafx.animation.FadeTransition;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.util.Duration;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import top.r3944realms.docchecktoolrefactored.Main;
import top.r3944realms.docchecktoolrefactored.ui.utils.DialogUtil;
import top.r3944realms.docchecktoolrefactored.util.LoggerMarker;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer;

/**
 * The type Scene manager.
 */
@Slf4j
public class SceneManager {
    @Getter
    @Setter
    private static Stage primaryStage;
    @Getter
    @Setter
    public static Image logo;
    @Getter
    private static MainStageController mainController;
    @Getter
    private static final List<Stage> openStages = new ArrayList<>();

    /**
     * Init.
     *
     * @param primaryStage the primary stage
     * @param logo the logo image
     */
    public static void init(Stage primaryStage, Image logo) {
        SceneManager.primaryStage = primaryStage;
        SceneManager.logo = logo;
        primaryStage.getIcons().add(logo);
    }

    /**
     * Switch login view.
     */
    public static void switchLoginView() {
        SceneManager.loadView("/fxml/login-view.fxml","数字化验收工具 - 登录", 400, 300);
    }

    /**
     * Switch main view.
     */
    public static void switchMainView() {
        try {
            FXMLLoader loader = new FXMLLoader(Objects.requireNonNull(Main.class.getResource("/fxml/main-view.fxml")));
            Parent root = loader.load();
            mainController = loader.getController(); // 保存控制器引用
            Scene newScene = new Scene(root, 1200, 900);

            String dialogCssPath = Objects.requireNonNull(Main.class.getResource("/css/inner/dialog.css")).toExternalForm();
            newScene.getStylesheets().addAll(dialogCssPath);

            applyFadeTransition(root);

            primaryStage.setScene(newScene);
            primaryStage.centerOnScreen();
            primaryStage.setTitle("数字化验收工具 - 主界面");

            // 设置窗口关闭确认
            primaryStage.setOnCloseRequest(event -> {
                if (!DialogUtil.showExitConfirmation(primaryStage)) {
                    event.consume();
                }
            });

        } catch (IOException e) {
            log.error(LoggerMarker.TRACE_MARKER, "Failed to load main view", e);
            DialogUtil.showErrorDialog("错误", "加载主界面失败", e.getMessage());
        }
    }
    /**
     * 打开设置窗口
     */
    public static void openSettingView() {
        try {
            Parent root = FXMLLoader.load(Objects.requireNonNull(Main.class.getResource("/fxml/setting-view.fxml")));
            Stage settingStage = new Stage();
            settingStage.getIcons().add(logo);
            settingStage.setTitle("数字化验收工具 - 设置");
            Scene scene = new Scene(root, 362, 332);
            settingStage.setScene(scene); // 默认大小可调
            settingStage.initOwner(primaryStage); // 设置父窗口
            settingStage.initModality(Modality.WINDOW_MODAL);

            String dialogCssPath = Objects.requireNonNull(Main.class.getResource("/css/inner/dialog.css")).toExternalForm();
            scene.getStylesheets().addAll(dialogCssPath);

            settingStage.setResizable(false);
            settingStage.centerOnScreen();

            settingStage.show();
            openStages.add(settingStage);

        } catch (IOException e) {
            log.error(LoggerMarker.TRACE_MARKER, "Failed to open setting view: {}", e.getMessage(), e);
            DialogUtil.showErrorDialog("错误", "加载设置窗口失败", "无法加载设置窗口: " + e.getMessage());
        }
    }

    /**
     * Load view.
     *
     * @param fxmlPath the fxml path
     * @param title    the title
     * @param width    the width
     * @param height   the height
     */
// 基础视图加载方法
    public static void loadView(String fxmlPath, String title, int width, int height) {
        loadView(fxmlPath, title, width, height, null);
    }

    /**
     * Load view.
     *
     * @param fxmlPath    the fxml path
     * @param title       the title
     * @param width       the width
     * @param height      the height
     * @param initializer the initializer
     */
    public static void loadView(String fxmlPath, String title, int width, int height, Consumer<Stage> initializer) {
        try {
            Parent root = FXMLLoader.load(Objects.requireNonNull(Main.class.getResource(fxmlPath)));
            Scene newScene = new Scene(root, width, height);

            String dialogCssPath = Objects.requireNonNull(Main.class.getResource("/css/inner/dialog.css")).toExternalForm();
            newScene.getStylesheets().addAll(dialogCssPath);
            // 淡入效果
            applyFadeTransition(root);

            primaryStage.setScene(newScene);
            primaryStage.centerOnScreen();
            primaryStage.setTitle(title);

            if (initializer != null) {
                initializer.accept(primaryStage);
            }

            // 设置窗口关闭确认
            primaryStage.setOnCloseRequest(event -> {
                if (!DialogUtil.showExitConfirmation(primaryStage)) {
                    event.consume();
                }
            });
        } catch (IOException e) {
            log.error(LoggerMarker.TRACE_MARKER, "Failed to load view: {}", fxmlPath, e);
            DialogUtil.showErrorDialog("错误", "加载视图失败", "无法加载视图: " + e.getMessage());
        }
    }
    private static void applyFadeTransition(Parent root) {
        root.setOpacity(0);
        FadeTransition fadeIn = new FadeTransition(Duration.millis(300), root);
        fadeIn.setToValue(1.0);
        fadeIn.play();
    }

    /**
     * Primary scene handler.
     *
     * @param handler the handler
     */
    public static void primarySceneHandler(Consumer<Scene> handler) {
        handler.accept(getPrimaryStage().getScene());
    }

    /**
     * Try to get scene handler.
     *
     * @param node    the node
     * @param handler the handler
     */
    public static void tryGetSceneHandler(@NonNull Node node, Consumer<Scene> handler) {
        node.sceneProperty().addListener((observable, oldScene, newScene) -> Optional.ofNullable(newScene).ifPresent(handler));
    }
}
