import React, { useCallback, useEffect, useRef, useState } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { TerminalComponent, type TerminalRef } from "../components/terminal";
import {
	TerminalSessionTabs,
	type TerminalSessionInfo,
} from "../components/terminal-session-tabs";
import { useMobileViewport } from "../hooks/use-mobile-viewport";
import { useAutoHide } from "../hooks/use-auto-hide";
import { useTerminalSessions } from "../hooks/use-terminal-sessions";
import type { TerminalSession } from "../api/terminal";

const SESSIONS_TO_INFO = (sessions: TerminalSession[]): TerminalSessionInfo[] =>
	sessions.map((s) => ({
		id: s.id,
		name: s.name,
		status: s.status as TerminalSessionInfo["status"],
	}));

export const TerminalPage: React.FC = () => {
	const { instanceId } = useParams<{
		instanceId: string;
	}>();
	const navigate = useNavigate();
	const isMobile = useMobileViewport();
	const [isFullscreen, setIsFullscreen] = useState(false);
	const terminalRefs = useRef<Record<string, React.RefObject<TerminalRef>>>({});
	const headerAutoHide = useAutoHide({ timeout: 3000, enabled: isMobile });

	const {
		sessions,
		activeSessionId,
		setActiveSessionId,
		createSession,
		closeSession,
		renameSession,
		resetSession,
		loading,
		error,
	} = useTerminalSessions(instanceId ?? "");

	// Auto-create default session if none exist after loading completes
	useEffect(() => {
		if (!loading && sessions.length === 0 && !error && instanceId) {
			void createSession("Session 1");
		}
	}, [loading, sessions.length, error, instanceId, createSession]);

	// Ensure refs map is kept in sync with sessions
	useEffect(() => {
		for (const session of sessions) {
			if (!terminalRefs.current[session.id]) {
				terminalRefs.current[session.id] = React.createRef<TerminalRef>();
			}
		}
		// Clean up refs for closed sessions
		const currentIds = new Set(sessions.map((s) => s.id));
		for (const id of Object.keys(terminalRefs.current)) {
			if (!currentIds.has(id)) {
				delete terminalRefs.current[id];
			}
		}
	}, [sessions]);

	// Fit and focus active terminal when switching tabs
	useEffect(() => {
		if (activeSessionId && terminalRefs.current[activeSessionId]) {
			const ref = terminalRefs.current[activeSessionId];
			// Small delay to allow display:block to apply
			const timer = setTimeout(() => {
				ref.current?.fit();
				ref.current?.focus();
			}, 50);
			return () => clearTimeout(timer);
		}
	}, [activeSessionId]);

	// Keyboard shortcuts
	useEffect(() => {
		const handleKeyDown = (e: KeyboardEvent) => {
			const isAltShift = e.altKey && e.shiftKey && !e.ctrlKey && !e.metaKey;
			if (!isAltShift) return;

			switch (e.key.toLowerCase()) {
				case "n":
					e.preventDefault();
					if (sessions.length < 5) {
						void createSession(`Session ${sessions.length + 1}`);
					}
					break;
				case "w":
					e.preventDefault();
					if (
						activeSessionId &&
						window.confirm("Close this terminal session?")
					) {
						void closeSession(activeSessionId);
					}
					break;
				case "arrowleft":
					e.preventDefault();
					if (activeSessionId) {
						const idx = sessions.findIndex((s) => s.id === activeSessionId);
						if (idx > 0) {
							setActiveSessionId(sessions[idx - 1].id);
						}
					}
					break;
				case "arrowright":
					e.preventDefault();
					if (activeSessionId) {
						const idx = sessions.findIndex((s) => s.id === activeSessionId);
						if (idx < sessions.length - 1) {
							setActiveSessionId(sessions[idx + 1].id);
						}
					}
					break;
				case "r":
					e.preventDefault();
					if (activeSessionId) {
						void resetSession(activeSessionId);
					}
					break;
				case "f":
					e.preventDefault();
					setIsFullscreen((prev) => !prev);
					break;
				default:
					break;
			}
		};

		window.addEventListener("keydown", handleKeyDown);
		return () => window.removeEventListener("keydown", handleKeyDown);
	}, [
		sessions,
		activeSessionId,
		createSession,
		closeSession,
		resetSession,
		setActiveSessionId,
	]);

	// Exit fullscreen on Escape
	useEffect(() => {
		if (!isFullscreen) return;
		const handleEscape = (e: KeyboardEvent) => {
			if (e.key === "Escape") {
				setIsFullscreen(false);
			}
		};
		window.addEventListener("keydown", handleEscape);
		return () => window.removeEventListener("keydown", handleEscape);
	}, [isFullscreen]);

	const handleSelect = useCallback(
		(sessionId: string) => {
			setActiveSessionId(sessionId);
		},
		[setActiveSessionId],
	);

	const handleClose = useCallback(
		async (sessionId: string) => {
			await closeSession(sessionId);
		},
		[closeSession],
	);

	const handleCreate = useCallback(() => {
		void createSession(`Session ${sessions.length + 1}`);
	}, [createSession, sessions.length]);

	const handleRename = useCallback(
		(sessionId: string, newName: string) => {
			void renameSession(sessionId, newName);
		},
		[renameSession],
	);

	if (!instanceId) {
		return (
			<section className="stack">
				<h1>Terminal</h1>
				<p className="muted">No instance ID provided.</p>
			</section>
		);
	}

	const sessionInfos = SESSIONS_TO_INFO(sessions);

	if (isMobile) {
		return (
			<section
				className={`terminal-page mobile ${isFullscreen ? "fullscreen" : ""}`}
			>
				<div
					className={`terminal-page-header mobile-header ${headerAutoHide.isVisible ? "visible" : "hidden"}`}
					onClick={() => headerAutoHide.show()}
				>
					<button
						className="secondary-button"
						onClick={() => navigate(-1)}
						type="button"
					>
						Back
					</button>
					<h1>Terminal</h1>
					<button
						className="secondary-button"
						onClick={() => setIsFullscreen((p) => !p)}
						type="button"
					>
						{isFullscreen ? "Exit" : "Fullscreen"}
					</button>
				</div>
				<div
					className={`mobile-tabs-container ${headerAutoHide.isVisible ? "visible" : "hidden"}`}
					onClick={() => headerAutoHide.show()}
				>
					<TerminalSessionTabs
						sessions={sessionInfos}
						activeSessionId={activeSessionId ?? ""}
						onSelect={handleSelect}
						onClose={handleClose}
						onCreate={handleCreate}
						onRename={handleRename}
						isMobile={true}
					/>
				</div>
				<div className="terminal-page-content">
					{error && <div className="terminal-error-banner">{error}</div>}
					{sessions
						.filter((session) => session.id === activeSessionId)
						.map((session) => (
							<div key={session.id} className="terminal-instance active">
								<TerminalComponent
									ref={terminalRefs.current[session.id]}
									instanceId={instanceId}
									sessionId={session.id}
									onClose={() => handleClose(session.id)}
									isMobile={true}
								/>
							</div>
						))}
					{sessions.length === 0 && !loading && (
						<div className="terminal-empty-state">
							<p>No terminal sessions. Press Alt+Shift+N to create one.</p>
						</div>
					)}
				</div>
			</section>
		);
	}

	return (
		<section className={`terminal-page ${isFullscreen ? "fullscreen" : ""}`}>
			{!isFullscreen && (
				<div className="terminal-page-header">
					<button
						className="secondary-button"
						onClick={() => navigate(-1)}
						type="button"
					>
						Back
					</button>
					<h1>Terminal</h1>
					<button
						className="secondary-button"
						onClick={() => setIsFullscreen((p) => !p)}
						type="button"
						title="Toggle fullscreen (Alt+Shift+F)"
					>
						{isFullscreen ? "Exit Fullscreen" : "Fullscreen"}
					</button>
				</div>
			)}
			<TerminalSessionTabs
				sessions={sessionInfos}
				activeSessionId={activeSessionId ?? ""}
				onSelect={handleSelect}
				onClose={handleClose}
				onCreate={handleCreate}
				onRename={handleRename}
				isMobile={false}
			/>
			<div className="terminal-page-content">
				{error && <div className="terminal-error-banner">{error}</div>}
				{sessions
					.filter((session) => session.id === activeSessionId)
					.map((session) => (
						<div key={session.id} className="terminal-instance active">
							<TerminalComponent
								ref={terminalRefs.current[session.id]}
								instanceId={instanceId}
								sessionId={session.id}
								onClose={() => handleClose(session.id)}
								isMobile={false}
							/>
						</div>
					))}
				{sessions.length === 0 && !loading && (
					<div className="terminal-empty-state">
						<p>No terminal sessions. Press Alt+Shift+N to create one.</p>
					</div>
				)}
			</div>
		</section>
	);
};
