import React, { useEffect, useMemo, useState } from 'react'
import {
  DeviceEventEmitter,
  Dimensions,
  NativeEventEmitter,
  NativeModules,
  Platform,
  requireNativeComponent,
  StyleSheet,
  View,
  ViewProps,
} from 'react-native'

// On the New Architecture (bridgeless + Fabric) the legacy
// `UIManagerModule.updateNodeSize` path used by the native Android view is
// unavailable, so the native side reports its measured size via a device event
// instead and JS sizes the container, mirroring the iOS behaviour.
const isFabricEnabled =
  (globalThis as unknown as { nativeFabricUIManager?: unknown })
    ?.nativeFabricUIManager != null

interface ApxorViewManagerProps extends ViewProps {
  cardID?: number
}

const ApxorViewManager =
  requireNativeComponent<ApxorViewManagerProps>('ApxorViewManager')

interface EmbedCardViewProps extends ViewProps {
  cardID?: number
}

const EmbedCardView =
  requireNativeComponent<EmbedCardViewProps>('APXRNEmbedCard')

interface ApxorWidgetProps extends ViewProps {
  cardID?: number
}

const ApxorWidget: React.FC<ApxorWidgetProps> = ({ cardID }) => {
  const [cardDimensions, setCardDimensions] = useState({
    height: 0,
    width: 0,
  })
  const eventEmitter = useMemo(
    () => new NativeEventEmitter(NativeModules.APXRNEventEmitter),
    [],
  )

  useEffect(() => {
    if (Platform.OS === 'android') {
      // Legacy Architecture sizes the view natively, no JS handling required.
      if (!isFabricEnabled) {
        return
      }
      const subscription = DeviceEventEmitter.addListener(
        'EmbedCardDimensionsSet',
        (dimensions) => {
          if (dimensions.id === cardID) {
            setCardDimensions(dimensions)
          }
        },
      )

      return () => {
        subscription.remove()
      }
    }
    const subscription = eventEmitter.addListener(
      'EmbedCardDimensionsSet',
      (dimensions) => {
        if (dimensions.width > Dimensions.get('screen').width) {
          dimensions.width = Dimensions.get('screen').width
        }
        if (dimensions.id === cardID) {
          setCardDimensions(dimensions)
        }
      },
    )

    const subscription2 = eventEmitter.addListener(
      'RemovePlaceHolder',
      (dimensions) => {
        if (dimensions.activeCards) {
          if (!dimensions.activeCards.includes(cardID?.toString())) {
            setCardDimensions(dimensions)
          }
        }
      },
    )

    return () => {
      subscription.remove()
      subscription2.remove()
    }
  }, [cardID, eventEmitter])

  if (Platform.OS === 'android') {
    if (!isFabricEnabled) {
      return (
        <View style={styles.viewManager}>
          <ApxorViewManager cardID={cardID} />
        </View>
      )
    }
    return (
      <View
        style={[
          styles.container,
          { height: cardDimensions.height, width: `100%` },
        ]}
        testID={cardID?.toString()}
        nativeID={cardID?.toString()}
      >
        <ApxorViewManager
          cardID={cardID}
          style={styles.fabricChild}
        />
      </View>
    )
  }

  return (
<View
      style={[
        styles.container,
        { height: cardDimensions.height, width: '100%' },
      ]}
      testID={cardID?.toString()}
      nativeID={cardID?.toString()}
      pointerEvents="box-none"
    >
      {/* Explicitly passing style here forces Yoga & the Interop layer
          to size the native component properly */}
      <EmbedCardView
        cardID={cardID}
        style={{ width: '100%', height: cardDimensions.height }}
        pointerEvents="auto"
      />
    </View>
  )
}

const styles = StyleSheet.create({
  container: {
    overflow: 'hidden', // Ensure that contents are clipped if they exceed the specified dimensions
  },
  fabricChild: {
    flex: 1,
  },
  viewManager: {
    width: '100%',
  },
})

export { ApxorWidget }
