import React from 'react'

import {QueryClient} from '@tanstack/react-query'
import {renderHook} from '@testing-library/react'
import {describe, expect, it} from 'vitest'

import {
  createShopMinisQueryClient,
  ShopMinisQueryClientContext,
  useShopMinisQueryClient,
} from './queryClient'

describe('queryClient', () => {
  describe('createShopMinisQueryClient', () => {
    it('creates a QueryClient instance', () => {
      const client = createShopMinisQueryClient()

      expect(client).toBeInstanceOf(QueryClient)
    })

    it('creates isolated QueryClient instances', () => {
      const client1 = createShopMinisQueryClient()
      const client2 = createShopMinisQueryClient()

      // Each call creates a new instance
      expect(client1).not.toBe(client2)
    })

    it('has caching disabled by default', () => {
      const client = createShopMinisQueryClient()

      const defaults = client.getDefaultOptions()

      expect(defaults.queries?.staleTime).toBe(0)
      expect(defaults.queries?.gcTime).toBe(0)
    })

    it('has retry and refetchOnWindowFocus configured', () => {
      const client = createShopMinisQueryClient()

      const defaults = client.getDefaultOptions()

      expect(defaults.queries?.retry).toBe(1)
      expect(defaults.queries?.refetchOnWindowFocus).toBe(false)
    })
  })

  describe('useShopMinisQueryClient', () => {
    it('throws error when used outside provider', () => {
      expect(() => {
        renderHook(() => useShopMinisQueryClient())
      }).toThrow(
        'Shop Minis hooks must be used within <MinisContainer> or <MinisQueryProvider>. ' +
          'Wrap your component tree with one of these providers.'
      )
    })

    it('returns QueryClient when used within provider', () => {
      const client = createShopMinisQueryClient()
      const wrapper = ({children}: {children: React.ReactNode}) => (
        <ShopMinisQueryClientContext.Provider value={client}>
          {children}
        </ShopMinisQueryClientContext.Provider>
      )

      const {result} = renderHook(() => useShopMinisQueryClient(), {wrapper})

      expect(result.current).toBe(client)
      expect(result.current).toBeInstanceOf(QueryClient)
    })

    it('returns the same client instance across re-renders', () => {
      const client = createShopMinisQueryClient()
      const wrapper = ({children}: {children: React.ReactNode}) => (
        <ShopMinisQueryClientContext.Provider value={client}>
          {children}
        </ShopMinisQueryClientContext.Provider>
      )

      const {result, rerender} = renderHook(() => useShopMinisQueryClient(), {
        wrapper,
      })

      const firstClient = result.current
      rerender()
      const secondClient = result.current

      expect(firstClient).toBe(secondClient)
    })
  })
})
