import React from "react"
import {
  useClubStatsQuery,
  useRecentDistributionsQuery,
} from "@/services/dashboard"
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
import { renderHook, waitFor } from "@testing-library/react"
import { afterAll, afterEach, beforeAll, describe, expect, it } from "vitest"

import { mockClubStats, mockRecentDistributions } from "../mocks/handlers"
import { server } from "../mocks/server"

beforeAll(() => server.listen({ onUnhandledRequest: "error" }))
afterEach(() => server.resetHandlers())
afterAll(() => server.close())

function createWrapper() {
  const queryClient = new QueryClient({
    defaultOptions: { queries: { retry: false, gcTime: 0 } },
  })
  return function Wrapper({ children }: { children: React.ReactNode }) {
    return (
      <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
    )
  }
}

describe("useClubStatsQuery", () => {
  it("returns club statistics", async () => {
    const { result } = renderHook(() => useClubStatsQuery(), {
      wrapper: createWrapper(),
    })

    await waitFor(() => expect(result.current.isSuccess).toBe(true))
    expect(result.current.data).toEqual(mockClubStats)
    expect(result.current.data?.totalMembers).toBe(42)
    expect(result.current.data?.activeMembers).toBe(38)
    expect(result.current.data?.totalDistributions).toBe(156)
  })

  it("returns error on API failure", async () => {
    const { http, HttpResponse } = await import("msw")
    server.use(
      http.get("/api/backend/dashboard/stats", () => {
        return HttpResponse.json(
          { code: "SERVER_ERROR", message: "Unavailable" },
          { status: 503 }
        )
      })
    )

    const { result } = renderHook(() => useClubStatsQuery(), {
      wrapper: createWrapper(),
    })

    await waitFor(() => expect(result.current.isError).toBe(true))
  })
})

describe("useRecentDistributionsQuery", () => {
  it("returns recent distributions with default limit", async () => {
    const { result } = renderHook(() => useRecentDistributionsQuery(), {
      wrapper: createWrapper(),
    })

    await waitFor(() => expect(result.current.isSuccess).toBe(true))
    expect(result.current.data).toEqual(mockRecentDistributions)
    expect(result.current.data).toHaveLength(2)
  })

  it("accepts custom limit parameter", async () => {
    const { result } = renderHook(() => useRecentDistributionsQuery(10), {
      wrapper: createWrapper(),
    })

    await waitFor(() => expect(result.current.isSuccess).toBe(true))
    expect(result.current.data).toBeDefined()
  })
})
