/**
 * useCanvasElapsedTime Hook
 *
 * Tracks elapsed time since page load for element visibility timing.
 * Used in constructor.tsx to control element appear/disappear based on timing.
 */

import { useState, useEffect, useRef } from 'react';

interface UseCanvasElapsedTimeOptions {
  /** Identifier for the current page (resets timer on change) */
  pageId: string;
  /** Whether the timer is active */
  enabled?: boolean;
  /** Update interval in milliseconds (default: 100ms) */
  intervalMs?: number;
}

interface UseCanvasElapsedTimeResult {
  /** Current elapsed time in seconds since page load */
  elapsedSec: number;
  /** Reset the elapsed time to zero */
  reset: () => void;
  /** Timestamp when the current page started (for external calculations) */
  startedAt: number;
}

/**
 * Hook to track elapsed time since page load.
 * Resets when pageId changes. Used for element visibility timing.
 *
 * @example
 * const { elapsedSec } = useCanvasElapsedTime({
 *   pageId: activePageId,
 *   enabled: !isLoading,
 * });
 *
 * // Check if element should be visible
 * const isVisible = elapsedSec >= element.appearDelaySec;
 */
export function useCanvasElapsedTime({
  pageId,
  enabled = true,
  intervalMs = 100,
}: UseCanvasElapsedTimeOptions): UseCanvasElapsedTimeResult {
  const [elapsedSec, setElapsedSec] = useState(0);
  const startedAtRef = useRef<number>(Date.now());

  // Reset timer when pageId changes
  useEffect(() => {
    if (typeof window === 'undefined') return;

    if (!enabled || !pageId) {
      setElapsedSec(0);
      return;
    }

    startedAtRef.current = Date.now();
    setElapsedSec(0);

    const intervalId = window.setInterval(() => {
      const elapsed = (Date.now() - startedAtRef.current) / 1000;
      setElapsedSec(elapsed > 0 ? elapsed : 0);
    }, intervalMs);

    return () => window.clearInterval(intervalId);
  }, [pageId, enabled, intervalMs]);

  const reset = () => {
    startedAtRef.current = Date.now();
    setElapsedSec(0);
  };

  return {
    elapsedSec,
    reset,
    startedAt: startedAtRef.current,
  };
}

/**
 * Check if an element should be visible based on timing settings.
 *
 * @param elapsedSec - Current elapsed time in seconds
 * @param appearDelaySec - Delay before element appears (default: 0)
 * @param appearDurationSec - Duration element is visible (null = infinite)
 * @returns Whether the element should be visible
 */
export function isElementVisibleAtTime(
  elapsedSec: number,
  appearDelaySec?: number,
  appearDurationSec?: number | null,
): boolean {
  const delay = Number(appearDelaySec || 0);

  // Not yet visible
  if (elapsedSec < delay) return false;

  // No duration limit - always visible after delay
  if (appearDurationSec === null || appearDurationSec === undefined) {
    return true;
  }

  const duration = Number(appearDurationSec);
  if (!Number.isFinite(duration) || duration <= 0) return true;

  // Check if still within visibility window
  return elapsedSec <= delay + duration;
}

export default useCanvasElapsedTime;
