package cn.forevermc.launcher.ctrl.pane;

import cn.forevermc.launcher.bean.Config;
import cn.forevermc.launcher.bean.Game;
import cn.forevermc.launcher.bean.LaunchGame;
import cn.forevermc.launcher.bean.Page;
import cn.forevermc.launcher.service.FMCLoginService;
import cn.forevermc.launcher.service.GameService;
import cn.forevermc.launcher.service.MCPopupTipsService;
import cn.forevermc.launcher.service.PageService;
import cn.forevermc.launcher.util.FabricBuilder;
import cn.forevermc.launcher.view.pages.GameOptionPane;
import javafx.beans.binding.Bindings;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import lombok.extern.slf4j.Slf4j;
import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.fx.utils.FileSelector;
import com.imyeyu.inject.annotation.Controller;
import com.imyeyu.inject.annotation.Inject;
import com.imyeyu.inject.annotation.InvokeForInjected;
import com.imyeyu.inject.annotation.SuperInject;
import com.imyeyu.java.TimiJava;

import java.io.File;

/**
 * 版本配置
 *
 * @author 夜雨
 * @since 2022-12-10 00:50
 */
@Slf4j
@Controller
@SuperInject
public class GameOption extends GameOptionPane {

	@Inject
	private Config config;

	@Inject
	private Dialog dialog;

	@Inject
	private LaunchGame launchGame;

	@Inject
	private GameService gameService;

	@Inject
	private PageService pageService;

	@Inject
	private FMCLoginService fmcLoginService;

	@Inject
	private FabricBuilder fabricBuilder;

	@Inject
	private MCPopupTipsService mcPopupTipsService;

	private final ObjectProperty<Game> game;

	public GameOption() {
		game = new SimpleObjectProperty<>();

		// 选择 Java
		javaSelect.setOnAction(e -> {
			FileSelector selector = new FileSelector(java.getText());
			selector.setTitle(TimiFXUI.MULTILINGUAL.text("fmc.launcher.option.java.select_title"));
			selector.addFilter("Java", "javaw.exe;java.exe;java");
			File file = selector.single(getScene().getWindow());
			if (file != null) {
				java.setText(file.getAbsolutePath());
			}
		});

		// 安装 Fabric
		installFabric.disableProperty().bind(Bindings.createBooleanBinding(() -> {
			Game game = this.game.get();
			if (game == null) {
				return true;
			}
			return game.isFabric() || gameService.getRealVersion(game).isSupportFabric();
		}, game));
		installFabric.setOnAction(e -> {
			dialog.setContent(TimiFXUI.MULTILINGUAL.text("fmc.launcher.pack_option.fabric.installing"));
			dialog.eject();

			new FabricBuilder() {

				{
					setBuildGame(game.get());
				}

				@Override
				protected void onFinish(Game builedGame) {
					pageService.to(Page.GAME_SELECT);

					if (fmcLoginService.isSupportFMCLogin(game.get())) {
						game.get().getOption().getLoginType().set(Game.Option.LoginType.FOREVER_MC);
					}
				}

				@Override
				protected void onException(Throwable e) {
					// TODO 出错应该返回整合包具体设置页
					dialog.setContent(e.getMessage());
					dialog.setCloseEvent(() -> pageService.to(Page.GAME_SELECT));
					dialog.eject();
					log.error("fabric install error", e);
				}
			}.start();
		});

		// 自动连接
		autoConnect.disableProperty().bind(Bindings.createBooleanBinding(() -> TimiJava.isEmpty(server.getText()), server.textProperty()));
		server.textProperty().addListener((obs, o, newServer) -> autoConnect.setValue(TimiJava.isEmpty(newServer)));

		// 完成
		finish.setOnAction(e -> pageService.to(Page.GAME_SELECT));

		// 编辑版本包变更
		game.addListener((obs, oldGame, newGame) -> {
			loginType.getItems().clear();
			if (oldGame != null) {
				java.textProperty().unbindBidirectional(newGame.getOption().getJava());
				autoConnect.valueProperty().unbindBidirectional(newGame.getOption().getAutoConnect());
				server.textProperty().unbindBidirectional(newGame.getOption().getServer());
				loginType.valueProperty().unbindBidirectional(newGame.getOption().getLoginType());

				setTitle("");
				java.clear();
				autoConnect.setValue(false);
				server.clear();
				loginType.setDisable(true);
				loginType.setValue(Game.Option.LoginType.OFFLINE);
				installFabric.disableProperty().unbind();
			}
			if (newGame != null) {
				setTitle(TimiFXUI.MULTILINGUAL.textArgs("fmc.launcher.pack_option.title", newGame.getName()));
				if (fmcLoginService.isSupportFMCLogin(newGame)) {
					loginType.getItems().setAll(Game.Option.LoginType.OFFLINE, Game.Option.LoginType.FOREVER_MC);
				} else {
					loginType.setDisable(true);
				}
				java.textProperty().bindBidirectional(newGame.getOption().getJava());
				autoConnect.valueProperty().bindBidirectional(newGame.getOption().getAutoConnect());
				server.textProperty().bindBidirectional(newGame.getOption().getServer());
				loginType.valueProperty().bindBidirectional(newGame.getOption().getLoginType());
			}
		});
	}

	@InvokeForInjected
	private void injected() {
		mcPopupTipsService.install(autoConnect, TimiFXUI.MULTILINGUAL.text("fmc.launcher.pack_option.auto_connect.tips"));
		mcPopupTipsService.install(loginType, TimiFXUI.MULTILINGUAL.text("fmc.launcher.pack_option.login_type.tips"));

		// TODO auto download runtime
	}

	@Override
	protected void onHide() {
		gameService.storeOption(game.get());
	}

	/**
	 * 设置编辑配置的版本包
	 *
	 * @param game 版本包
	 */
	public void setGame(Game game) {
		this.game.set(game);
	}
}
