import { AfterViewInit, Directive, ElementRef, inject, input, OnChanges } from '@angular/core'
import { UntilDestroy } from '@ngneat/until-destroy'

const LOADING_ELEMENT_ID = 'kadi-btn-loading'

@UntilDestroy({ checkProperties: true })
@Directive({
	selector: 'button[kadiLoadingButton]',
})
export class LoadingButtonDirective implements OnChanges, AfterViewInit {
	readonly kadiLoadingButton = input(false)

	private _elementRef = inject<ElementRef<HTMLButtonElement>>(ElementRef)

	ngOnChanges(): void {
		if (this.kadiLoadingButton()) this.showLoading()
		else this.hideLoading()
	}

	ngAfterViewInit(): void {
		this.createLoadingElement()
	}

	private createLoadingElement(): void {
		const loadingElement = document.createElement('i')
		loadingElement.classList.add(
			'absolute',
			'left-8',
			'size-5',
			'rounded-full',
			'border-3',
			'border-solid',
			'border-t-transparent',
			'border-current',
			'animate-spin',
		)
		loadingElement.style.display = 'none'
		loadingElement.id = LOADING_ELEMENT_ID

		this._elementRef.nativeElement.style.position = 'relative'
		this._elementRef.nativeElement.insertBefore(loadingElement, this._elementRef.nativeElement.firstChild)
	}

	private showLoading(): void {
		const element = this.getLoadingElement()
		if (!element) return

		element.style.display = 'inline-block'
	}

	private hideLoading(): void {
		const element = this.getLoadingElement()
		if (!element) return

		element.style.display = 'none'
	}

	private getLoadingElement(): HTMLElement | null {
		return this._elementRef.nativeElement.children.namedItem(LOADING_ELEMENT_ID) as HTMLElement
	}
}
