package cn.forevermc.launcher.ctrl.pane;

import cn.forevermc.launcher.bean.ComponentSize;
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.GameService;
import cn.forevermc.launcher.service.PageService;
import cn.forevermc.launcher.util.Path;
import cn.forevermc.launcher.view.components.control.MCButton;
import cn.forevermc.launcher.view.components.control.MCLabel;
import cn.forevermc.launcher.view.pages.GameSelectPane;
import com.google.gson.Gson;
import javafx.util.Duration;
import lombok.extern.slf4j.Slf4j;
import com.imyeyu.fx.task.RunAsync;
import com.imyeyu.fx.task.RunAsyncScheduled;
import com.imyeyu.fx.ui.TimiFXUI;
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.io.IO;
import com.imyeyu.java.TimiJava;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 启动选择
 *
 * @author 夜雨
 * @since 2022-11-28 10:22
 */
@Slf4j
@Controller
@SuperInject
public class GameSelect extends GameSelectPane {

	@Inject
	private Config config;

	@Inject
	private Gson gson;

	@Inject
	private Dialog dialog;

	@Inject
	private GameOption gameOption;

	@Inject
	private PageService pageService;

	@Inject
	private GameService gameService;

	@Inject
	private LaunchGame launchGame;

	/** 记录从哪个页面进入的启动选择 */
	private Page from;

	public GameSelect() {
		// 官方原版下载
		originalDL.setOnAction(e -> pageService.to(Page.ORIGINAL_SELECT));

		// 整合版下载
		packDL.setOnAction(e -> pageService.to(Page.PACK_SELECT));

		// 版本设置
		option.setOnAction(e -> {
			gameOption.setGame(list.getSelectionModel().getSelectedItem());
			pageService.to(Page.PACK_OPTION);
		});

		// 删除
		destory.setOnAction(e -> {
			Game selectedGame = list.getSelectionModel().getSelectedItem();
			dialog.setTitle(TimiFXUI.MULTILINGUAL.text("warning"));
			dialog.setContent(TimiFXUI.MULTILINGUAL.textArgs("fmc.launcher.launch_select.delete.tips", selectedGame.getName()));
			dialog.getTitle().setTextFill(Colorful.RED);

			MCButton confirm = new MCButton(ComponentSize.NORMAL, TimiFXUI.MULTILINGUAL.text("confirm"));
			confirm.setDisable(true);
			MCButton cancel = new MCButton(ComponentSize.NORMAL, TimiFXUI.MULTILINGUAL.text("cancel"));

			// 倒数
			new RunAsyncScheduled<Integer>(Duration.seconds(1)) {

				int value = 5;

				@Override
				protected Integer call() {
					return value--;
				}

				@Override
				protected void onFinish(Integer value) {
					confirm.getLabel().setText(TimiFXUI.MULTILINGUAL.textArgs("fmc.launcher.launch_select.delete.confirm", value));
					if (value < 0) {
						confirm.getLabel().setText(TimiFXUI.MULTILINGUAL.text("confirm"));
						confirm.setDisable(false);
						cancel();
					}
				}
			}.start();
			confirm.setOnAction(subE -> {
				dialog.setTitle("");
				dialog.setContent(TimiFXUI.MULTILINGUAL.textArgs("fmc.launcher.launch_select.delete.working", selectedGame.getName()));
				dialog.clearButtons();
				new RunAsync<Void>() {

					@Override
					protected Void call() throws Exception {
						Thread.sleep(500);
						IO.destroy(selectedGame.getPath());
						return null;
					}

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

					@Override
					protected void onException(Throwable e) {
						dialog.setTitle(TimiFXUI.MULTILINGUAL.text("delete.error"));
						dialog.setContent(e.getMessage());
						dialog.setCloseEvent(() -> pageService.to(Page.GAME_SELECT));
					}
				}.start();
			});
			cancel.setOnAction(subE -> pageService.to(Page.GAME_SELECT));
			dialog.setOnHideEvent(() -> {
				dialog.getTitle().setTextFill(Colorful.LIGHT_GRAY);
				dialog.setOnHideEvent(null);
			});
			dialog.setButtons(confirm, cancel);
			dialog.eject();
		});

		// 选择
		select.setOnAction(e -> {
			if (launchGame.get() != null && launchGame.get().equals(list.getSelectionModel().getSelectedItem())) {
				pageService.to(TimiJava.firstNotNull(from, Page.OPTION));
			} else {
				launchGame.set(list.getSelectionModel().getSelectedItem());
			}
		});

		// 返回
		back.setOnAction(e -> pageService.to(TimiJava.firstNotNull(from, Page.OPTION)));
	}

	@InvokeForInjected
	private void injected() {
		parseList();
	}

	@Override
	public void onShow() {
		if (pageService.getPrev() == Page.MENU || pageService.getPrev() == Page.OPTION) {
			from = pageService.getPrev();
		} else if (pageService.getPrev() == Page.DIALOG) {
			// 启动失败的弹窗
			from = Page.MENU;
		}
		parseList();
	}

	/** 解析版本列表 */
	private void parseList() {
		setLoading(true);

		new RunAsync<List<Game>>() {

			/** 启动版本 */
			private Game launchGame;

			@Override
			protected List<Game> call() throws Exception {
				List<Game> result = new ArrayList<>();
				File[] games = IO.dir(Path.P_PACK).listFiles();
				if (games != null) {
					for (int i = 0; i < games.length; i++) {
						File json = new File(IO.fitPath(games[i].getAbsolutePath()) + games[i].getName() + ".json");
						if (json.exists() && json.isFile()) {
							// 只有版本 JSON 存在时才识别为正常版本包
							try {
								Game game = gameService.buildGame(games[i]);
								if (game.getName().equals(config.getLauncher().getGame().get())) {
									this.launchGame = game;
								}
								result.add(game);
							} catch (IOException e) {
								log.error("parse pack data error", e);
							}
						}
					}
				}
				return result;
			}

			@Override
			protected void onFinish(List<Game> gameData) {
				list.getItems().setAll(gameData);
				list.getSelectionModel().select(launchGame);
				GameSelect.this.launchGame.set(launchGame);
				if (list.getItems().size() == 1) {
					list.getSelectionModel().select(0);
					GameSelect.this.launchGame.set(list.getSelectionModel().getSelectedItem());
				}
			}

			@Override
			protected void onFinally() {
				setLoading(false);
				if (list.getItems().isEmpty()) {
					list.placeholderProperty().unbind();
					list.setPlaceholder(new MCLabel(TimiFXUI.MULTILINGUAL.text("fmc.launcher.launch_select.empty")));
				}
			}
		}.start();
	}
}
