import type { VNode } from 'vue';
import type { _ButtonArgsBase, ButtonLayout, ButtonSize } from './button-layout';
import { Tooltip } from 'bootstrap';
import { Prop, toNative } from 'vue-facing-decorator';
import TsxComponent, { Component } from '../../app/vuetsx';
import { isNullOrEmpty } from '../../common/utils/is-null-or-empty';

interface ButtonArgs extends _ButtonArgsBase {
	href?: string;
	hrefTarget?: '_blank' | '_self' | '_parent' | '_top';
	/** Render the href variant as a <router-link> (SPA navigation, no full reload) instead of a plain <a>. Default false. */
	isRouterLink?: boolean;
	clicked?: (e: any) => void;
}

@Component
class ButtonComponent extends TsxComponent<ButtonArgs> implements ButtonArgs {
	@Prop() cssClass!: string;
	@Prop() layout!: ButtonLayout;
	@Prop() text!: string | VNode;
	@Prop() tooltip!: string;
	@Prop() size!: ButtonSize;
	@Prop() round!: boolean;
	@Prop() outlined!: boolean;
	@Prop() dismissModal!: boolean;
	@Prop() icon!: string;
	@Prop() iconButton!: boolean;
	@Prop() iconOnRight!: boolean;
	@Prop() clicked: (e: any) => void;
	@Prop() disabled!: boolean;
	@Prop() fullWidth!: boolean;
	@Prop() pulsate!: boolean;
	@Prop() ariaLabel!: string;
	@Prop() href!: string;
	@Prop() hrefTarget!: '_blank' | '_self' | '_parent' | '_top';
	@Prop() isRouterLink!: boolean;

	// When update, update Button & DropdownButton :/
	getCssClass(): string {
		return (
			this.getParsedLayout()
			+ (this.size != null ? ` ${this.size}` : '')
			+ (this.outlined ? ' btn-simple' : '')
			+ (this.round ? ' btn-round' : '')
			+ (this.iconButton ? ' btn-icon' : '')
			+ (this.cssClass != null ? ` ${this.cssClass}` : '')
			+ (this.fullWidth ? ' full-width' : '')
			+ (this.pulsate ? ' btn-pulsating' : '')
			+ (this.iconOnRight ? ' btn-icon-on-right' : '')
		);
	}

	getParsedLayout() {
		if (!this.outlined) {
			return this.layout || 'btn btn-primary';
		} else {
			return (this.layout || 'btn btn-primary').replace('btn btn-', 'btn btn-outline-');
		}
	}

	handleButtonClicked(e) {
		// Optional since the href/router-link variants are pure navigation.
		this.clicked?.(e);

		if (!isNullOrEmpty(this.tooltip)) {
			document.querySelector('body > .tooltip')?.remove();
		}

		// Blur after a POINTER click only (clears the lingering focus ring). For
		// keyboard activation (Enter/Space → click with detail === 0) we must NOT
		// blur, or focus drops to <body> and keyboard navigation breaks — e.g.
		// repeatedly pressing a +/- counter in the occupancy picker (WCAG 2.4.3).
		if (e?.detail !== 0) {
			(this.$el as HTMLElement)?.blur?.();
		}
	}

	mounted() {
		if (!isNullOrEmpty(this.tooltip)) {
			// eslint-disable-next-line no-new
			new Tooltip(this.$el);
		}
	}

	render(h) {
		if (this.href == null) {
			return (
				<button type="button" class={this.getCssClass()} disabled={this.disabled == true} data-dismiss={this.dismissModal ? 'modal' : null} data-bs-dismiss={this.dismissModal ? 'modal' : null} title={this.tooltip} aria-label={this.ariaLabel || undefined} onClick={(e) => { this.handleButtonClicked(e); }}>
					{this.icon && this.iconOnRight != true
					&& (
						<span class="btn-label">
							<i class={this.icon} aria-hidden="true"></i>
							{this.text
							&& <span>&nbsp;&nbsp;</span>}
						</span>
					)}

					{this.text}

					{this.icon && this.iconOnRight == true
					&& (
						<span class="btn-label">
							{this.text
							&& <span>&nbsp;&nbsp;</span>}
							<i class={this.icon} aria-hidden="true"></i>
						</span>
					)}
				</button>
			);
		} else if (this.isRouterLink == true) {
			return (
				// disabled must be null (not false) when enabled: router-link passes it through as a fallthrough
				// attr, which stringifies false to disabled="false" — and CSS [disabled] matches by presence.
				<router-link to={this.href} class={this.getCssClass()} disabled={this.disabled == true ? true : null} data-dismiss={this.dismissModal ? 'modal' : null} data-bs-dismiss={this.dismissModal ? 'modal' : null} title={this.tooltip} aria-label={this.ariaLabel || undefined}>
					{this.icon && this.iconOnRight != true
					&& (
						<span class="btn-label">
							<i class={this.icon} aria-hidden="true"></i>
							{this.text
							&& <span>&nbsp;&nbsp;</span>}
						</span>
					)}

					{this.text}

					{this.icon && this.iconOnRight == true
					&& (
						<span class="btn-label">
							{this.text
							&& <span>&nbsp;&nbsp;</span>}
							<i class={this.icon} aria-hidden="true"></i>
						</span>
					)}
				</router-link>
			);
		} else {
			return (
				<a href={this.href} target={this.hrefTarget == null ? '_self' : this.hrefTarget} class={this.getCssClass()} disabled={this.disabled == true ? true : null} data-dismiss={this.dismissModal ? 'modal' : null} data-bs-dismiss={this.dismissModal ? 'modal' : null} title={this.tooltip} aria-label={this.ariaLabel || undefined}>
					{this.icon && this.iconOnRight != true
					&& (
						<span class="btn-label">
							<i class={this.icon} aria-hidden="true"></i>
							{this.text
							&& <span>&nbsp;&nbsp;</span>}
						</span>
					)}

					{this.text}

					{this.icon && this.iconOnRight == true
					&& (
						<span class="btn-label">
							{this.text
							&& <span>&nbsp;&nbsp;</span>}
							<i class={this.icon} aria-hidden="true"></i>
						</span>
					)}
				</a>
			);
		}
	}
}

const Button = toNative(ButtonComponent);
export default Button;
