import { describe, it, expect, beforeEach, vi } from 'vitest'
import { renderHook, waitFor } from '@testing-library/react'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { useSourceStore } from '../providers/sources/store'
import type { QuerySource, Source } from '../providers/sources/types'
import { getAggregations, useAggregations } from './aggregations'
import type { AggregationsWidgetProps } from './aggregations'

/**
 * End-to-end parity check: a value warmed by calling
 * `queryClient.prefetchQuery(getAggregations(...))` is read by
 * `useAggregations` on the first render with no fetching.
 */
describe('getAggregations ↔ useAggregations parity', () => {
  beforeEach(() => {
    useSourceStore.setState({ sources: {}, filters: {} })
  })

  it('useAggregations returns prefetched data on first render without re-fetching', async () => {
    const queryClient = new QueryClient({
      defaultOptions: { queries: { retry: false, staleTime: Infinity } },
    })

    const expected = { total_count: 42, total_revenue: 12345 }
    const widgetSpy = vi.fn().mockResolvedValue(expected)

    const widgetProps: AggregationsWidgetProps = {
      aggregations: [
        { column: 'id', operation: 'count', alias: 'total_count' },
        { column: 'revenue', operation: 'sum', alias: 'total_revenue' },
      ],
    }

    const sourceConfig: Omit<Source<QuerySource>, 'id'> = {
      type: 'query',
      data: 'SELECT 1',
      connectionName: 'conn',
      apiBaseUrl: 'http://api',
    }
    useSourceStore.getState().setSource<QuerySource>('demo', sourceConfig)

    const source = useSourceStore.getState().sources.demo
    if (source?.widgets) {
      source.widgets.getAggregations = widgetSpy
    }

    await queryClient.prefetchQuery(
      getAggregations({
        accessToken: 'tok',
        sourceId: 'demo',
        widgetProps,
      }),
    )

    expect(widgetSpy).toHaveBeenCalledOnce()

    const wrapper = ({ children }: { children: React.ReactNode }) => (
      <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
    )

    const { result } = renderHook(
      () =>
        useAggregations({
          accessToken: 'tok',
          sourceId: 'demo',
          widgetProps,
        }),
      { wrapper },
    )

    await waitFor(() => {
      expect(result.current.data).toEqual(expected)
    })

    expect(widgetSpy).toHaveBeenCalledOnce()
  })
})
