import type { ReactElement } from 'react'
import { render } from '@testing-library/react'
import type { RenderOptions } from '@testing-library/react'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { BrowserRouter } from 'react-router-dom'
import type { User, UserRole } from '../types/api'

// Mock user for testing
export const createMockUser = (overrides: Partial<User> = {}): User => ({
  id: 'test-user-id',
  email: 'test@example.com',
  full_name: 'Test User',
  role: 'client' as UserRole,
  is_active: true,
  created_at: '2024-01-01T00:00:00Z',
  ...overrides,
})

// Mock auth context
export const createMockAuthContext = (user: User | null = null) => ({
  user,
  login: vi.fn(),
  logout: vi.fn(),
  isLoading: false,
  refreshAuth: vi.fn(),
})

// Test wrapper component
interface AllTheProvidersProps {
  children: React.ReactNode
  queryClient?: QueryClient
}

const AllTheProviders = ({
  children,
  queryClient,
}: AllTheProvidersProps) => {
  const testQueryClient = queryClient || new QueryClient({
    defaultOptions: {
      queries: {
        retry: false,
      },
      mutations: {
        retry: false,
      },
    },
  })

  return (
    <QueryClientProvider client={testQueryClient}>
      <BrowserRouter>
        {children}
      </BrowserRouter>
    </QueryClientProvider>
  )
}

// Custom render function
interface CustomRenderOptions extends Omit<RenderOptions, 'wrapper'> {
  queryClient?: QueryClient
  initialEntries?: string[]
}

const customRender = (
  ui: ReactElement,
  options: CustomRenderOptions = {}
) => {
  const { queryClient, initialEntries, ...renderOptions } = options

  return render(ui, {
    wrapper: ({ children }) => (
      <AllTheProviders 
        queryClient={queryClient}
        initialEntries={initialEntries}
      >
        {children}
      </AllTheProviders>
    ),
    ...renderOptions,
  })
}

// Mock API responses
export const mockApiResponses = {
  auth: {
    loginSuccess: {
      access_token: 'mock-access-token',
      token_type: 'bearer',
      user_id: 'test-user-id',
      role: 'client',
    },
    refreshSuccess: {
      access_token: 'new-mock-access-token',
      token_type: 'bearer',
    },
  },
  jobs: {
    jobList: {
      jobs: [
        {
          id: 'job-1',
          client_id: 'test-user-id',
          filename: 'test-video.mp4',
          status: 'pending_qc',
          created_at: '2024-01-01T00:00:00Z',
          updated_at: '2024-01-01T01:00:00Z',
          review: {
            history: [],
            current_reviewer_id: null,
            english_approval: null,
            final_approval: null,
          },
        },
      ],
      total: 1,
      page: 1,
      size: 20,
    },
    jobDetail: {
      id: 'job-1',
      client_id: 'test-user-id',
      filename: 'test-video.mp4',
      status: 'pending_qc',
      created_at: '2024-01-01T00:00:00Z',
      updated_at: '2024-01-01T01:00:00Z',
      urls: {
        source_video: 'https://example.com/video.mp4',
        captions_vtt: 'https://example.com/captions.vtt',
        audio_description_vtt: 'https://example.com/ad.vtt',
      },
      review: {
        history: [],
        current_reviewer_id: null,
        english_approval: null,
        final_approval: null,
      },
    },
  },
}

// Mock file for file upload tests
export const createMockFile = (
  name: string = 'test-video.mp4',
  type: string = 'video/mp4',
  size: number = 1024 * 1024
): File => {
  const file = new File([''], name, { type })
  Object.defineProperty(file, 'size', { value: size })
  return file
}

// Async test utilities
export const waitForLoadingToFinish = () => 
  new Promise((resolve) => setTimeout(resolve, 0))

// Re-export everything from testing-library
export * from '@testing-library/react'
export { default as userEvent } from '@testing-library/user-event'

// Export the custom render as the default render
export { customRender as render }