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

export interface DropdownButtonArgs extends _ButtonArgsBase {
	subtitle?: string;
	menuOnRight?: boolean;
	rootCssClass?: string;
	displayInline?: boolean;
	menuOnTop?: boolean;
	autoClose?: boolean | 'inside' | 'outside';
	textIsPlaceholder?: boolean;
}

@Component
class DropdownButtonComponent extends TsxComponent<DropdownButtonArgs> implements DropdownButtonArgs {
	@Prop() cssClass!: string;
	@Prop() rootCssClass!: string;
	@Prop() layout!: ButtonLayout;
	@Prop() text!: string | VNode;
	@Prop() textIsPlaceholder?: boolean;
	@Prop() subtitle?: string;
	@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() ariaLabel!: string;
	@Prop() disabled!: boolean;
	@Prop() fullWidth!: boolean;
	@Prop() pulsate!: boolean;
	@Prop() menuOnRight!: boolean;
	@Prop() displayInline?: boolean;
	@Prop() menuOnTop?: boolean;
	@Prop({ default: true }) autoClose?: boolean | 'inside' | 'outside';

	// When update, update Button & DropdownButton :/
	getCssClass(): string {
		return (
			`dropdown-toggle ${
				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' : ''
			}${this.subtitle ? ' btn-subtitle' : ''}`
		);
	}

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

	open() {
		// Only click the toggle button — querying with `button` alone would also click
		// any nested buttons inside the dropdown menu (e.g. counter +/- controls).
		const toggle = Array.from((this.$el as HTMLElement).children).find(c => c.matches('button[data-bs-toggle="dropdown"], button[data-toggle="dropdown"]')) as HTMLElement | undefined;
		toggle?.click();
	}

	render(h) {
		return (
			<div class={`dropdown${
				!isNullOrEmpty(this.rootCssClass) ? ` ${this.rootCssClass}` : ''
			}${this.displayInline == true ? ' dropdown-inline-disp' : ''
			}${this.menuOnTop == true ? ' dropdown-menuontop' : ''}`}
			>
				<button class={this.getCssClass()} disabled={this.disabled == true} type="button" data-toggle="dropdown" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" title={this.tooltip} aria-label={this.ariaLabel || undefined} data-bs-auto-close={this.autoClose}>
					{!isNullOrEmpty(this.icon)
					&& <i class={this.icon} aria-hidden="true"></i>}
					<span class={`dropdown-button-text${(this.textIsPlaceholder ? ' dropdown-button-text-placeholder' : '')}`}>
						{this.text}

						{this.subtitle
						&& <span class="subtitle">{this.subtitle}</span>}
					</span>
				</button>
				<div class={`dropdown-menu${this.menuOnRight == true ? ' dropdown-menu-right' : ''}`}>
					{this.$slots.default?.()}
				</div>
			</div>
		);
	}
}

const DropdownButton = toNative(DropdownButtonComponent);
export default DropdownButton;
