import React, { useEffect, type ReactNode } from 'react'
import { useAuth } from '../hooks/useAuth'
import type { AuthGuardOptions } from '../types'

interface RequireAuthProps extends AuthGuardOptions {
  children: ReactNode
}

export function RequireAuth({ 
  children, 
  requiredRole, 
  requiredPermissions = [],
  redirectTo = '/login',
  fallbackComponent: FallbackComponent,
  onUnauthorized 
}: RequireAuthProps) {
  const { state, hasPermission, hasRole } = useAuth()

  useEffect(() => {
    if (!state.isLoading && !state.isAuthenticated) {
      onUnauthorized?.()
      if (typeof window !== 'undefined') {
        window.location.href = redirectTo
      }
    }
  }, [state.isLoading, state.isAuthenticated, redirectTo, onUnauthorized])

  if (state.isLoading) {
    return (
      <div className="flex items-center justify-center min-h-screen">
        <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-indigo-600"></div>
      </div>
    )
  }

  if (!state.isAuthenticated) {
    return FallbackComponent ? <FallbackComponent /> : null
  }

  if (requiredRole && !hasRole(requiredRole)) {
    return (
      <div className="flex items-center justify-center min-h-screen">
        <div className="text-center">
          <h2 className="text-2xl font-bold text-gray-900 mb-4">Access Denied</h2>
          <p className="text-gray-600">You don't have permission to access this page.</p>
        </div>
      </div>
    )
  }

  if (requiredPermissions.length > 0) {
    const hasAllPermissions = requiredPermissions.every(permission => hasPermission(permission))
    
    if (!hasAllPermissions) {
      return (
        <div className="flex items-center justify-center min-h-screen">
          <div className="text-center">
            <h2 className="text-2xl font-bold text-gray-900 mb-4">Access Denied</h2>
            <p className="text-gray-600">You don't have the required permissions to access this page.</p>
          </div>
        </div>
      )
    }
  }

  return <>{children}</>
}

export function withRequireAuth<P extends object>(
  Component: React.ComponentType<P>,
  guardOptions?: AuthGuardOptions
) {
  return function WrappedComponent(props: P) {
    return (
      <RequireAuth {...guardOptions}>
        <Component {...props} />
      </RequireAuth>
    )
  }
}