import React from 'react'
import { QueryClient, QueryClientProvider, useQueryClient } from '@tanstack/react-query'
import { renderHook } from '@testing-library/react'
import { afterEach, describe, expect, it, vi } from 'vitest'
import { usePrefetchOnIntent } from './prefetch'

function createWrapper(queryClient: QueryClient) {
  return function Wrapper({ children }: { children: React.ReactNode }): React.ReactElement {
    return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
  }
}

describe('usePrefetchOnIntent', () => {
  afterEach(() => {
    vi.useRealTimers()
  })

  it('dedupes by string key even when closures change identity', async () => {
    vi.useFakeTimers()
    const queryClient = new QueryClient()
    const prefetch = vi.fn()
    const wrapper = createWrapper(queryClient)

    const first = renderHook(() => {
      const qc = useQueryClient()
      return usePrefetchOnIntent('users:list', () => prefetch(qc))
    }, { wrapper })

    first.result.current.onPointerEnter()
    await vi.advanceTimersByTimeAsync(80)

    const second = renderHook(() => {
      const qc = useQueryClient()
      return usePrefetchOnIntent('users:list', () => prefetch(qc))
    }, { wrapper })

    second.result.current.onFocus()

    expect(prefetch).toHaveBeenCalledTimes(1)
  })

  it('prefetches on touch intent without waiting for hover delay', () => {
    const queryClient = new QueryClient()
    const prefetch = vi.fn()
    const wrapper = createWrapper(queryClient)
    const { result } = renderHook(() => {
      const qc = useQueryClient()
      return usePrefetchOnIntent('products:grid', () => prefetch(qc))
    }, { wrapper })

    result.current.onTouchStart()

    expect(prefetch).toHaveBeenCalledTimes(1)
  })

  it('cancels the hover-intent timer on pointer leave, so a pass-over never prefetches', async () => {
    vi.useFakeTimers()
    const queryClient = new QueryClient()
    const prefetch = vi.fn()
    const wrapper = createWrapper(queryClient)
    const { result } = renderHook(() => {
      const qc = useQueryClient()
      return usePrefetchOnIntent('deals:list', () => prefetch(qc))
    }, { wrapper })

    result.current.onPointerEnter()
    result.current.onPointerLeave()
    await vi.advanceTimersByTimeAsync(80)

    expect(prefetch).not.toHaveBeenCalled()
  })
})
