import { useEffect, useImperativeHandle, useRef, useState, forwardRef } from "react" import { Maximize2, Minimize2, Pause, Play, Trash2 } from "lucide-react" import { apiClient } from "@/services/api/client" interface LogViewerProps { name: string lines?: number follow?: boolean } export interface LogViewerHandle { clear: () => void } export const LogViewer = forwardRef(function LogViewer( { name, lines = 50, follow = true }, ref, ) { const [logs, setLogs] = useState([]) const [connected, setConnected] = useState(false) const [maximized, setMaximized] = useState(false) // When true, new log lines scroll the view to the bottom. Scrolling up to read // pauses it; scrolling back to the bottom (or the play button) resumes. const [autoScroll, setAutoScroll] = useState(true) const preRef = useRef(null) useEffect(() => { if (!follow) { apiClient .get<{ lines: string[] }>(`/logs/${name}?n=${lines}`) .then((data) => setLogs(data.lines)) return } const url = apiClient.streamUrl(`/logs/${name}?n=${lines}&follow=true`) const es = new EventSource(url) es.onopen = () => setConnected(true) es.onmessage = (e) => { setLogs((prev) => { const next = [...prev, e.data] return next.length > 500 ? next.slice(-500) : next }) } es.onerror = () => setConnected(false) return () => es.close() }, [name, lines, follow]) const clear = () => setLogs([]) useImperativeHandle(ref, () => ({ clear }), []) // Esc exits fullscreen. useEffect(() => { if (!maximized) return const onKey = (e: KeyboardEvent) => e.key === "Escape" && setMaximized(false) window.addEventListener("keydown", onKey) return () => window.removeEventListener("keydown", onKey) }, [maximized]) // Jump to the newest line only while auto-scroll is on. Scroll the
  // container directly (not scrollIntoView, which would walk up to the window
  // and jump the whole page). Instant, so the scroll-position check below never
  // sees a mid-animation false "scrolled up".
  useEffect(() => {
    const el = preRef.current
    if (autoScroll && el) el.scrollTop = el.scrollHeight
  }, [logs, autoScroll])

  // Keep auto-scroll in sync with where the user is: away from the bottom pauses,
  // back at the bottom resumes — so the button and the scroll position never disagree.
  const onScroll = () => {
    const el = preRef.current
    if (!el) return
    const atBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 40
    setAutoScroll(atBottom)
  }

  const btn =
    "p-1 rounded text-[var(--muted)] hover:text-[var(--foreground)] hover:bg-white/10 transition-colors"

  return (
    
logs: {name} {follow && ( {connected ? "streaming" : "disconnected"} )} {follow && !autoScroll && paused}
        {logs.length === 0 ? (
          No logs yet
        ) : (
          logs.map((line, i) => (
            
{line}
)) )}
) })