'use client'

/**
 * Small async-resource hook for the SEO tabs: wraps a service fetcher with
 * loading / error / data / refetch and abort-on-unmount safety. Keeps each
 * tab declarative without re-implementing fetch plumbing.
 */
import { useCallback, useEffect, useRef, useState } from 'react'

export interface SeoResource<T> {
  data: T | null
  loading: boolean
  error: string | null
  refetch: () => void
}

export function useSeoResource<T>(
  fetcher: () => Promise<T>,
  deps: ReadonlyArray<unknown> = [],
): SeoResource<T> {
  const [data, setData] = useState<T | null>(null)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  // Tracks whether the component is still mounted (guards setState after
  // unmount). Set once on mount; never toggled by dependency-driven reloads.
  const mountedRef = useRef(true)
  // Monotonic id of the most recently *started* request. A response is only
  // applied when its id still matches — otherwise a slow earlier request that
  // resolves after a faster later one (rapid filter switches) would clobber
  // the newer, correct data.
  const requestIdRef = useRef(0)
  // eslint-disable-next-line react-hooks/exhaustive-deps
  const stableFetcher = useCallback(fetcher, deps)

  const load = useCallback(async () => {
    const requestId = ++requestIdRef.current
    const isCurrent = () => mountedRef.current && requestId === requestIdRef.current
    setLoading(true)
    setError(null)
    try {
      const result = await stableFetcher()
      if (isCurrent()) setData(result)
    } catch (err) {
      if (isCurrent()) {
        setError(err instanceof Error ? err.message : 'Failed to load data')
      }
    } finally {
      if (isCurrent()) setLoading(false)
    }
  }, [stableFetcher])

  // Mount/unmount guard only — independent of `load` so a dependency change
  // (which recreates `load`) never flips `mountedRef` to false mid-flight.
  useEffect(() => {
    mountedRef.current = true
    return () => {
      mountedRef.current = false
    }
  }, [])

  useEffect(() => {
    load()
  }, [load])

  return { data, loading, error, refetch: load }
}
