/**
 * NoSsr Component - Lynx 版 MUI NoSsr
 * 一比一对应 MUI NoSsr
 * 
 * NoSsr 用于跳过服务端渲染 (SSR)，仅在客户端渲染子元素
 * 
 * 功能：
 * - 延迟渲染 (defer mode)
 * - 占位符支持 (fallback)
 * - 首次挂载检测
 */
// Hooks 类型在 lynx.d.ts 中声明

export interface NoSsrProps {
  /** 子元素 */
  children?: any
  /** 是否延迟渲染 (使用 requestAnimationFrame/setTimeout) */
  defer?: boolean
  /** 服务端渲染时的占位符 */
  fallback?: any
}

/**
 * useEnhancedEffect - 在客户端使用 useLayoutEffect，服务端使用 useEffect
 * 对应 MUI 的 useEnhancedEffect
 */
const useEnhancedEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect

/**
 * NoSsr 组件 - 完整实现
 * 
 * 用法：
 * ```tsx
 * // 基础用法
 * <NoSsr>
 *   <HeavyComponent />
 * </NoSsr>
 * 
 * // 延迟渲染 - 使用 requestAnimationFrame
 * <NoSsr defer>
 *   <AnimatedComponent />
 * </NoSsr>
 * 
 * // 带占位符
 * <NoSsr fallback={<Skeleton />}>
 *   <Content />
 * </NoSsr>
 * ```
 */
export function NoSsr(props: NoSsrProps) {
  const { children, defer = false, fallback = null } = props
  
  // 挂载状态
  const [mounted, setMounted] = useState(false)

  // 使用 useEnhancedEffect 确保在客户端执行
  useEnhancedEffect(() => {
    if (!defer) {
      // 立即挂载
      setMounted(true)
    }
  }, [defer])

  // defer 模式：延迟到下一帧
  useEffect(() => {
    if (defer) {
      // 使用 requestAnimationFrame 或 setTimeout 延迟渲染
      // 这允许浏览器先完成当前帧的渲染
      let rafId: number
      let timeoutId: ReturnType<typeof setTimeout>
      
      if (typeof requestAnimationFrame !== 'undefined') {
        rafId = requestAnimationFrame(() => {
          setMounted(true)
        })
      } else {
        timeoutId = setTimeout(() => {
          setMounted(true)
        }, 0)
      }
      
      return () => {
        if (rafId) {
          cancelAnimationFrame(rafId)
        }
        if (timeoutId) {
          clearTimeout(timeoutId)
        }
      }
    }
    return undefined
  }, [defer])

  // 未挂载时显示占位符
  if (!mounted) {
    return fallback
  }

  // 已挂载，渲染子元素
  return children
}

export default NoSsr
