import React, { useState, useRef, useEffect, useCallback } from "react";

interface ChatBubbleProps {
	agentName: string;
	agentUrl: string;
	initialPosition?: { bottom?: number; right?: number; top?: number; left?: number };
}

const MIN_WIDTH = 200;
const MIN_HEIGHT = 150;
const DEFAULT_WIDTH = 350;
const DEFAULT_HEIGHT = 500;

export function ChatBubble({ agentName, agentUrl, initialPosition = { bottom: 20, right: 20 } }: ChatBubbleProps) {
	const [isExpanded, setIsExpanded] = useState(false);
	const [position, setPosition] = useState(initialPosition);
	const [size, setSize] = useState({ width: DEFAULT_WIDTH, height: DEFAULT_HEIGHT });
	const [isDragging, setIsDragging] = useState(false);
	const [isResizing, setIsResizing] = useState(false);
	const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 });
	const [resizeStart, setResizeStart] = useState({ x: 0, y: 0, width: 0, height: 0 });

	const bubbleRef = useRef<HTMLDivElement>(null);

	const toggleExpansion = useCallback(
		(e: React.MouseEvent) => {
			if (isResizing) {
				return;
			}
			if (
				isExpanded &&
				(e.target === e.currentTarget || (e.target as HTMLElement).closest("button") === e.currentTarget)
			) {
				e.stopPropagation();
			}
			setIsExpanded((prev) => !prev);
			if (!isExpanded) {
				setSize({ width: DEFAULT_WIDTH, height: DEFAULT_HEIGHT });
			}
		},
		[isExpanded, isResizing],
	);

	const handleDragMouseDown = useCallback((e: React.MouseEvent) => {
		if (!bubbleRef.current || (e.target as HTMLElement).closest("button")) {
			return;
		}
		setIsDragging(true);
		const rect = bubbleRef.current.getBoundingClientRect();
		setDragOffset({
			x: e.clientX - rect.left,
			y: e.clientY - rect.top,
		});
		e.preventDefault();
	}, []);

	const handleDragMouseMove = useCallback(
		(e: MouseEvent) => {
			if (!isDragging) return;
			setPosition({
				top: e.clientY - dragOffset.y,
				left: e.clientX - dragOffset.x,
				bottom: undefined,
				right: undefined,
			});
		},
		[isDragging, dragOffset],
	);

	const handleDragMouseUp = useCallback(() => {
		setIsDragging(false);
	}, []);

	const handleResizeMouseDown = useCallback(
		(e: React.MouseEvent) => {
			e.stopPropagation();
			setIsResizing(true);
			setResizeStart({
				x: e.clientX,
				y: e.clientY,
				width: size.width,
				height: size.height,
			});
			e.preventDefault();
		},
		[size],
	);

	const handleResizeMouseMove = useCallback(
		(e: MouseEvent) => {
			if (!isResizing) return;
			const newWidth = Math.max(MIN_WIDTH, resizeStart.width + (e.clientX - resizeStart.x));
			const newHeight = Math.max(MIN_HEIGHT, resizeStart.height + (e.clientY - resizeStart.y));
			setSize({ width: newWidth, height: newHeight });
		},
		[isResizing, resizeStart],
	);

	const handleResizeMouseUp = useCallback(() => {
		setIsResizing(false);
	}, []);

	useEffect(() => {
		const activeDragging = isDragging;
		const activeResizing = isResizing;

		const globalMouseMove = (e: MouseEvent) => {
			if (activeDragging) handleDragMouseMove(e);
			if (activeResizing) handleResizeMouseMove(e);
		};
		const globalMouseUp = () => {
			if (activeDragging) handleDragMouseUp();
			if (activeResizing) handleResizeMouseUp();
		};

		if (activeDragging || activeResizing) {
			window.addEventListener("mousemove", globalMouseMove);
			window.addEventListener("mouseup", globalMouseUp);
		} else {
			window.removeEventListener("mousemove", globalMouseMove);
			window.removeEventListener("mouseup", globalMouseUp);
		}
		return () => {
			window.removeEventListener("mousemove", globalMouseMove);
			window.removeEventListener("mouseup", globalMouseUp);
		};
	}, [isDragging, isResizing, handleDragMouseMove, handleDragMouseUp, handleResizeMouseMove, handleResizeMouseUp]);

	const baseBubbleClasses = `fixed border shadow-lg z-[1000] flex flex-col bg-card text-card-foreground p-3`;
	const collapsedClasses = `min-w-[150px] h-auto rounded-lg items-start`;
	const expandedDynamicClasses = `rounded-lg items-center`;

	const bubbleDynamicClasses = `${baseBubbleClasses} ${isExpanded ? expandedDynamicClasses : collapsedClasses}`;

	const headerClasses = "w-full flex justify-between items-center cursor-grab select-none";
	const iframeContainerClasses = "w-full flex-grow mt-2.5 relative";
	const iframeClasses = "w-full h-full border-none rounded-b-md";
	const buttonClasses = "bg-transparent border-none text-card-foreground p-1 leading-none cursor-pointer";
	const resizeHandleClasses =
		"absolute bottom-0 right-0 w-4 h-4 cursor-se-resize bg-gray-400 opacity-50 hover:opacity-100";

	const bubbleStyle: React.CSSProperties = {
		top: position.top !== undefined ? `${position.top}px` : undefined,
		left: position.left !== undefined ? `${position.left}px` : undefined,
		bottom: position.bottom !== undefined && position.top === undefined ? `${position.bottom}px` : undefined,
		right: position.right !== undefined && position.left === undefined ? `${position.right}px` : undefined,
		width: isExpanded ? `${size.width}px` : undefined,
		height: isExpanded ? `${size.height}px` : undefined,
	};

	return (
		<div
			ref={bubbleRef}
			className={bubbleDynamicClasses}
			style={bubbleStyle}
			onClick={!isExpanded && !isDragging && !isResizing ? toggleExpansion : undefined}
		>
			<div
				className={headerClasses}
				onMouseDown={handleDragMouseDown}
				onDoubleClick={(e) => {
					e.stopPropagation();
					toggleExpansion(e);
				}}
			>
				<span className="font-semibold truncate pr-2">{agentName}</span>
				<button
					onClick={(e) => {
						e.stopPropagation();
						toggleExpansion(e);
					}}
					className={buttonClasses}
					aria-label={isExpanded ? "Collapse chat" : "Expand chat"}
				>
					{isExpanded ? "▼" : "▲"}
				</button>
			</div>
			{isExpanded && (
				<div className={iframeContainerClasses}>
					<iframe
						src={agentUrl}
						title={agentName}
						className={iframeClasses}
						style={{ pointerEvents: isDragging || isResizing ? "none" : "auto" }}
					/>
					<div className={resizeHandleClasses} onMouseDown={handleResizeMouseDown} />
				</div>
			)}
		</div>
	);
}
