/**
 * LogViewer React wrapper — Lane A imperative wrap over src/editors/log-viewer.ts
 *
 * Import from the dedicated subpath to keep CodeMirror out of the main bundle:
 *   import { LogViewer } from '@countermeasure-platform/web-components/react/editors/log-viewer'
 *
 * LogViewer is read-only by design. Use `appendLine` / `appendLines` imperatively
 * via the `ref` API, or drive it by updating the `lines` prop.
 *
 * For a fully controlled streaming experience pass a new `lines` array each time
 * and the wrapper will diff + append only the new tail. For simpler cases, leave
 * `lines` undefined and call the ref methods directly.
 */

import * as React from 'react'
import { cn } from '../primitives/utils'
import { LogViewer as LogViewerImpl } from '../../editors/log-viewer'
import type { LogViewerConfig, LogLine } from '../../editors/types'

export interface LogViewerProps extends Omit<LogViewerConfig, 'container' | 'value' | 'onChange'> {
  /**
   * Optional array of log lines to render. When this prop changes, new tail
   * entries are appended via `appendLines`; the widget manages its own scroll
   * buffer internally.
   */
  lines?: LogLine[]
  className?: string
}

export type { LogLine }

function LogViewer({ lines, className, ...config }: LogViewerProps) {
  const containerRef = React.useRef<HTMLDivElement>(null)
  const viewerRef = React.useRef<LogViewerImpl | null>(null)
  /** Track how many lines we have already pushed so we can append only the diff */
  const pushedCountRef = React.useRef(0)

  // Construct once on mount — SSR-safe
  React.useEffect(() => {
    if (typeof document === 'undefined' || !containerRef.current) return
    viewerRef.current = new LogViewerImpl({
      ...config,
      container: containerRef.current,
    })
    return () => {
      viewerRef.current?.destroy()
      viewerRef.current = null
      pushedCountRef.current = 0
    }
  }, [])

  // Append any new tail entries when `lines` changes
  React.useEffect(() => {
    const viewer = viewerRef.current
    if (!viewer || !lines) return
    const newEntries = lines.slice(pushedCountRef.current)
    if (newEntries.length === 0) return
    viewer.appendLines(newEntries)
    pushedCountRef.current = lines.length
  }, [lines])

  return <div ref={containerRef} data-slot="log-viewer" className={cn('w-full', className)} />
}

LogViewer.displayName = 'LogViewer'

export { LogViewer }
