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 { useProperties, useProperty, usePropertyById, useCreateProperty } from '../useProperties'

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

describe('useProperties', () => {
  it('returns a non-empty array of properties', async () => {
    const { result } = renderHook(() => useProperties(), { 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 Property[]', async () => {
    const { result } = renderHook(() => useProperties(), { 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?.areaSqm).toBe('number')
  })

  it('accepts an assetType filter', async () => {
    const { result } = renderHook(() => useProperties({ assetType: 'OFFICE' }), { wrapper: wrapper() })
    await waitFor(() => expect(result.current.isSuccess).toBe(true))
    // Filter may or may not be implemented in mock provider — just verify it doesn't error
    expect(result.current.isError).toBe(false)
  })
})

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

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

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

  it('fetches property when id is provided', async () => {
    const { result: all } = renderHook(() => useProperties(), { wrapper: wrapper() })
    await waitFor(() => expect(all.current.isSuccess).toBe(true))
    const id = all.current.data![0].id

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

describe('useCreateProperty', () => {
  it('creates a property and returns it', async () => {
    const { result } = renderHook(() => useCreateProperty(), { wrapper: wrapper() })
    result.current.mutate({
      title: 'Hook-Test Objekt',
      assetType: 'LOGISTICS',
      resultType: 'VERIFIED_PORTFOLIO',
      location: { city: 'Bern', country: 'CH' },
      address: { street: 'Teststrasse', houseNumber: '1', postalCode: '3000', city: 'Bern', country: 'CH' },
      areaSqm: 300,
      rentPricePerSqm: 100,
      availabilityDate: '2025-01-01',
      availabilityStatus: 'AVAILABLE_NOW',
      sourceType: 'DIRECT',
      confidenceScore: 0.8,
      dataQuality: { score: 0.8, missingCriticalFields: [], missingOptionalFields: [], freshness: 'FRESH', warnings: [] },
      organizationId: 'org-test',
    })
    await waitFor(() => expect(result.current.isSuccess).toBe(true))
    expect(result.current.data?.data.title).toBe('Hook-Test Objekt')
  })
})
