import { useState, useCallback, useEffect } from 'react';
import { useStdout } from 'ink';

export interface UseViewportOptions {
  totalItems: number;
  reservedLines?: number;
}

export interface UseViewportReturn {
  scrollOffset: number;
  viewportSize: number;
  isScrolledUp: boolean;
  scrollToBottom: () => void;
  scrollBy: (delta: number) => void;
  scrollTo: (offset: number) => void;
  canScrollUp: boolean;
  canScrollDown: boolean;
}

export function useViewport({
  totalItems,
  reservedLines = 10,
}: UseViewportOptions): UseViewportReturn {
  const { stdout } = useStdout();
  const rows = stdout?.rows ?? 24;
  const viewportSize = Math.max(1, rows - reservedLines);

  const [scrollOffset, setScrollOffset] = useState(0);
  const [autoFollow, setAutoFollow] = useState(true);

  // Compute the maximum valid scroll offset
  const maxOffset = Math.max(0, totalItems - viewportSize);

  // Auto-follow: when new items arrive and auto-follow is on, snap to bottom
  useEffect(() => {
    if (autoFollow) {
      setScrollOffset(maxOffset);
    }
  }, [autoFollow, maxOffset]);

  const scrollTo = useCallback(
    (offset: number) => {
      const clamped = Math.max(0, Math.min(offset, maxOffset));
      setScrollOffset(clamped);
      setAutoFollow(clamped >= maxOffset);
    },
    [maxOffset],
  );

  const scrollBy = useCallback(
    (delta: number) => {
      setScrollOffset((prev) => {
        const next = Math.max(0, Math.min(prev + delta, maxOffset));
        setAutoFollow(next >= maxOffset);
        return next;
      });
    },
    [maxOffset],
  );

  const scrollToBottom = useCallback(() => {
    setScrollOffset(maxOffset);
    setAutoFollow(true);
  }, [maxOffset]);

  const isScrolledUp = scrollOffset < maxOffset;
  const canScrollUp = scrollOffset > 0;
  const canScrollDown = scrollOffset < maxOffset;

  return {
    scrollOffset,
    viewportSize,
    isScrolledUp,
    scrollToBottom,
    scrollBy,
    scrollTo,
    canScrollUp,
    canScrollDown,
  };
}
