import { describe, it, expect, vi, beforeEach } from 'vitest';
import { renderHook, waitFor } from '@testing-library/react';
import { MemoryRouter, useNavigate, useSearchParams } from 'react-router-dom';
import { useOAuthCallback } from './useOAuthCallback';
import { useAuthStore } from './useAuth';
import { TokenStorage } from '@/services/tokenStorage';
import React from 'react';

// Mock dependencies
vi.mock('react-router-dom', async () => {
  const actual = await vi.importActual('react-router-dom');
  return {
    ...actual,
    useNavigate: vi.fn(),
    useSearchParams: vi.fn(),
  };
});

vi.mock('./useAuth', () => ({
  useAuthStore: vi.fn(),
}));

describe('useOAuthCallback', () => {
  const mockNavigate = vi.fn();
  const mockSetAuth = vi.fn();
  const mockSearchParams = new URLSearchParams();

  beforeEach(() => {
    vi.clearAllMocks();
    vi.mocked(useNavigate).mockReturnValue(mockNavigate);
    vi.mocked(useSearchParams).mockReturnValue([mockSearchParams]);
    vi.mocked(useAuthStore).mockReturnValue({
      setAuth: mockSetAuth,
    } as any);

    // Clear localStorage
    localStorage.clear();
  });

  it('should redirect to dashboard when token and user_id are present', async () => {
    mockSearchParams.set('token', 'test-token');
    mockSearchParams.set('user_id', '123');

    renderHook(() => useOAuthCallback(), {
      wrapper: ({ children }: { children: React.ReactNode }) => (
        <MemoryRouter>{children}</MemoryRouter>
      ),
    });

    await waitFor(() => {
      expect(TokenStorage.getAccessToken()).toBe('test-token');
      expect(mockSetAuth).toHaveBeenCalled();
      expect(mockNavigate).toHaveBeenCalledWith('/dashboard', {
        replace: true,
      });
    });
  });

  it('should redirect to login when token is missing', async () => {
    mockSearchParams.set('user_id', '123');
    // No token

    renderHook(() => useOAuthCallback(), {
      wrapper: ({ children }: { children: React.ReactNode }) => (
        <MemoryRouter>{children}</MemoryRouter>
      ),
    });

    await waitFor(() => {
      expect(mockNavigate).toHaveBeenCalledWith('/login', { replace: true });
    });
  });

  it('should redirect to login when user_id is missing', async () => {
    mockSearchParams.set('token', 'test-token');
    // No user_id

    renderHook(() => useOAuthCallback(), {
      wrapper: ({ children }: { children: React.ReactNode }) => (
        <MemoryRouter>{children}</MemoryRouter>
      ),
    });

    await waitFor(() => {
      expect(mockNavigate).toHaveBeenCalledWith('/login', { replace: true });
    });
  });
});
