import { useState, useRef, useEffect } from "react";
import type { Session } from "../../../api/sessions";
import { Icon } from "../../icon";
import { useMobileViewport } from "../../../hooks/use-mobile-viewport";
import { MobileActionSheet } from "../mobile/mobile-action-sheet";
import { LoadingOverlay } from "../../loading-overlay";
import type { IconName } from "../../icon";

export interface SessionCardProps {
	session: Session;
	onOpen?: (session: Session) => void;
	onStart?: (session: Session) => void;
	onStop?: (session: Session) => void;
	onDelete?: (session: Session) => void;
	onRecreateTunnel?: (session: Session) => void;
	onRename?: (session: Session, newName: string) => void;
	isBusy?: boolean;
	busyLabel?: string;
	tunnelHealth?: {
		healthy: boolean;
		container_status: string;
		container_health: string | null;
		tunnel_status: string;
		tunnel_status_code: number | null;
		probe_status: string;
		last_probe_output: string | null;
		error: string | null;
	} | null;
}

const statusConfig: Record<string, { color: string; label: string }> = {
	running: { color: "running", label: "Running" },
	building: { color: "pending", label: "Building" },
	starting: { color: "starting", label: "Starting" },
	probing: { color: "probing", label: "Probing" },
	pending: { color: "pending", label: "Pending" },
	stopped: { color: "stopped", label: "Stopped" },
	error: { color: "error", label: "Error" },
	unhealthy: { color: "unhealthy", label: "Unhealthy" },
};

export function SessionCard({
	session,
	onOpen,
	onStart,
	onStop,
	onDelete,
	onRecreateTunnel,
	onRename,
	isBusy = false,
	busyLabel = "Working...",
	tunnelHealth = null,
}: SessionCardProps) {
	const [showActionSheet, setShowActionSheet] = useState(false);
	const [isEditingName, setIsEditingName] = useState(false);
	const [editName, setEditName] = useState(session.display_name);
	const [optionsOpen, setOptionsOpen] = useState(false);
	const optionsRef = useRef<HTMLDivElement>(null);
	const isMobile = useMobileViewport();

	const status = statusConfig[session.status] || {
		color: "gray",
		label: session.status,
	};
	const isTerminalOnly =
		session.tool_type_interfaces?.includes("terminal") &&
		!session.tool_type_interfaces?.includes("web");
	const hasTunnelError =
		!isTerminalOnly && tunnelHealth?.tunnel_status === "unreachable";
	const hasAppError =
		!isTerminalOnly && tunnelHealth?.tunnel_status === "error_response";

	const isActive = [
		"running",
		"building",
		"starting",
		"probing",
		"pending",
		"unhealthy",
	].includes(session.status);

	useEffect(() => {
		if (!optionsOpen) return;
		const handleClick = (e: MouseEvent) => {
			if (
				optionsRef.current &&
				!optionsRef.current.contains(e.target as Node)
			) {
				setOptionsOpen(false);
			}
		};
		const handleKey = (e: KeyboardEvent) => {
			if (e.key === "Escape") setOptionsOpen(false);
		};
		document.addEventListener("mousedown", handleClick);
		document.addEventListener("keydown", handleKey);
		return () => {
			document.removeEventListener("mousedown", handleClick);
			document.removeEventListener("keydown", handleKey);
		};
	}, [optionsOpen]);

	const handleDeleteClick = () => {
		setOptionsOpen(false);
		if (window.confirm("Are you sure you want to delete this session?")) {
			onDelete?.(session);
		}
	};

	return (
		<article className="card session-card">
			<LoadingOverlay visible={isBusy} label={busyLabel} />
			<div className="session-card-content">
				<div className="session-card-header">
					<div className="session-card-title">
						{isEditingName ? (
							<div className="session-card-rename">
								<input
									type="text"
									value={editName}
									onChange={(e) => setEditName(e.target.value)}
									onKeyDown={(e) => {
										if (e.key === "Enter") {
											onRename?.(session, editName);
											setIsEditingName(false);
										}
										if (e.key === "Escape") {
											setEditName(session.display_name);
											setIsEditingName(false);
										}
									}}
									onBlur={() => {
										if (editName.trim() && editName !== session.display_name) {
											onRename?.(session, editName);
										}
										setIsEditingName(false);
									}}
									autoFocus
								/>
							</div>
						) : (
							<h4
								onClick={() => {
									setEditName(session.display_name);
									setIsEditingName(true);
								}}
								title="Click to rename"
								style={{ cursor: "pointer" }}
							>
								{session.display_name}
							</h4>
						)}
						<div className="session-card-status-badges">
							<span className={`status-badge ${status.color}`}>
								{status.label}
							</span>
							{hasTunnelError && (
								<span className="status-badge error">Tunnel Error</span>
							)}
							{hasAppError && (
								<span className="status-badge warning">
									App Error {tunnelHealth?.tunnel_status_code}
								</span>
							)}
						</div>
					</div>
					<p className="muted session-card-meta session-card-context">
						<strong>{session.project_name}</strong>
						{session.workspace_name && (
							<>
								{" "}
								/ <span>{session.workspace_name}</span>
							</>
						)}
						{!session.workspace_name && session.repository_name && (
							<>
								{" "}
								/ <span>{session.repository_name}</span>
							</>
						)}{" "}
						· {session.tool_type_name}
					</p>
					{session.url && (
						<p className="session-card-url">
							<button
								type="button"
								className="link-button"
								onClick={() => onOpen?.(session)}
							>
								{session.url}
							</button>
						</p>
					)}
					{session.created_at && (
						<p className="muted session-card-meta">
							Created: {new Date(session.created_at).toLocaleString()}
						</p>
					)}
				</div>
			</div>

			{isMobile ? (
				<div className="session-card-actions mobile">
					{isActive && (
						<>
							<button
								className="secondary-button mobile-primary"
								onClick={() => onOpen?.(session)}
								type="button"
								disabled={isBusy}
							>
								<Icon name="external" size="sm" />
								Open
							</button>
							<button
								className="ghost-button mobile-more"
								onClick={() => setShowActionSheet(true)}
								type="button"
								disabled={isBusy}
							>
								<Icon name="menu" size="sm" />
							</button>
						</>
					)}
					{!isActive && onStart && (
						<>
							<button
								className="secondary-button mobile-primary"
								onClick={() => onStart(session)}
								type="button"
								disabled={isBusy}
							>
								<Icon name="play" size="sm" />
								Start
							</button>
							<button
								className="ghost-button mobile-more"
								onClick={() => setShowActionSheet(true)}
								type="button"
								disabled={isBusy}
							>
								<Icon name="menu" size="sm" />
							</button>
						</>
					)}
				</div>
			) : (
				<div className="session-card-actions">
					{isActive && onOpen && (
						<button
							className="secondary-button small"
							onClick={() => onOpen(session)}
							type="button"
							disabled={isBusy}
						>
							<Icon name="external" size="sm" />
							<span className="action-label">Open</span>
						</button>
					)}
					{!isActive && onStart && (
						<button
							className="secondary-button small"
							onClick={() => onStart(session)}
							type="button"
							disabled={isBusy}
						>
							<Icon name="play" size="sm" />
							<span className="action-label">Start</span>
						</button>
					)}

					<div className="session-options" ref={optionsRef}>
						<button
							className="ghost-button small"
							onClick={() => setOptionsOpen((prev) => !prev)}
							type="button"
							disabled={isBusy}
							aria-haspopup="menu"
							aria-expanded={optionsOpen}
						>
							<Icon name="more" size="sm" />
							<span className="action-label">Options</span>
						</button>

						{optionsOpen && (
							<div className="session-options-dropdown" role="menu">
								{isActive && onStop && (
									<button
										className="session-option-item"
										onClick={() => {
											setOptionsOpen(false);
											onStop(session);
										}}
										type="button"
										role="menuitem"
									>
										<Icon name="stop" size="sm" />
										Stop
									</button>
								)}
								{!isActive && onStart && (
									<button
										className="session-option-item"
										onClick={() => {
											setOptionsOpen(false);
											onStart(session);
										}}
										type="button"
										role="menuitem"
									>
										<Icon name="play" size="sm" />
										Start
									</button>
								)}
								{isActive && !isTerminalOnly && onRecreateTunnel && (
									<button
										className="session-option-item"
										onClick={() => {
											setOptionsOpen(false);
											onRecreateTunnel(session);
										}}
										type="button"
										role="menuitem"
									>
										<Icon name="refresh" size="sm" />
										Recreate Tunnel
									</button>
								)}
								{onDelete && (
									<button
										className="session-option-item danger-text"
										onClick={handleDeleteClick}
										type="button"
										role="menuitem"
									>
										<Icon name="delete" size="sm" />
										Delete
									</button>
								)}
							</div>
						)}
					</div>
				</div>
			)}

			<MobileActionSheet
				isOpen={showActionSheet}
				onClose={() => setShowActionSheet(false)}
				title={session.display_name}
				actions={[
					...(isActive && !isTerminalOnly && onRecreateTunnel
						? [
								{
									id: "tunnel",
									label: "Recreate Tunnel",
									icon: "refresh" as IconName,
									onClick: () => onRecreateTunnel(session),
								},
							]
						: []),
					...(isActive && onStop
						? [
								{
									id: "stop",
									label: "Stop",
									icon: "stop" as IconName,
									variant: "danger" as const,
									onClick: () => onStop(session),
								},
							]
						: []),
					...(!isActive && onStart
						? [
								{
									id: "start",
									label: "Start",
									icon: "play" as IconName,
									onClick: () => onStart(session),
								},
							]
						: []),
					...(onDelete
						? [
								{
									id: "delete",
									label: "Delete",
									icon: "delete" as IconName,
									variant: "danger" as const,
									onClick: () => onDelete(session),
								},
							]
						: []),
				]}
			/>
		</article>
	);
}
