import { useEffect, useRef } from "react";
import { Terminal } from "xterm";
import { FitAddon } from "xterm-addon-fit";
import "xterm/css/xterm.css";

interface XTermProps {
	logs: string;
}

const scrollbarHack = `
.xterm-viewport {
	scrollbar-width: auto;
	scrollbar-color: #a0a0a0 #f1f5f9;
}
.xterm-viewport::-webkit-scrollbar {
	width: 8px;
}
.xterm-viewport::-webkit-scrollbar-track {
	background: #f1f5f9;
}
.xterm-viewport::-webkit-scrollbar-thumb {
	background-color: #a0a0a0;
	border-radius: 4px;
	border: 2px solid #f1f5f9;
}
`;

export function XTerm({ logs }: XTermProps) {
	const termRef = useRef<HTMLDivElement>(null);
	const termInstance = useRef<Terminal | null>(null);
	const fitAddon = useRef<FitAddon | null>(null);
	const prevLogs = useRef<string>("");

	useEffect(() => {
		if (termRef.current && !termInstance.current) {
			const term = new Terminal({
				disableStdin: true,
				convertEol: true,
				fontFamily: `'JetBrains Mono', monospace`,
				fontSize: 12,
				theme: {
					background: "#f1f5f9", // bg-muted color
					foreground: "#020817", // text-foreground color
					cursor: "#f1f5f9",
					selectionBackground: "#bfdbfe", // blue-200
					selectionInactiveBackground: "#e2e8f0", // slate-200
				},
			});
			const addon = new FitAddon();
			fitAddon.current = addon;
			term.loadAddon(addon);
			term.open(termRef.current);
			addon.fit();
			termInstance.current = term;

			const resizeObserver = new ResizeObserver(() => {
				fitAddon.current?.fit();
			});
			resizeObserver.observe(termRef.current);

			return () => {
				resizeObserver.disconnect();
				term.dispose();
			};
		}
	}, []);

	useEffect(() => {
		if (termInstance.current) {
			if (logs === "") {
				termInstance.current.clear();
				prevLogs.current = "";
				return;
			}

			const buffer = termInstance.current.buffer.active;
			const wasAtBottom = buffer.viewportY + termInstance.current.rows >= buffer.length;

			const newLogContent = logs.substring(prevLogs.current.length);
			prevLogs.current = logs;

			if (newLogContent) {
				termInstance.current.write(newLogContent, () => {
					if (wasAtBottom) {
						termInstance.current?.scrollToBottom();
					}
				});
			}
		}
	}, [logs]);

	return (
		<>
			<style>{scrollbarHack}</style>
			<div ref={termRef} className="h-full w-full" />
		</>
	);
}
