/**
 * Drag-to-resize Svelte action. Attaches pointerdown to the host element
 * (a thin handle on the inner edge of a sidebar) and writes the new width
 * back via the supplied setter. The pointer is captured so the drag keeps
 * tracking when the cursor leaves the handle.
 *
 *   edge: 'right' — handle on the right edge of the panel; drag right widens
 *   edge: 'left'  — handle on the left  edge of the panel; drag left  widens
 *
 * Usage:
 *   <div use:resizable={{ edge: 'right', getWidth: () => view.leftSidebarWidth, setWidth: setLeftSidebarWidth }} />
 */
export interface ResizableParams {
	edge: 'right' | 'left';
	getWidth: () => number;
	setWidth: (px: number) => void;
}

export function resizable(node: HTMLElement, initial: ResizableParams) {
	let params = initial;
	let pointerId = -1;
	let startX = 0;
	let startWidth = 0;

	function onDown(e: PointerEvent) {
		if (e.button !== 0) return;
		pointerId = e.pointerId;
		startX = e.clientX;
		startWidth = params.getWidth();
		node.setPointerCapture(pointerId);
		document.body.style.cursor = 'col-resize';
		document.body.style.userSelect = 'none';
		node.addEventListener('pointermove', onMove);
		node.addEventListener('pointerup', onUp);
		node.addEventListener('pointercancel', onUp);
	}

	function onMove(e: PointerEvent) {
		if (e.pointerId !== pointerId) return;
		const dx = e.clientX - startX;
		const delta = params.edge === 'right' ? dx : -dx;
		params.setWidth(startWidth + delta);
	}

	function onUp(e: PointerEvent) {
		if (pointerId === -1) return;
		try {
			node.releasePointerCapture(pointerId);
		} catch {
			// Pointer may already be released; ignore.
		}
		pointerId = -1;
		document.body.style.cursor = '';
		document.body.style.userSelect = '';
		node.removeEventListener('pointermove', onMove);
		node.removeEventListener('pointerup', onUp);
		node.removeEventListener('pointercancel', onUp);
	}

	function onDoubleClick() {
		// Reset to the current default-ish midpoint. Callers can override by
		// providing their own dblclick handler; we just stop pointer events
		// from leaking up so the page underneath doesn't react.
	}

	node.addEventListener('pointerdown', onDown);
	node.addEventListener('dblclick', onDoubleClick);

	return {
		update(next: ResizableParams) {
			params = next;
		},
		destroy() {
			node.removeEventListener('pointerdown', onDown);
			node.removeEventListener('dblclick', onDoubleClick);
		}
	};
}
