import {createRandomID} from '@/helpers/randomId'
import {computePosition, flip, shift, offset} from '@floating-ui/dom'
import {nextTick} from 'vue'
import {eventToShortcutString} from '@/helpers/shortcut'

export default function inputPrompt(pos: ClientRect, oldValue: string = ''): Promise<string> {
	return new Promise((resolve) => {
		const id = 'link-input-' + createRandomID()

		// Create popup element
		const popupElement = document.createElement('div')
		popupElement.style.position = 'fixed'
		popupElement.style.top = '0'
		popupElement.style.left = '0'
		popupElement.style.zIndex = '4700'
		popupElement.style.background = 'var(--white)'
		popupElement.style.border = '1px solid var(--grey-300)'
		popupElement.style.borderRadius = '4px'
		popupElement.style.padding = '8px'
		popupElement.style.boxShadow = 'var(--shadow-md)'
		const wrapperDiv = document.createElement('div')
		const inputElement = document.createElement('input')
		inputElement.className = 'input'
		inputElement.placeholder = 'URL'
		inputElement.id = id
		inputElement.value = oldValue
		wrapperDiv.appendChild(inputElement)
		popupElement.appendChild(wrapperDiv)
		document.body.appendChild(popupElement)

		// Create a local mutable copy of the position for scroll tracking
		let currentRect = new DOMRect(pos.left, pos.top, pos.width, pos.height)

		// Virtual reference for positioning
		const virtualReference = {
			getBoundingClientRect: () => currentRect,
		}

		// Function to update popup position
		const updatePosition = () => {
			computePosition(virtualReference, popupElement, {
				placement: 'top-start',
				strategy: 'fixed',
				middleware: [
					offset(8),
					flip(),
					shift({ padding: 8 }),
				],
			}).then(({ x, y }) => {
				popupElement.style.left = `${x}px`
				popupElement.style.top = `${y}px`
			})
		}

		// Position the popup initially
		updatePosition()

		// Track scroll position
		let lastScrollY = window.scrollY
		let lastScrollX = window.scrollX

		// Update position on scroll
		const handleScroll = () => {
			const deltaY = window.scrollY - lastScrollY
			const deltaX = window.scrollX - lastScrollX

			// Update the local mutable rect to account for scroll
			currentRect = new DOMRect(
				currentRect.x - deltaX,
				currentRect.y - deltaY,
				currentRect.width,
				currentRect.height,
			)

			lastScrollY = window.scrollY
			lastScrollX = window.scrollX

			updatePosition()
		}

		window.addEventListener('scroll', handleScroll, true)

		nextTick(() => document.getElementById(id)?.focus())

		const cleanup = () => {
			window.removeEventListener('scroll', handleScroll, true)
			if (document.body.contains(popupElement)) {
				document.body.removeChild(popupElement)
			}
		}

		document.getElementById(id)?.addEventListener('keydown', event => {
			const shortcutString = eventToShortcutString(event)
			if (shortcutString !== 'Enter') {
				return
			}

			if (event.isComposing) {
				return
			}

			const url = (event.target as HTMLInputElement).value

			resolve(url)
			cleanup()
		})

		// Close on click outside
		const handleClickOutside = (event: MouseEvent) => {
			if (!popupElement.contains(event.target as Node)) {
				resolve('')
				cleanup()
				document.removeEventListener('click', handleClickOutside)
			}
		}

		// Add slight delay to prevent immediate closing
		setTimeout(() => {
			document.addEventListener('click', handleClickOutside)
		}, 100)

	})
}
