import { useCallback, useEffect, useRef } from 'react'

import { useResizeObserver } from '@/hooks/use-resize-observer'
import { cn } from '@/lib/utils'

interface TerminalOutputProps {
  className?: string
  text: string
}

const NEAR_BOTTOM_PX = 24

/**
 * Tiny read-only terminal viewer: monospace, non-wrapping (long lines scroll
 * horizontally), vertical scroll past `max-h`. Jumps to the bottom on mount,
 * then tails — sticking to the bottom as `text` grows, but only when the user
 * is already near the bottom so scrolling up to read earlier output isn't
 * interrupted.
 *
 * Self-contained so any surface (status rows, tool calls, inspectors) can drop
 * in a stdout/stderr box without re-implementing the scroll logic.
 */
export function TerminalOutput({ className, text }: TerminalOutputProps) {
  const ref = useRef<HTMLDivElement>(null)

  // On open: jump straight to the latest output. Rides the ResizeObserver's
  // initial delivery (layout-clean, still before paint) instead of a layout
  // effect — a sync scrollHeight read there forces a reflow per instance, and
  // a tool-heavy transcript mounts dozens of these on a session switch.
  const jumpedRef = useRef(false)

  const jumpToBottom = useCallback(() => {
    const el = ref.current

    // First delivery only; later box resizes must not yank the user back
    // down while they're scrolled up reading earlier output.
    if (el && !jumpedRef.current) {
      jumpedRef.current = true
      el.scrollTop = el.scrollHeight
    }
  }, [])

  useResizeObserver(jumpToBottom, ref)

  // On growth: tail only when already pinned near the bottom.
  useEffect(() => {
    const el = ref.current

    if (el && el.scrollHeight - el.scrollTop - el.clientHeight < NEAR_BOTTOM_PX) {
      el.scrollTop = el.scrollHeight
    }
  }, [text])

  return (
    <div className={cn('max-h-16 overflow-auto overscroll-contain', className)} data-selectable-text="true" ref={ref}>
      <pre className="w-max min-w-full font-mono text-[0.5625rem] leading-[0.85rem] whitespace-pre text-muted-foreground/70">
        {text}
      </pre>
    </div>
  )
}
