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 { useNeeds, useNeed, useCreateNeed } from '../useNeeds'

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

describe('useNeeds', () => {
  it('returns an array of needs when data loads', async () => {
    const { result } = renderHook(() => useNeeds(), { 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 data envelope so data is Need[]', async () => {
    const { result } = renderHook(() => useNeeds(), { 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?.companyName).toBe('string')
  })

  it('accepts refetchOnMount option without changing query key', async () => {
    const { result } = renderHook(() => useNeeds({ refetchOnMount: 'always' }), { wrapper: wrapper() })
    await waitFor(() => expect(result.current.isSuccess).toBe(true))
    expect(result.current.data?.length).toBeGreaterThan(0)
  })
})

describe('useNeed', () => {
  it('returns a single need for a valid id', async () => {
    // First fetch all to get a real id
    const { result: all } = renderHook(() => useNeeds(), { wrapper: wrapper() })
    await waitFor(() => expect(all.current.isSuccess).toBe(true))
    const id = all.current.data![0].id

    const { result } = renderHook(() => useNeed(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(() => useNeed(''), { wrapper: wrapper() })
    expect(result.current.fetchStatus).toBe('idle')
  })
})

describe('useCreateNeed', () => {
  it('mutates successfully and returns the created need', async () => {
    const { result } = renderHook(() => useCreateNeed(), { wrapper: wrapper() })
    result.current.mutate({
      companyName: 'Hook Test GmbH',
      assetType: 'OFFICE',
      requiredArea: { min: 200, max: 400 },
      preferredLocations: ['Zürich'],
      budgetRange: { maxPerSqm: 400, maxMonthlyTotal: 10000, currency: 'CHF' },
      organizationId: 'org-test',
      timing: { earliestMoveIn: '2025-01-01', latestMoveIn: '2026-01-01', flexibleTiming: true },
      weightingProfile: { area: 0.3, location: 0.3, budget: 0.2, timing: 0.1, prestige: 0, accessibility: 0, expansionPotential: 0, flexibility: 0, visibility: 0, footfall: 0, talentAccess: 0, esg: 0, taxEnvironment: 0 },
      confidenceInCriteria: 0.8,
    })
    await waitFor(() => expect(result.current.isSuccess).toBe(true))
    expect(result.current.data?.data.companyName).toBe('Hook Test GmbH')
  })
})
