'use client';

import { useEffect, useRef } from 'react';

/** Anything with a `.focus()` method. */
export interface Focusable {
  focus: () => void;
}

/**
 * Core stream-end focus effect — context-free on purpose so it can run
 * *inside* `ChatProvider` without an import cycle (`context` →
 * `hooks/useAutoFocusOnStreamEnd` → `context`).
 *
 * Fires `resolveTarget().focus()` on the streaming true → false edge.
 * Both `ChatProvider` and the public `useAutoFocusOnStreamEnd` hook
 * delegate here.
 */
export function useStreamEndFocus(params: {
  isStreaming: boolean;
  enabled: boolean;
  delayMs: number;
  /** Resolves the focus target lazily, at fire time — so it always
   *  sees the freshest registered composer handle. */
  resolveTarget: () => Focusable | null;
}): void {
  const { isStreaming, enabled, delayMs, resolveTarget } = params;

  // Keep the resolver in a ref so the effect doesn't re-fire when the
  // caller passes a fresh closure each render.
  const resolveRef = useRef(resolveTarget);
  resolveRef.current = resolveTarget;

  const prevStreamingRef = useRef(isStreaming);

  useEffect(() => {
    const wasStreaming = prevStreamingRef.current;
    prevStreamingRef.current = isStreaming;

    if (!enabled) return;
    // Only the true → false transition fires focus — toggling `enabled`
    // mid-stream won't steal focus while the user is reading.
    if (!(wasStreaming && !isStreaming)) return;

    const focusNow = () => resolveRef.current()?.focus();

    if (delayMs > 0) {
      const id = window.setTimeout(focusNow, delayMs);
      return () => window.clearTimeout(id);
    }
    const raf = requestAnimationFrame(focusNow);
    return () => cancelAnimationFrame(raf);
  }, [isStreaming, enabled, delayMs]);
}
