import type { Directive, DirectiveBinding } from 'vue'

const ripple: Directive<HTMLElement, boolean> = {
	mounted(el: HTMLElement, binding: DirectiveBinding<boolean>) {
		const clickHandler = (e: MouseEvent) => {
			const rect = el.getBoundingClientRect()
			const size = Math.max(rect.width, rect.height)
			const ripple = document.createElement('span')

			ripple.className = 'ripple'
			Object.assign(ripple.style, {
				width: `${size}px`,
				height: `${size}px`,
				left: `${e.clientX - rect.left - size / 2}px`,
				top: `${e.clientY - rect.top - size / 2}px`,
				position: 'absolute',
				borderRadius: '50%',
				transform: 'scale(0)',
				background: 'rgba(0, 0, 0, 0.3)',
				pointerEvents: 'none',
				animation: 'rippleEffect 0.6s ease-out',
			})

			el.appendChild(ripple)
			setTimeout(() => { ripple.remove() }, 600)
		};

		(el as any).__rippleClickHandler = clickHandler

		if (binding.value !== false) {
			if (getComputedStyle(el).position === 'static') {
				el.style.position = 'relative'
			}
			el.style.overflow = 'hidden'
			el.addEventListener('mousedown', clickHandler)
		}
	},
	updated(el: HTMLElement, binding: DirectiveBinding<boolean>) {
		const clickHandler = (el as any).__rippleClickHandler
		if (binding.value === false) {
			el.removeEventListener('mousedown', clickHandler)
		} else {
			if (getComputedStyle(el).position === 'static') {
				el.style.position = 'relative'
			}
			el.style.overflow = 'hidden'
			el.addEventListener('mousedown', clickHandler)
		}
	},
	unmounted(el: HTMLElement) {
		const clickHandler = (el as any).__rippleClickHandler
		if (clickHandler) {
			el.removeEventListener('mousedown', clickHandler)
			delete (el as any).__rippleClickHandler
		}
	},
}

export default ripple
