import { renderHook, act } from '@testing-library/react'
import { vi, beforeEach, describe, it, expect } from 'vitest'
import { useData } from '../src/hooks/useData'
import * as sb from '../src/lib/supabase'
import * as table from '../src/hooks/useSupabaseTable'

beforeEach(() => vi.restoreAllMocks())

describe('useData', () => {
  it('returns sample data when supabase not configured', async () => {
    vi.spyOn(sb, 'isSupabaseConfigured').mockReturnValue(false)
    const sample = [{ id: 1, title: 's' }]
    const { result } = renderHook(() => useData('posts', sample))
    expect(result.current.data).toBe(sample)
    expect(result.current.isLive).toBe(false)
    expect(result.current.loading).toBe(false)
    expect(result.current.error).toBeNull()

    let addResult: any = 'unset'
    await act(async () => { addResult = await result.current.add({ title: 'x' }) })
    expect(addResult).toBeNull()
    let upd: any = 'unset'
    await act(async () => { upd = await result.current.update('1', { title: 'x' }) })
    expect(upd).toBe(false)
    let rem: any = 'unset'
    await act(async () => { rem = await result.current.remove('1') })
    expect(rem).toBe(false)
  })

  it('returns live rows when configured and table has data', () => {
    vi.spyOn(sb, 'isSupabaseConfigured').mockReturnValue(true)
    const liveRows = [{ id: '1', title: 'live' }]
    const add = vi.fn()
    const update = vi.fn()
    const remove = vi.fn()
    const refresh = vi.fn()
    vi.spyOn(table, 'useSupabaseTable').mockReturnValue({
      data: liveRows, loading: false, error: null, add, update, remove, refresh,
    } as any)
    const sample = [{ id: 99, title: 'sample' }]
    const { result } = renderHook(() => useData('posts', sample))
    expect(result.current.data).toBe(liveRows)
    expect(result.current.isLive).toBe(true)
    expect(result.current.add).toBe(add)
    expect(result.current.update).toBe(update)
    expect(result.current.remove).toBe(remove)
    expect(result.current.refresh).toBe(refresh)
  })

  it('falls back to sample data when live fetch errors (e.g. missing table)', () => {
    vi.spyOn(sb, 'isSupabaseConfigured').mockReturnValue(true)
    vi.spyOn(table, 'useSupabaseTable').mockReturnValue({
      data: [], loading: false, error: 'relation does not exist',
      add: vi.fn(), update: vi.fn(), remove: vi.fn(), refresh: vi.fn(),
    } as any)
    const sample = [{ id: 99, title: 'sample' }]
    const { result } = renderHook(() => useData('posts', sample))
    expect(result.current.data).toBe(sample)
    expect(result.current.isLive).toBe(true)
  })

  it('shows sample data while live fetch is still loading', () => {
    vi.spyOn(sb, 'isSupabaseConfigured').mockReturnValue(true)
    vi.spyOn(table, 'useSupabaseTable').mockReturnValue({
      data: [], loading: true, error: null,
      add: vi.fn(), update: vi.fn(), remove: vi.fn(), refresh: vi.fn(),
    } as any)
    const sample = [{ id: 99, title: 'sample' }]
    const { result } = renderHook(() => useData('posts', sample))
    expect(result.current.data).toBe(sample)
    expect(result.current.loading).toBe(true)
  })

  it('returns a genuinely empty live collection (no error, not loading)', () => {
    vi.spyOn(sb, 'isSupabaseConfigured').mockReturnValue(true)
    const empty: any[] = []
    vi.spyOn(table, 'useSupabaseTable').mockReturnValue({
      data: empty, loading: false, error: null,
      add: vi.fn(), update: vi.fn(), remove: vi.fn(), refresh: vi.fn(),
    } as any)
    const sample = [{ id: 99, title: 'sample' }]
    const { result } = renderHook(() => useData('posts', sample))
    expect(result.current.data).toBe(empty)
    expect(result.current.isLive).toBe(true)
  })
})
