import * as React from "react";

const { useCallback, useEffect, useRef, useState } = React;

export interface LogEntry {
	timestamp: string;
	level: string;
	message: string;
}

interface ServerLogsPanelProps {
	logs: LogEntry[];
}

function levelColor(level: string): string {
	switch (level.toUpperCase()) {
		case "ERROR":
			return "#e06c75";
		case "WARN":
			return "#e5c07b";
		default:
			return "#98c379";
	}
}

export function ServerLogsPanel({ logs }: ServerLogsPanelProps) {
	const [isOpen, setIsOpen] = useState(false);
	const [filter, setFilter] = useState("");
	const [severityFilter, setSeverityFilter] = useState<string>("ALL");
	const scrollRef = useRef<HTMLDivElement>(null);
	const userScrolledUpRef = useRef(false);
	const lastScrollTopRef = useRef(0);

	const filteredLogs = logs.filter((entry) => {
		const matchesSeverity =
			severityFilter === "ALL" || entry.level.toUpperCase() === severityFilter;
		const matchesFilter =
			filter === "" ||
			entry.message.toLowerCase().includes(filter.toLowerCase()) ||
			entry.timestamp.includes(filter);
		return matchesSeverity && matchesFilter;
	});

	const scrollToBottom = useCallback(() => {
		const el = scrollRef.current;
		if (el) {
			el.scrollTop = el.scrollHeight;
			lastScrollTopRef.current = el.scrollTop;
		}
	}, []);

	// Auto-scroll when new entries arrive (unless user scrolled up).
	useEffect(() => {
		if (!isOpen) return;
		if (!userScrolledUpRef.current) {
			scrollToBottom();
		}
	}, [filteredLogs.length, isOpen, scrollToBottom]);

	const handleScroll = () => {
		const el = scrollRef.current;
		if (!el) return;
		const isAtBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 5;
		if (el.scrollTop < lastScrollTopRef.current) {
			userScrolledUpRef.current = true;
		}
		if (isAtBottom) {
			userScrolledUpRef.current = false;
		}
		lastScrollTopRef.current = el.scrollTop;
	};

	const severityButtons = ["ALL", "INFO", "WARN", "ERROR"] as const;

	return (
		<div
			data-testid="server-logs-panel"
			style={{
				borderRadius: "8px",
				border: "1px solid #333",
				overflow: "hidden",
			}}
		>
			{/* Header / toggle */}
			<button
				type="button"
				data-testid="server-logs-panel-toggle"
				onClick={() => setIsOpen((v) => !v)}
				style={{
					width: "100%",
					display: "flex",
					alignItems: "center",
					justifyContent: "space-between",
					padding: "8px 12px",
					background: "#1e1e1e",
					border: "none",
					cursor: "pointer",
					color: "#ccc",
					fontSize: "0.85em",
					fontWeight: 600,
					textAlign: "left",
				}}
			>
				<span>Server Logs</span>
				<span style={{ color: "#666", fontSize: "0.85em" }}>
					{logs.length > 0 && (
						<span style={{ marginRight: "8px", color: "#555" }}>
							{logs.length}
						</span>
					)}
					{isOpen ? "▲" : "▼"}
				</span>
			</button>

			{isOpen && (
				<div style={{ background: "#0d1117" }}>
					{/* Filter controls */}
					<div
						style={{
							display: "flex",
							gap: "6px",
							padding: "8px",
							borderBottom: "1px solid #1e1e1e",
							flexWrap: "wrap",
							alignItems: "center",
						}}
					>
						<input
							type="text"
							data-testid="server-logs-filter-input"
							value={filter}
							onChange={(e) => setFilter(e.target.value)}
							placeholder="Filter logs..."
							style={{
								flex: 1,
								minWidth: "80px",
								padding: "4px 8px",
								borderRadius: "4px",
								border: "1px solid #333",
								background: "#161b22",
								color: "#ccc",
								fontSize: "0.8em",
								outline: "none",
							}}
						/>
						{severityButtons.map((sev) => (
							<button
								key={sev}
								type="button"
								data-testid={`server-logs-severity-${sev.toLowerCase()}`}
								onClick={() => setSeverityFilter(sev)}
								style={{
									padding: "3px 8px",
									borderRadius: "4px",
									border: "1px solid",
									borderColor:
										severityFilter === sev ? levelColor(sev) : "#333",
									background:
										severityFilter === sev
											? "rgba(255,255,255,0.06)"
											: "transparent",
									color:
										sev === "ALL"
											? severityFilter === "ALL"
												? "#ccc"
												: "#555"
											: levelColor(sev),
									fontSize: "0.75em",
									cursor: "pointer",
									fontWeight: severityFilter === sev ? 700 : 400,
								}}
							>
								{sev}
							</button>
						))}
					</div>

					{/* Log entries */}
					<div
						ref={scrollRef}
						onScroll={handleScroll}
						data-testid="server-logs-entries"
						style={{
							maxHeight: "240px",
							overflowY: "auto",
							padding: "4px 0",
							fontFamily: "monospace",
							fontSize: "0.75em",
						}}
					>
						{filteredLogs.length === 0 ? (
							<div
								style={{
									padding: "16px",
									color: "#444",
									textAlign: "center",
									fontSize: "0.9em",
								}}
							>
								No log entries
							</div>
						) : (
							filteredLogs.map((entry, idx) => (
								<div
									// biome-ignore lint/suspicious/noArrayIndexKey: log entries have no stable ID
									key={`${entry.timestamp}-${idx}`}
									style={{
										display: "flex",
										gap: "6px",
										padding: "1px 8px",
										lineHeight: "1.5",
										borderBottom: "1px solid #111",
									}}
								>
									<span
										style={{ color: "#444", flexShrink: 0, minWidth: "70px" }}
									>
										{entry.timestamp.replace("T", " ").replace("Z", "")}
									</span>
									<span
										style={{
											color: levelColor(entry.level),
											flexShrink: 0,
											minWidth: "38px",
											fontWeight: 700,
										}}
									>
										{entry.level}
									</span>
									<span
										style={{
											color: "#c9d1d9",
											wordBreak: "break-word",
											whiteSpace: "pre-wrap",
										}}
									>
										{entry.message}
									</span>
								</div>
							))
						)}
					</div>
				</div>
			)}
		</div>
	);
}
