/**
 * PortBar Component
 *
 * A single expandable port bar on one side of a node.
 * Contains the expand/collapse state, positioning logic,
 * compatibility checking, and edge creation initiation.
 *
 * Extracted from NodePorts.tsx in v1.4.0.
 *
 * @since 1.4.0
 */

'use client';

import React, { useState } from 'react';
import { useSetAtom } from 'jotai';
import type { PortDefinition, PortSide } from '../core/port-types';
import { calculatePortPosition, arePortsCompatible } from '../core/port-types';
import { edgeCreationAtom } from '../core/graph-store';
import type { EdgeCreationState } from '../core/types';
import { useCanvasStyle } from '../providers/CanvasStyleProvider';
import { PortHandle, PORT_ROW_HEIGHT } from './PortHandle';

// --- Types ---

export interface PortBarProps {
	/** Node ID */
	nodeId: string;
	/** Which side this bar is on */
	side: PortSide;
	/** Ports on this side */
	ports: PortDefinition[];
	/** Node dimensions for positioning */
	nodeWidth: number;
	nodeHeight: number;
	/** Whether to force expanded state */
	forceExpanded?: boolean;
	/** Callback when port is clicked */
	onPortClick?: (portId: string, port: PortDefinition) => void;
	/** Callback when port is hovered */
	onPortHover?: (portId: string | null, port: PortDefinition | null) => void;
	/** Whether we're in drag mode (showing as drop target) */
	isDragTarget?: boolean;
	/** Source port for compatibility checking */
	dragSourcePort?: PortDefinition | null;
}

// --- Constants ---

const COLLAPSED_WIDTH = 8;
const EXPANDED_WIDTH = 80;
const TRANSITION_DURATION = '150ms';

// --- Component ---

export function PortBar({
	nodeId,
	side,
	ports,
	nodeWidth,
	nodeHeight,
	forceExpanded = false,
	onPortClick,
	onPortHover,
	isDragTarget = false,
	dragSourcePort,
}: PortBarProps) {
	const [isExpanded, setIsExpanded] = useState(false);
	const [hoveredPortId, setHoveredPortId] = useState<string | null>(null);
	const canvasStyles = useCanvasStyle();
	const setEdgeCreation = useSetAtom(edgeCreationAtom);

	const showExpanded = isExpanded || forceExpanded || isDragTarget;

	// Calculate bar position based on side
	const barStyle = ((): React.CSSProperties => {
		const base: React.CSSProperties = {
			position: 'absolute',
			display: 'flex',
			flexDirection: side === 'top' || side === 'bottom' ? 'row' : 'column',
			alignItems: 'stretch',
			transition: `all ${TRANSITION_DURATION} ease-out`,
			backgroundColor: canvasStyles.nodes.defaultBackground,
			borderRadius: '4px',
			overflow: 'hidden',
			zIndex: 10,
		};

		const barSize = showExpanded ? EXPANDED_WIDTH : COLLAPSED_WIDTH;
		const barLength = side === 'left' || side === 'right'
			? Math.max(ports.length * PORT_ROW_HEIGHT, nodeHeight * 0.6)
			: Math.max(ports.length * PORT_ROW_HEIGHT, nodeWidth * 0.6);

		switch (side) {
			case 'left':
				return { ...base, left: -barSize, top: '50%', transform: 'translateY(-50%)', width: `${barSize}px`, height: `${barLength}px`, borderRight: `1px solid ${canvasStyles.nodes.defaultBorderColor}`, borderTopRightRadius: 0, borderBottomRightRadius: 0 };
			case 'right':
				return { ...base, right: -barSize, top: '50%', transform: 'translateY(-50%)', width: `${barSize}px`, height: `${barLength}px`, borderLeft: `1px solid ${canvasStyles.nodes.defaultBorderColor}`, borderTopLeftRadius: 0, borderBottomLeftRadius: 0 };
			case 'top':
				return { ...base, top: -barSize, left: '50%', transform: 'translateX(-50%)', height: `${barSize}px`, width: `${barLength}px`, borderBottom: `1px solid ${canvasStyles.nodes.defaultBorderColor}`, borderBottomLeftRadius: 0, borderBottomRightRadius: 0 };
			case 'bottom':
				return { ...base, bottom: -barSize, left: '50%', transform: 'translateX(-50%)', height: `${barSize}px`, width: `${barLength}px`, borderTop: `1px solid ${canvasStyles.nodes.defaultBorderColor}`, borderTopLeftRadius: 0, borderTopRightRadius: 0 };
		}
	})();

	const isPortCompatible = (port: PortDefinition): boolean => {
		if (!isDragTarget || !dragSourcePort) return true;
		return arePortsCompatible(dragSourcePort, port);
	};

	const handleMouseEnter = () => { if (!isDragTarget) setIsExpanded(true); };
	const handleMouseLeave = () => { if (!forceExpanded) { setIsExpanded(false); setHoveredPortId(null); onPortHover?.(null, null); } };

	const handlePortPointerDown = (portId: string, port: PortDefinition, e: React.PointerEvent) => {
		if (e.button !== 0) return;
		e.stopPropagation();
		e.preventDefault();
		const portPos = calculatePortPosition(0, 0, nodeWidth, nodeHeight, port);
		setEdgeCreation({
			isCreating: true,
			sourceNodeId: nodeId,
			sourceNodePosition: { x: portPos.x, y: portPos.y },
			targetPosition: { x: portPos.x, y: portPos.y },
			hoveredTargetNodeId: null,
			sourceHandle: `widget:${nodeId}:${port.type === 'input' ? 'input' : 'output'}:${port.id}`,
			targetHandle: null,
			sourcePort: portId,
			targetPort: null,
			snappedTargetPosition: null,
		} satisfies EdgeCreationState);
	};

	return (
		<div style={barStyle} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave} data-port-bar={side} data-node-id={nodeId}>
			{ports.map((port) => (
				<PortHandle
					key={port.id}
					port={port}
					side={side}
					isHovered={hoveredPortId === port.id}
					showExpanded={showExpanded}
					isCompatible={isPortCompatible(port)}
					isDragTarget={isDragTarget}
					onClick={(id, p) => onPortClick?.(id, p)}
					onPointerDown={handlePortPointerDown}
					onMouseEnter={(id, p) => { setHoveredPortId(id); onPortHover?.(id, p); }}
					onMouseLeave={() => { setHoveredPortId(null); onPortHover?.(null, null); }}
				/>
			))}
		</div>
	);
}
