import React from 'react'
import { StyleSheet, View } from 'react-native'
import Animated, { useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated'
import { SafeAreaInsetsContext } from 'react-native-safe-area-context'
import { QuickPreviewOptions } from '../types'
import { Backdrop } from './components/Backdrop'
import { SheetContainer } from './components/SheetContainer'
import { PopoverContainer } from './components/PopoverContainer'

export function QuickPreviewRoot({
  options,
  onRequestClose,
  children,
}: {
  options?: QuickPreviewOptions
  onRequestClose: () => void
  children: React.ReactNode
}) {
  // Read insets from context directly so a missing <SafeAreaProvider> degrades
  // to zero insets instead of throwing. useSafeAreaInsets() would crash the host
  // app when no provider is mounted; the peek only needs insets to clear the
  // notch / home indicator, so zero is a safe fallback (provider still recommended).
  const insets = React.useContext(SafeAreaInsetsContext)
  const top = insets?.top ?? 0
  const bottom = insets?.bottom ?? 0
  const variant = options?.variant ?? 'popover'
  const dismissOnBackdropPress = options?.dismissOnBackdropPress ?? true

  const opacity = useSharedValue(0)

  const cbs = React.useRef({
    onOpenStart: options?.onOpenStart,
    onOpenEnd: options?.onOpenEnd,
    onCloseStart: options?.onCloseStart,
    onCloseEnd: options?.onCloseEnd,
  })
  React.useEffect(() => {
    cbs.current = {
      onOpenStart: options?.onOpenStart,
      onOpenEnd: options?.onOpenEnd,
      onCloseStart: options?.onCloseStart,
      onCloseEnd: options?.onCloseEnd,
    }
  }, [options?.onOpenStart, options?.onOpenEnd, options?.onCloseStart, options?.onCloseEnd])

  React.useEffect(() => {
    cbs.current.onOpenStart?.()
    opacity.value = withTiming(1, { duration: 180 }, finished => {
      if (finished) cbs.current.onOpenEnd?.()
    })
    return () => {
      cbs.current.onCloseStart?.()
      cbs.current.onCloseEnd?.()
    }
    // run once (mount-only effect)
  }, [])

  const containerStyle = useAnimatedStyle(() => ({ opacity: opacity.value }))

  return (
    <View style={StyleSheet.absoluteFill} pointerEvents="box-none" accessibilityViewIsModal>
      <Animated.View style={[StyleSheet.absoluteFill, containerStyle]} pointerEvents="box-none">
        <Backdrop
          onPress={dismissOnBackdropPress ? onRequestClose : undefined}
          dismissOnBackdropPress={dismissOnBackdropPress}
        />
        {variant === 'sheet' ? (
          <SheetContainer insets={{ top, bottom }} options={options} onRequestClose={onRequestClose}>
            {children}
          </SheetContainer>
        ) : (
          <PopoverContainer insets={{ top, bottom }} options={options} onRequestClose={onRequestClose}>
            {children}
          </PopoverContainer>
        )}
      </Animated.View>
    </View>
  )
}
