package com.imyeyu.fx.ui.components.alert;

import com.imyeyu.fx.TimiFX;
import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.fx.utils.scroll.SmoothScroll;
import com.imyeyu.fx.utils.Windows;
import com.imyeyu.java.bean.CallbackArg;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.scene.control.TextArea;
import javafx.scene.layout.Border;
import javafx.stage.Window;
import lombok.Getter;

import java.io.PrintWriter;
import java.io.StringWriter;

/**
 * 文本域输入弹窗
 *
 * @author 夜雨
 * @since 2022-01-20 00:36
 */
public class AlertTextArea extends AbstractAlertInput<TextArea> {

	/** 反馈错误事件 */
	@Getter
	private static CallbackArg<String> onFeedback4Error;

	/** 默认构造 */
	public AlertTextArea() {
		this("");
	}

	/**
	 * 文本域输入弹窗
	 *
	 * @param text 输入内容
	 */
	public AlertTextArea(String text) {
		this(AlertType.INFORMATION, AlertType.INFORMATION.getTitle(), "", text, AlertButton.confirm(), AlertButton.cancel());
	}

	/**
	 * 文本域输入弹窗
	 *
	 * @param content 提示
	 * @param text    输入内容
	 */
	public AlertTextArea(String content, String text) {
		this(AlertType.INFORMATION, AlertType.INFORMATION.getTitle(), content, text, AlertButton.confirm(), AlertButton.cancel());
	}

	/**
	 * 文本域输入弹窗
	 *
	 * @param text 输入内容
	 * @param buttons 可控按钮
	 */
	public AlertTextArea(String text, AlertButton... buttons) {
		this(AlertType.INFORMATION, AlertType.INFORMATION.getTitle(), "", text, buttons);
	}

	/**
	 * 文本域输入弹窗
	 *
	 * @param content 提示
	 * @param text    输入内容
	 * @param buttons    可控按钮
	 */
	public AlertTextArea(String content, String text, AlertButton... buttons) {
		this(AlertType.INFORMATION, AlertType.INFORMATION.getTitle(), content, text, buttons);
	}

	/**
	 * 文本域输入弹窗
	 *
	 * @param type    弹窗类型
	 * @param title   标题
	 * @param content 内容
	 * @param text    预设输入框文本
	 * @param buttons    可控按钮
	 */
	public AlertTextArea(AlertType type, String title, String content, String text, AlertButton... buttons) {
		super(new TextArea(), type, title, content, text, buttons);

		SmoothScroll.text.install(getInput());
		setResizable(true);

		// 没有按钮监听
		BooleanBinding emptyButton = Bindings.createBooleanBinding(() -> {
			boolean emptyLeft   = getLeftButtons().getChildren().isEmpty();
			boolean emptyCenter = getCenterButtons().getChildren().isEmpty();
			boolean emptyRight  = getRightButtons().getChildren().isEmpty();
			return emptyLeft && emptyCenter && emptyRight;
		}, getLeftButtons().getChildren(), getCenterButtons().getChildren(), getRightButtons().getChildren());

		emptyButton.addListener((obs, o, isEmpty) -> {
			btnPane.setVisible(!isEmpty);
			btnPane.setManaged(!isEmpty);
			super.content.setPadding(isEmpty ? Insets.EMPTY : PADDING_CONTENT);
			super.btnPane.setPadding(isEmpty ? Insets.EMPTY : PADDING_BUTTON);
		});
		input.borderProperty().bind(Bindings.when(emptyButton).then(Stroke.TOP).otherwise(Stroke.DEFAULT));
		root.borderProperty().bind(Bindings.when(tips.visibleProperty()).then(Stroke.TOP).otherwise(Border.EMPTY));
	}

	/**
	 * 一般提示
	 *
	 * @param owner   依赖窗体
	 * @param content 内容
	 * @return 弹窗对象
	 */
	public static AlertTextArea info(Window owner, String content) {
		AlertTextArea alert = new AlertTextArea(content);
		alert.getInput().setEditable(false);
		alert.clearButton();
		Windows.showCentered(owner, alert);
		return alert;
	}

	/**
	 * 一般错误
	 *
	 * @param owner   依赖窗体
	 * @param content 内容
	 * @return 弹窗对象
	 */
	public static AlertTextArea error(Window owner, String content) {
		return error(owner, "", content);
	}

	/**
	 * 一般错误
	 *
	 * @param owner   依赖窗体
	 * @param tips    提示
	 * @param content 内容
	 * @return 弹窗对象
	 */
	public static AlertTextArea error(Window owner, String tips, String content) {
		AlertTextArea alert = new AlertTextArea(AlertType.ERROR, AlertType.ERROR.getTitle(), tips, content);
		alert.getInput().setEditable(false);
		alert.getInput().setPrefSize(750, 340);
		alert.content.setPadding(Insets.EMPTY);
		alert.btnPane.setPadding(Insets.EMPTY);
		Windows.showCentered(owner, alert);
		return alert;
	}

	/**
	 * 异常错误
	 *
	 * @param owner 依赖窗体
	 * @param e     异常
	 * @return 弹窗对象
	 */
	public static AlertTextArea error(Window owner, Throwable e) {
		return error(owner, e.getMessage(), e);
	}

	/**
	 * 异常错误
	 *
	 * @param owner 依赖窗体
	 * @param tips   提示
	 * @param e      异常
	 * @return 弹窗对象
	 */
	public static AlertTextArea error(Window owner, String tips, Throwable e) {
		StringWriter sw = new StringWriter();
		e.printStackTrace(new PrintWriter(sw));
		String text = sw.getBuffer().toString();

		AlertTextArea alert = new AlertTextArea(AlertType.ERROR, AlertType.ERROR.getTitle(), tips, text);
		alert.getTips().setPrefWidth(750);
		alert.getInput().setEditable(false);
		alert.getInput().setPrefSize(750, 340);
		if (onFeedback4Error != null) {
			// 支持反馈时显示反馈按钮和关闭
			alert.putButtons(new AlertButton(HPos.LEFT, AlertButton.Action.OTHER, TimiFXUI.MULTILINGUAL.text("alert.feedback")));
			alert.putButtons(AlertButton.close());
			alert.setOnActionEvent(action -> {
				if (action == AlertButton.Action.OTHER) {
					onFeedback4Error.handler(tips + "\n" + text);
					return false;
				}
				return true;
			});
		} else {
			alert.content.setPadding(Insets.EMPTY);
			alert.btnPane.setPadding(Insets.EMPTY);
		}
		alert.autoSize().showRelativeCenter(owner);
		return alert;
	}

	/**
	 * 设置反馈错误事件，全局事件，设置一次即可
	 *
	 * @param onFeedback4Error 反馈错误事件
	 */
	public static void setOnFeedback4Error(CallbackArg<String> onFeedback4Error) {
		AlertTextArea.onFeedback4Error = onFeedback4Error;
	}
}
