import { describe, it, expect } from 'vitest'
import { renderHook, waitFor } from '@testing-library/react'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { createElement } from 'react'
import { useMatches, useMatchesByNeed, useMatchesByProperty, useMatchDetail } from '../useMatches'

function wrapper() {
  const qc = new QueryClient({ defaultOptions: { queries: { retry: false } } })
  return ({ children }: { children: React.ReactNode }) =>
    createElement(QueryClientProvider, { client: qc }, children)
}

describe('useMatches', () => {
  it('returns an array of matches', async () => {
    const { result } = renderHook(() => useMatches(), { wrapper: wrapper() })
    await waitFor(() => expect(result.current.isSuccess).toBe(true))
    expect(Array.isArray(result.current.data)).toBe(true)
    expect((result.current.data ?? []).length).toBeGreaterThan(0)
  })

  it('select unwraps the envelope — data is Match[]', async () => {
    const { result } = renderHook(() => useMatches(), { wrapper: wrapper() })
    await waitFor(() => expect(result.current.isSuccess).toBe(true))
    const first = result.current.data?.[0]
    expect(typeof first?.id).toBe('string')
    expect(typeof first?.matchScore).toBe('number')
    expect(typeof first?.needId).toBe('string')
    expect(typeof first?.propertyId).toBe('string')
  })
})

describe('useMatchesByNeed', () => {
  it('returns matches for the given needId', async () => {
    const { result: all } = renderHook(() => useMatches(), { wrapper: wrapper() })
    await waitFor(() => expect(all.current.isSuccess).toBe(true))
    const needId = all.current.data![0].needId

    const { result } = renderHook(() => useMatchesByNeed(needId), { wrapper: wrapper() })
    await waitFor(() => expect(result.current.isSuccess).toBe(true))
    expect(result.current.data?.every(m => m.needId === needId)).toBe(true)
  })

  it('is disabled when needId is empty string', () => {
    const { result } = renderHook(() => useMatchesByNeed(''), { wrapper: wrapper() })
    expect(result.current.fetchStatus).toBe('idle')
  })
})

describe('useMatchesByProperty', () => {
  it('returns matches for the given propertyId', async () => {
    const { result: all } = renderHook(() => useMatches(), { wrapper: wrapper() })
    await waitFor(() => expect(all.current.isSuccess).toBe(true))
    const propertyId = all.current.data![0].propertyId

    const { result } = renderHook(() => useMatchesByProperty(propertyId), { wrapper: wrapper() })
    await waitFor(() => expect(result.current.isSuccess).toBe(true))
    expect(result.current.data?.every(m => m.propertyId === propertyId)).toBe(true)
  })
})

describe('useMatchDetail', () => {
  it('returns a single match for a valid id', async () => {
    const { result: all } = renderHook(() => useMatches(), { wrapper: wrapper() })
    await waitFor(() => expect(all.current.isSuccess).toBe(true))
    const id = all.current.data![0].id

    const { result } = renderHook(() => useMatchDetail(id), { wrapper: wrapper() })
    await waitFor(() => expect(result.current.isSuccess).toBe(true))
    expect(result.current.data?.id).toBe(id)
  })

  it('is disabled when id is empty string', () => {
    const { result } = renderHook(() => useMatchDetail(''), { wrapper: wrapper() })
    expect(result.current.fetchStatus).toBe('idle')
  })
})
