package com.ecep.contract.util;

import java.io.IOException;
import java.net.URL;
import java.util.concurrent.CompletableFuture;

import com.ecep.contract.AppV2;
import com.ecep.contract.Desktop;
import com.ecep.contract.SpringApp;

import javafx.application.Platform;
import javafx.fxml.FXMLLoader;

public class FxmlUtils {

    public static FXMLLoader newLoader(String path) {
        FXMLLoader loader = new FXMLLoader();
        URL location = AppV2.class.getResource(path);
        if (location == null) {
            throw new RuntimeException("无法找到窗口资源文件 " + path);
        }
        loader.setLocation(location);
        loader.setControllerFactory(SpringApp::getBean);
        return loader;
    }

    public static CompletableFuture<FXMLLoader> newLoaderAsync(String path,
            java.util.function.Consumer<FXMLLoader> consumer) {
        return CompletableFuture.supplyAsync(() -> {
            FXMLLoader loader = newLoader(path);
            try {
                loader.load();
            } catch (IOException e) {
                throw new RuntimeException("Unable open " + path, e);
            }
            consumer.accept(loader);
            return loader;
        }).whenComplete((v, ex) -> {
            if (ex != null) {
                UITools.showExceptionAndWait("无法打开 " + path + " 界面", ex);
            }
        });
    }

    /**
     * 异步载入显示界面
     *
     * @param path             fxml文件路径，类地址 / 开头 根路径
     * @param initializeLoader fxml 文件加载完毕后，回调函数
     * @param runLater         在JavaFx线程中执行的回调函数
     * @return CompletableFuture
     */
    public static CompletableFuture<Void> newLoaderAsyncWithRunLater(
            String path,
            java.util.function.Consumer<FXMLLoader> initializeLoader,
            java.util.function.Consumer<FXMLLoader> runLater) {
        CompletableFuture<Void> future = new CompletableFuture<>();
        CompletableFuture.runAsync(() -> {
            try {
                FXMLLoader loader = newLoader(path);
                if (initializeLoader != null) {
                    initializeLoader.accept(loader);
                }
                loader.load();
                Platform.runLater(() -> {
                    try {
                        runLater.accept(loader);
                        future.complete(null);
                    } catch (Exception e) {
                        future.completeExceptionally(e);
                    }
                });
            } catch (IOException e) {
                future.completeExceptionally(new RuntimeException("Unable open " + path, e));
            }
        }, Desktop.instance.getExecutorService()).whenComplete((v, ex) -> {
            if (ex != null) {
                future.completeExceptionally(ex);
            }
        });
        future.whenComplete((v, ex) -> {
            if (ex != null) {
                UITools.showExceptionAndWait("无法打开 " + path + " 界面", ex);
            }
        });
        return future;
    }
}
