package cn.forevermc.launcher.view.pages;

import cn.forevermc.launcher.bean.ComponentSize;
import cn.forevermc.launcher.bean.MCPopupTips;
import cn.forevermc.launcher.bean.Pack;
import cn.forevermc.launcher.service.MCPopupTipsService;
import cn.forevermc.launcher.util.Resources;
import cn.forevermc.launcher.view.components.AbstractContentPane;
import cn.forevermc.launcher.view.components.control.MCButton;
import cn.forevermc.launcher.view.components.control.MCLabel;
import cn.forevermc.launcher.view.components.control.MCList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.ListCell;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.fx.utils.BorderStroke;
import com.imyeyu.inject.annotation.Component;
import com.imyeyu.inject.annotation.Inject;
import com.imyeyu.inject.annotation.InvokeForInjected;
import com.imyeyu.io.IOSize;
import com.imyeyu.utils.Time;

/**
 * 整合版下载页面
 *
 * @author 夜雨
 * @since 2023-06-13 23:30
 */
public abstract class PackSelectPane extends AbstractContentPane {

	@Inject
	protected PackListPane packListPane;

	@Inject
	protected SourceListPane sourceListPane;

	protected MCButton install, back;

	public PackSelectPane() {
		MCLabel titleList = new MCLabel(TimiFXUI.MULTILINGUAL.text("fmc.launcher.download.fmc.list"));
		titleList.setPadding(new Insets(24, 0, 16, 8));
		titleList.prefWidthProperty().bind(widthProperty().multiply(.618));

		MCLabel titleUrl = new MCLabel(TimiFXUI.MULTILINGUAL.text("fmc.launcher.download.fmc.url"));
		titleUrl.setPadding(new Insets(24, 0, 16, 0));
		titleUrl.prefWidthProperty().bind(widthProperty().multiply(1 - .618).subtract(8));

		// 安装
		install = new MCButton(ComponentSize.MEDIUM, TimiFXUI.MULTILINGUAL.text("install"));

		// 返回
		back = new MCButton(ComponentSize.MEDIUM, TimiFXUI.MULTILINGUAL.text("back"));

		content.setPadding(Insets.EMPTY);
		setTop(new HBox(titleList, titleUrl));
		setBottomPaneValue(install, back);
	}

	@InvokeForInjected
	private void injected() {
		install.disableProperty().bind(sourceListPane.getSelectionModel().selectedItemProperty().isNull());

		packListPane.prefWidthProperty().bind(widthProperty().multiply(.618));
		sourceListPane.prefWidthProperty().bind(widthProperty().multiply(1 - .618));
		setContentPane(new BorderPane() {{
			setCenter(new StackPane() {{
				setBorder(new BorderStroke(Color.valueOf("#FFF4")).right(2).build());
				getChildren().setAll(packListPane);
			}});
			setRight(sourceListPane);
		}});
	}

	/**
	 * 整合版列表面板
	 *
	 * @author 夜雨
	 * @since 2023-06-15 10:17
	 */
	@Component
	protected static class PackListPane extends MCList<Pack> {

		@Inject
		private MCPopupTipsService mcPopupTipsService;

		public PackListPane() {
			setCellFactory(cell -> new ListCell<>() {

				final MCLabel gameVer, name, title, deprecated, time;
				final BorderPane root;
				final MCPopupTips tips;

				{
					// 提示
					tips = new MCPopupTips();
					tips.getNode().setMaxWidth(440);
					tips.getNode().setWrapText(true);
					tips.enableProperty().bind(tips.getNode().textProperty().isNotEmpty());

					// 名称
					name = new MCLabel();

					// 标题
					title = new MCLabel();
					title.setTextFill(Colorful.LIGHT_GRAY);
					title.getStyleClass().clear();

					// 游戏版本
					gameVer = new MCLabel();

					// 过时提示
					deprecated = new MCLabel(TimiFXUI.MULTILINGUAL.text("deprecated"));
					deprecated.setTextFill(Colorful.LIGHT_GRAY);

					// 更新时间
					time = new MCLabel();

					root = new BorderPane();
					BorderPane.setAlignment(name, Pos.CENTER_LEFT);
					root.setLeft(new BorderPane() {{
						setPadding(new Insets(0, 4, 0, 0));
						setLeft(new MCLabel("["));
						setCenter(new StackPane() {{
							setAlignment(Pos.CENTER_LEFT);
							setPrefWidth(50);
							getChildren().add(gameVer);
						}});
						setRight(new MCLabel("]"));
					}});
					root.setCenter(new HBox(4, name, title));
					root.setRight(new HBox(8, deprecated, time));

					mcPopupTipsService.install(this, tips);
				}

				@Override
				protected void updateItem(Pack item, boolean empty) {
					super.updateItem(item, empty);
					if (empty || item == null) {
						setGraphic(null);
						tips.getNode().setText("");
						deprecated.setVisible(false);
					} else {
						name.setText(item.getName());
						title.setText(" - " + item.getTitle());
						gameVer.setText(item.getGameVer());
						time.setText(Time.toDate(item.getCreatedAt()));

						// 提示内容
						String tipsContent = item.getDescription();
						if (item.isDeprecated()) {
							setOpacity(.6);
							deprecated.setVisible(true);
						}
						Object[] tipsParams = {
								item.getName(),
								item.getTitle(),
								item.getGameVer(),
								item.getVer(),
								IOSize.format(item.getSize()),
								Time.toDateTime(item.getCreatedAt()),
								tipsContent
						};
						tips.getNode().setText(TimiFXUI.MULTILINGUAL.textArgs("fmc.launcher.download.fmc.tips", tipsParams));
						setGraphic(root);
					}
				}
			});
		}
	}

	/**
	 * 下载源列表面板
	 *
	 * @author 夜雨
	 * @since 2023-06-15 10:17
	 */
	@Component
	protected static class SourceListPane extends MCList<Pack.Source> {

		private static final String ATTACH_DL_API = Resources.TIMI_SERVER_API + "/attachment/download";

		@Inject
		private MCPopupTipsService mcPopupTipsService;

		public SourceListPane() {
			setCellFactory(cell -> new ListCell<>() {

				final MCPopupTips tips;

				{
					// 提示
					tips = new MCPopupTips();
					tips.enableProperty().bind(tips.getNode().textProperty().isNotEmpty());

					mcPopupTipsService.install(this, tips);
				}

				@Override
				protected void updateItem(Pack.Source item, boolean empty) {
					super.updateItem(item, empty);
					if (empty || item == null) {
						setText("");
						setGraphic(null);
						tips.getNode().setText("");
					} else {
						setText(item.getName());

						String url = switch (item.getType()) {
							case URL -> item.getData();
							case ATTACH -> ATTACH_DL_API + "/%s".formatted(item.getData());
						};
						String domain = url.substring(0, url.indexOf("/", url.indexOf("//") + 2));
						tips.getNode().setText(TimiFXUI.MULTILINGUAL.textArgs("fmc.launcher.download.fmc.url.tips", domain));
					}
				}
			});
		}
	}
}
