import { renderHook } from '@testing-library/react'
import { useSession } from 'next-auth/react'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { useProAccess } from '../use-pro-access'
import React from 'react'

// Mock next-auth
jest.mock('next-auth/react')
const mockUseSession = useSession as jest.MockedFunction<typeof useSession>

// Mock fetch
global.fetch = jest.fn()

// Test wrapper with QueryClient
const createWrapper = () => {
  const queryClient = new QueryClient({
    defaultOptions: {
      queries: {
        retry: false,
      },
    },
  })
  const TestWrapper = ({ children }: { children: React.ReactNode }) => (
    <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
  )
  TestWrapper.displayName = 'TestWrapper'
  return TestWrapper
}

describe('useProAccess Hook', () => {
  beforeEach(() => {
    jest.clearAllMocks()
  })

  it('returns false for unauthenticated users', () => {
    mockUseSession.mockReturnValue({
      data: null,
      status: 'unauthenticated',
      update: jest.fn(),
    })

    const { result } = renderHook(() => useProAccess(), {
      wrapper: createWrapper()
    })
    expect(result.current.hasProAccess).toBe(false)
    expect(result.current.isLoading).toBe(false)
  })

  it('returns false for authenticated users without pro subscription', () => {
    mockUseSession.mockReturnValue({
      data: {
        user: {
          id: '1',
          email: 'user@example.com',
          name: 'Test User',
        },
        expires: '2024-12-31',
      },
      status: 'authenticated',
      update: jest.fn(),
    })

    const { result } = renderHook(() => useProAccess(), {
      wrapper: createWrapper()
    })
    expect(result.current.hasProAccess).toBe(false)
    expect(result.current.isLoading).toBe(false)
  })

  it('returns true for authenticated users with active pro subscription', () => {
    mockUseSession.mockReturnValue({
      data: {
        user: {
          id: '1',
          email: 'pro@example.com',
          name: 'Pro User',
          subscription: {
            plan: 'pro',
            status: 'active',
            expiresAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(), // 30 days from now
          },
        },
        expires: '2024-12-31',
      },
      status: 'authenticated',
      update: jest.fn(),
    })

    const { result } = renderHook(() => useProAccess(), {
      wrapper: createWrapper()
    })
    expect(result.current.hasProAccess).toBe(true)
    expect(result.current.isLoading).toBe(false)
  })

  it('returns false for users with expired pro subscription', () => {
    mockUseSession.mockReturnValue({
      data: {
        user: {
          id: '1',
          email: 'expired@example.com',
          name: 'Expired User',
          subscription: {
            plan: 'pro',
            status: 'active',
            expiresAt: new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString(), // 1 day ago
          },
        },
        expires: '2024-12-31',
      },
      status: 'authenticated',
      update: jest.fn(),
    })

    const { result } = renderHook(() => useProAccess(), {
      wrapper: createWrapper()
    })
    expect(result.current.hasProAccess).toBe(false)
    expect(result.current.isLoading).toBe(false)
  })

  it('returns false for users with cancelled pro subscription', () => {
    mockUseSession.mockReturnValue({
      data: {
        user: {
          id: '1',
          email: 'cancelled@example.com',
          name: 'Cancelled User',
          subscription: {
            plan: 'pro',
            status: 'cancelled',
            expiresAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(),
          },
        },
        expires: '2024-12-31',
      },
      status: 'authenticated',
      update: jest.fn(),
    })

    const { result } = renderHook(() => useProAccess(), {
      wrapper: createWrapper()
    })
    expect(result.current.hasProAccess).toBe(false)
    expect(result.current.isLoading).toBe(false)
  })

  it('returns loading state when session is loading', () => {
    mockUseSession.mockReturnValue({
      data: null,
      status: 'loading',
      update: jest.fn(),
    })

    const { result } = renderHook(() => useProAccess(), {
      wrapper: createWrapper()
    })
    expect(result.current.hasProAccess).toBe(false)
    expect(result.current.isLoading).toBe(true)
  })

  it('handles edge cases with missing subscription data', () => {
    mockUseSession.mockReturnValue({
      data: {
        user: {
          id: '1',
          email: 'user@example.com',
          name: 'Test User',
          subscription: undefined,
        },
        expires: '2024-12-31',
      },
      status: 'authenticated',
      update: jest.fn(),
    })

    const { result } = renderHook(() => useProAccess(), {
      wrapper: createWrapper()
    })
    expect(result.current.hasProAccess).toBe(false)
    expect(result.current.isLoading).toBe(false)
  })
})
