package cn.forevermc.launcher.view.components.control;

import com.sun.javafx.scene.control.VirtualScrollBar;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.scene.control.ListView;
import javafx.scene.control.skin.ListViewSkin;
import javafx.scene.control.skin.VirtualFlow;
import lombok.extern.slf4j.Slf4j;
import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.fx.utils.SmoothScroll;
import com.imyeyu.java.ref.Ref;

/**
 * @author 夜雨
 * @since 2024-07-14 20:38
 */
@Slf4j
public class MCList<T> extends ListView<T> {

	protected static final String STYLE_CLASS_LIST = "mc-list";

	protected final BooleanProperty isLoading;

	protected final BooleanBinding showingVScrollBar;

	private VirtualScrollBar vBar;

	public MCList() {
		isLoading = new SimpleBooleanProperty(true);

		MCLabel emptyList = new MCLabel(TimiFXUI.MULTILINGUAL.text("select.empty"));
		MCLabel loading = new MCLabel(TimiFXUI.MULTILINGUAL.text("loading"));
		placeholderProperty().bind(Bindings.when(isLoading).then(loading).otherwise(emptyList));

		getStyleClass().addAll(STYLE_CLASS_LIST, TimiFXUI.CSS.BORDER_N);

		SmoothScroll.virtual(this);

		showingVScrollBar = Bindings.createBooleanBinding(() -> {
			// TODO 最大化最小化无效
			try {
				if (vBar == null && getSkin() != null && getSkin() instanceof ListViewSkin<?> skin) {
					VirtualFlow<?> flow = Ref.getFieldValue(skin, "flow", VirtualFlow.class);
					vBar = Ref.getFieldValue(flow, "vbar", VirtualScrollBar.class);
				}
				if (vBar != null) {
					return vBar.isVisible();
				}
			} catch (Exception e) {
				log.error("ref MCList virtual scroll bar error", e);
			}
			return false;
		}, skinProperty(), layoutBoundsProperty());
	}

	public BooleanBinding showingVScrollBarProperty() {
		return showingVScrollBar;
	}

	/** @return true 为正在加载 */
	public boolean isLoading() {
		return isLoading.get();
	}

	/** @return 正在加载属性 */
	public BooleanProperty loadingProperty() {
		return isLoading;
	}

	/** @param isLoading true 为正在加载 */
	public void setLoading(boolean isLoading) {
		this.isLoading.set(isLoading);
	}
}