/**
 * Edge Label Editor
 *
 * Renders an HTML input overlay positioned at the edge label's world coordinates.
 * Activated by double-clicking an edge label. Commits on blur/Enter, cancels on Escape.
 */

import React, { useRef, useEffect } from 'react';
import { useAtomValue, useSetAtom } from 'jotai';
import { edgeFamilyAtom } from '../core/graph-derived';
import { editingEdgeLabelAtom, updateEdgeLabelAtom } from '../core/graph-mutations';
import { panAtom, zoomAtom } from '../core/viewport-store';
import { getEdgePathCalculator } from '../utils/edge-path-calculators';
import { useCanvasStyle } from '../providers/CanvasStyleProvider';

export interface EdgeLabelEditorProps {
	/** Additional CSS class name for the input */
	className?: string;
}

export function EdgeLabelEditor({ className }: EdgeLabelEditorProps) {
	const editingEdgeKey = useAtomValue(editingEdgeLabelAtom);

	if (!editingEdgeKey) return null;

	return <EdgeLabelInput edgeKey={editingEdgeKey} className={className} />;
}

function EdgeLabelInput({ edgeKey, className }: { edgeKey: string; className?: string }) {
	const edgeData = useAtomValue(edgeFamilyAtom(edgeKey));
	const setEditingEdge = useSetAtom(editingEdgeLabelAtom);
	const updateLabel = useSetAtom(updateEdgeLabelAtom);
	const pan = useAtomValue(panAtom);
	const zoom = useAtomValue(zoomAtom);
	const styles = useCanvasStyle();
	const inputRef = useRef<HTMLInputElement>(null);

	useEffect(() => {
		// Auto-focus and select text on mount
		if (inputRef.current) {
			inputRef.current.focus();
			inputRef.current.select();
		}
	}, []);

	if (!edgeData) {
		setEditingEdge(null);
		return null;
	}

	// Compute label position using the same path calculator as EdgeRenderer
	const { sourcePosition, targetPosition, sourceEndpoint, targetEndpoint } = edgeData;
	const x1 = sourceEndpoint?.x ?? (sourcePosition.x + edgeData.sourceNodeWidth / 2);
	const y1 = sourceEndpoint?.y ?? (sourcePosition.y + edgeData.sourceNodeHeight / 2);
	const x2 = targetEndpoint?.x ?? (targetPosition.x + edgeData.targetNodeWidth / 2);
	const y2 = targetEndpoint?.y ?? (targetPosition.y + edgeData.targetNodeHeight / 2);

	const pathCalculator = getEdgePathCalculator(styles.edges.pathType || 'bezier');
	const { labelX, labelY } = pathCalculator({
		x1, y1, x2, y2,
		sourceWidth: edgeData.sourceNodeWidth,
		sourceHeight: edgeData.sourceNodeHeight,
		targetWidth: edgeData.targetNodeWidth,
		targetHeight: edgeData.targetNodeHeight,
	});

	// Transform world coords to screen coords
	const screenX = labelX * zoom + pan.x;
	const screenY = labelY * zoom + pan.y;

	const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {
		updateLabel({ edgeKey, label: e.target.value });
		setEditingEdge(null);
	};

	const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
		if (e.key === 'Enter') {
			e.currentTarget.blur();
		} else if (e.key === 'Escape') {
			// Cancel without saving
			setEditingEdge(null);
		}
	};

	return (
		<input
			ref={inputRef}
			data-no-drag="true"
			className={className}
			defaultValue={edgeData.label || ''}
			onBlur={handleBlur}
			onKeyDown={handleKeyDown}
			style={{
				position: 'absolute',
				left: screenX,
				top: screenY,
				transform: 'translate(-50%, -50%)',
				zIndex: 10000,
				fontSize: '10px',
				padding: '2px 6px',
				border: '1px solid #3b82f6',
				borderRadius: '3px',
				outline: 'none',
				background: 'white',
				textAlign: 'center',
				minWidth: '60px',
			}}
		/>
	);
}
