'use client';

import React, { useEffect, useRef, useState } from 'react';
import { useAtom, useAtomValue, useSetAtom } from 'jotai';
import {
	commandLineVisibleAtom,
	commandLineStateAtom,
	closeCommandLineAtom,
	commandProgressAtom,
	selectedSuggestionIndexAtom,
	inputModeAtom,
	selectCommandAtom,
} from '../../commands/store';
import { commandRegistry } from '../../commands/registry';
import type { CommandDefinition } from '../../commands/types';
import { CommandSearch } from './CommandSearch';
import { CommandInputCollector } from './CommandInputCollector';

const MIN_HEIGHT = 60;
const MAX_HEIGHT = 400;
const DEFAULT_HEIGHT = 200;

/**
 * Props for the CommandLine component
 */
export interface CommandLineProps {
	/**
	 * Optional callback to check if any modal is currently open.
	 * When a modal is open, the Escape key will not be captured by the command line.
	 * This allows modals to close themselves instead.
	 */
	isModalOpen?: () => boolean;
}

/**
 * CommandLine
 *
 * The main command line UI bar that appears at the bottom of the screen.
 * Hidden by default, shown when user presses `/` or Cmd+K.
 *
 * States:
 * - idle: Shows search input
 * - searching: Shows autocomplete suggestions
 * - collecting: Shows sequential input prompts
 * - executing: Shows loading spinner
 * - error: Shows error message
 */
export function CommandLine({ isModalOpen }: CommandLineProps) {
	const visible = useAtomValue(commandLineVisibleAtom);
	const [state, setState] = useAtom(commandLineStateAtom);
	const closeCommandLine = useSetAtom(closeCommandLineAtom);
	const progress = useAtomValue(commandProgressAtom);
	const selectedIndex = useAtomValue(selectedSuggestionIndexAtom);
	const setInputMode = useSetAtom(inputModeAtom);
	const containerRef = useRef<HTMLDivElement>(null);
	const [height, setHeight] = useState(DEFAULT_HEIGHT);
	const [isDragging, setIsDragging] = useState(false);
	const dragStartY = useRef(0);
	const dragStartHeight = useRef(DEFAULT_HEIGHT);

	// Handle escape key to cancel current command (not close)
	// Don't capture escape when modals are open - let them handle it
	useEffect(() => {
		if (!visible) return;

		const handleKeyDown = (e: KeyboardEvent) => {
			if (e.key === 'Escape') {
				// Don't capture escape if any modal is open - let it close the modal
				if (isModalOpen?.()) {
					return;
				}
				e.preventDefault();
				e.stopPropagation();
				// If collecting/executing, cancel back to search mode
				if (state.phase === 'collecting' || state.phase === 'executing' || state.phase === 'error') {
					setState({ phase: 'searching', query: '', suggestions: commandRegistry.all() });
					setInputMode({ type: 'normal' });
				}
				// If in search mode, don't close - user can use / to toggle
			}
		};

		window.addEventListener('keydown', handleKeyDown, { capture: true });
		return () => window.removeEventListener('keydown', handleKeyDown, { capture: true });
	}, [visible, state.phase, setState, setInputMode, isModalOpen]);

	// Handle drag resize
	const handleDragStart = (e: React.MouseEvent) => {
		e.preventDefault();
		setIsDragging(true);
		dragStartY.current = e.clientY;
		dragStartHeight.current = height;
	};

	useEffect(() => {
		if (!isDragging) return;

		const handleMouseMove = (e: MouseEvent) => {
			const deltaY = dragStartY.current - e.clientY;
			const newHeight = Math.min(MAX_HEIGHT, Math.max(MIN_HEIGHT, dragStartHeight.current + deltaY));
			setHeight(newHeight);
		};

		const handleMouseUp = () => {
			setIsDragging(false);
		};

		window.addEventListener('mousemove', handleMouseMove);
		window.addEventListener('mouseup', handleMouseUp);
		return () => {
			window.removeEventListener('mousemove', handleMouseMove);
			window.removeEventListener('mouseup', handleMouseUp);
		};
	}, [isDragging]);

	if (!visible) {
		return null;
	}

	// Calculate max height for suggestions (50% of viewport)
	const maxSuggestionsHeight = typeof window !== 'undefined' ? Math.min(400, window.innerHeight * 0.5) : 300;

	return (
		<div
			ref={containerRef}
			className="fixed right-0 bottom-0 left-0 z-50 flex flex-col shadow-2xl"
			style={{ height: `${height}px`, maxHeight: '50vh', backgroundColor: 'var(--cmd-bg)' }}
		>
			{/* Draggable resize handle */}
			<div
				onMouseDown={handleDragStart}
				className="flex h-3 w-full shrink-0 cursor-ns-resize items-center justify-center border-t transition-colors"
				style={{
					borderColor: 'var(--cmd-border)',
					backgroundColor: isDragging ? 'var(--cmd-resize-hover)' : 'var(--cmd-resize-bg)',
				}}
				onMouseEnter={(e) => !isDragging && (e.currentTarget.style.backgroundColor = 'var(--cmd-resize-hover)')}
				onMouseLeave={(e) => !isDragging && (e.currentTarget.style.backgroundColor = 'var(--cmd-resize-bg)')}
			>
				<div className="h-1 w-12 rounded-full opacity-50" style={{ backgroundColor: 'var(--hud-icon)' }} />
			</div>

			{/* Main content area */}
			<div className="flex min-h-0 flex-1 flex-col overflow-hidden">
				<div className="flex items-center px-4 py-3 font-mono text-sm">
					{/* Command prefix */}
					<span className="mr-2 text-lg font-bold select-none" style={{ color: 'var(--badge-info-text)' }}>
						&gt;
					</span>

					{/* Phase: Idle or Searching */}
					{(state.phase === 'idle' || state.phase === 'searching') && <CommandSearch />}

					{/* Phase: Collecting inputs */}
					{state.phase === 'collecting' && <CommandInputCollector />}

					{/* Phase: Executing */}
					{state.phase === 'executing' && (
						<div className="flex items-center gap-2" style={{ color: 'var(--badge-warning-text)' }}>
							<svg className="h-5 w-5 animate-spin" viewBox="0 0 24 24">
								<circle
									className="opacity-25"
									cx="12"
									cy="12"
									r="10"
									stroke="currentColor"
									strokeWidth="4"
									fill="none"
								/>
								<path
									className="opacity-75"
									fill="currentColor"
									d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
								/>
							</svg>
							<span className="text-base">Executing {state.command.name}...</span>
						</div>
					)}

					{/* Phase: Error */}
					{state.phase === 'error' && (
						<div className="flex items-center gap-2" style={{ color: 'var(--badge-error-text)' }}>
							<svg
								className="h-5 w-5"
								viewBox="0 0 24 24"
								fill="none"
								stroke="currentColor"
								strokeWidth="2"
							>
								<circle cx="12" cy="12" r="10" />
								<line x1="15" y1="9" x2="9" y2="15" />
								<line x1="9" y1="9" x2="15" y2="15" />
							</svg>
							<span className="text-base">{state.message}</span>
							<button
								onClick={() => setState({ phase: 'idle' })}
								className="ml-2 rounded px-2 py-1 text-sm transition-colors"
								style={{
									backgroundColor: 'var(--list-item-bg-hover)',
									color: 'var(--hud-text-secondary)',
								}}
								onMouseEnter={(e) => (e.currentTarget.style.color = 'var(--hud-text)')}
								onMouseLeave={(e) => (e.currentTarget.style.color = 'var(--hud-text-secondary)')}
							>
								Try again
							</button>
						</div>
					)}

					{/* Spacer */}
					<div className="flex-1" />

					{/* Progress indicator */}
					{progress && (
						<span
							className="mr-4 rounded px-2 py-1 text-sm"
							style={{
								backgroundColor: 'var(--list-item-bg-hover)',
								color: 'var(--hud-text-secondary)',
							}}
						>
							Step {progress.current}/{progress.total}
						</span>
					)}

					{/* Close hint */}
					<span
						className="text-sm select-none"
						style={{ color: 'var(--hud-text-secondary)', opacity: 0.6 }}
					>
						/ to close • ESC to cancel
					</span>
				</div>

				{/* Suggestions dropdown (when searching) */}
				{state.phase === 'searching' && state.suggestions.length > 0 && (
					<div
						className="min-h-0 shrink overflow-y-auto border-t"
						style={{ maxHeight: '40vh', borderColor: 'var(--cmd-border)' }}
					>
						{state.suggestions.map((cmd, index) => (
							<CommandSuggestionItem
								key={cmd.name}
								command={cmd}
								isHighlighted={index === selectedIndex}
							/>
						))}
					</div>
				)}
			</div>
		</div>
	);
}

/**
 * Individual command suggestion item
 */
function CommandSuggestionItem({
	command,
	isHighlighted,
}: {
	command: CommandDefinition;
	isHighlighted: boolean;
}) {
	const selectCommand = useSetAtom(selectCommandAtom);

	return (
		<button
			onClick={() => selectCommand(command)}
			className="flex w-full items-center gap-3 px-4 py-2 text-left transition-colors"
			style={{
				backgroundColor: isHighlighted ? 'var(--list-item-bg-hover)' : 'transparent',
			}}
			onMouseEnter={(e) =>
				!isHighlighted && (e.currentTarget.style.backgroundColor = 'var(--list-item-bg-hover)')
			}
			onMouseLeave={(e) => !isHighlighted && (e.currentTarget.style.backgroundColor = 'transparent')}
		>
			<span className="font-mono" style={{ color: 'var(--hud-text)' }}>
				{command.name}
			</span>
			{command.aliases && command.aliases.length > 0 && (
				<span className="text-xs" style={{ color: 'var(--hud-text-secondary)', opacity: 0.5 }}>
					({command.aliases.join(', ')})
				</span>
			)}
			<span className="text-sm" style={{ color: 'var(--hud-text-secondary)' }}>
				{command.description}
			</span>
		</button>
	);
}

export default CommandLine;
