/**
 * react-native mock for component rendering tests (vitest + jsdom)
 *
 * This file is used as a resolve.alias for 'react-native' in vitest.config.render.ts.
 * It provides real React component implementations so @testing-library/react-native
 * can render and query them in jsdom. The real react-native package cannot be loaded
 * in Node 22 due to ESM/typeof issues.
 */

import React from 'react'

// ---------------------------------------------------------------------------
// Helper: create a simple host component that forwards props to a DOM element
// ---------------------------------------------------------------------------
function createMockComponent(name: string) {
  const Component = React.forwardRef((props: any, ref: any) => {
    const { children, testID, ...rest } = props
    return React.createElement(
      name,
      { ...rest, testID, 'data-testid': testID, ref },
      children
    )
  })
  Component.displayName = name
  return Component
}

// ---------------------------------------------------------------------------
// Core RN Components
// ---------------------------------------------------------------------------
export const View = createMockComponent('View')
export const Text = createMockComponent('Text')
export const TextInput = createMockComponent('TextInput')
export const Image = createMockComponent('Image')
export const ImageBackground = createMockComponent('ImageBackground')
export const ScrollView = createMockComponent('ScrollView')
export const SafeAreaView = createMockComponent('SafeAreaView')
export const ActivityIndicator = createMockComponent('ActivityIndicator')
export const TouchableOpacity = createMockComponent('TouchableOpacity')
export const TouchableHighlight = createMockComponent('TouchableHighlight')
export const TouchableWithoutFeedback = createMockComponent('TouchableWithoutFeedback')
export const Switch = createMockComponent('Switch')
export const StatusBar = createMockComponent('StatusBar')
export const KeyboardAvoidingView = createMockComponent('KeyboardAvoidingView')
export const RefreshControl = createMockComponent('RefreshControl')
export const SectionList = createMockComponent('SectionList')

// Pressable needs onPress / disabled support
export const Pressable = React.forwardRef((props: any, ref: any) => {
  const { children, testID, onPress, disabled, ...rest } = props
  return React.createElement(
    'Pressable',
    {
      ...rest,
      testID,
      'data-testid': testID,
      onClick: disabled ? undefined : onPress,
      disabled,
      onPress,
      ref,
    },
    typeof children === 'function' ? children({ pressed: false }) : children
  )
})
;(Pressable as any).displayName = 'Pressable'

// Modal
export const Modal = React.forwardRef((props: any, ref: any) => {
  const { children, visible, testID, onRequestClose, ...rest } = props
  if (!visible) return null
  return React.createElement(
    'Modal',
    { ...rest, testID, 'data-testid': testID, visible, onRequestClose, ref },
    children
  )
})
;(Modal as any).displayName = 'Modal'

// FlatList — simplified: just render items in a ScrollView-like wrapper
export const FlatList = React.forwardRef((props: any, ref: any) => {
  const { data, renderItem, keyExtractor, testID, ListHeaderComponent, ListFooterComponent, ListEmptyComponent, ...rest } = props
  const items = data?.map((item: any, index: number) => {
    const key = keyExtractor ? keyExtractor(item, index) : String(index)
    return React.createElement(React.Fragment, { key }, renderItem({ item, index, separators: {} }))
  }) ?? []

  const children = [
    ListHeaderComponent ? React.createElement(React.Fragment, { key: '__header' }, typeof ListHeaderComponent === 'function' ? React.createElement(ListHeaderComponent) : ListHeaderComponent) : null,
    ...(items.length === 0 && ListEmptyComponent
      ? [React.createElement(React.Fragment, { key: '__empty' }, typeof ListEmptyComponent === 'function' ? React.createElement(ListEmptyComponent) : ListEmptyComponent)]
      : items),
    ListFooterComponent ? React.createElement(React.Fragment, { key: '__footer' }, typeof ListFooterComponent === 'function' ? React.createElement(ListFooterComponent) : ListFooterComponent) : null,
  ].filter(Boolean)

  return React.createElement('FlatList', { ...rest, testID, 'data-testid': testID, ref }, ...children)
})
;(FlatList as any).displayName = 'FlatList'

// ---------------------------------------------------------------------------
// StyleSheet
// ---------------------------------------------------------------------------
const absoluteFillValue = {
  position: 'absolute' as const,
  left: 0,
  right: 0,
  top: 0,
  bottom: 0,
}

export const StyleSheet = {
  create: <T extends Record<string, any>>(styles: T): T => styles,
  flatten: (style: any): any => {
    if (Array.isArray(style)) {
      return Object.assign({}, ...style.filter(Boolean).map((s: any) => StyleSheet.flatten(s)))
    }
    return style ?? {}
  },
  absoluteFill: absoluteFillValue,
  absoluteFillObject: absoluteFillValue,
  hairlineWidth: 1,
  compose: (a: any, b: any) => [a, b],
}

// ---------------------------------------------------------------------------
// Dimensions
// ---------------------------------------------------------------------------
const dimensionsValues = { width: 375, height: 812, scale: 2, fontScale: 1 }
export const Dimensions = {
  get: (_dim?: string) => dimensionsValues,
  addEventListener: () => ({ remove: () => {} }),
  set: () => {},
}

// ---------------------------------------------------------------------------
// useWindowDimensions
// ---------------------------------------------------------------------------
export function useWindowDimensions() {
  return dimensionsValues
}

// ---------------------------------------------------------------------------
// Platform
// ---------------------------------------------------------------------------
export const Platform = {
  OS: 'ios' as const,
  Version: 18,
  isPad: false,
  isTVOS: false,
  isTV: false,
  select: (obj: any) => obj.ios ?? obj.default,
  constants: {
    reactNativeVersion: { major: 0, minor: 81, patch: 5 },
  },
}

// ---------------------------------------------------------------------------
// Alert
// ---------------------------------------------------------------------------
export const Alert = {
  alert: (() => {}) as any,
}

// ---------------------------------------------------------------------------
// Animated
// ---------------------------------------------------------------------------
class AnimatedValue {
  _value: number
  _listeners: Map<string, Function> = new Map()
  constructor(value: number = 0) {
    this._value = value
  }
  setValue(value: number) {
    this._value = value
  }
  setOffset(_offset: number) {}
  flattenOffset() {}
  extractOffset() {}
  addListener(cb: Function) {
    const id = String(Math.random())
    this._listeners.set(id, cb)
    return id
  }
  removeListener(id: string) {
    this._listeners.delete(id)
  }
  removeAllListeners() {
    this._listeners.clear()
  }
  stopAnimation(cb?: Function) {
    cb?.(this._value)
  }
  resetAnimation(cb?: Function) {
    cb?.(this._value)
  }
  interpolate(config: any) {
    return {
      ...config,
      __isAnimatedInterpolation: true,
      interpolate: (c: any) => ({ ...c, __isAnimatedInterpolation: true }),
    }
  }
  // Arithmetic methods for combined animations
  __getValue() { return this._value }
}

class AnimatedValueXY {
  x: AnimatedValue
  y: AnimatedValue
  constructor(value?: { x?: number; y?: number }) {
    this.x = new AnimatedValue(value?.x ?? 0)
    this.y = new AnimatedValue(value?.y ?? 0)
  }
  setValue(value: { x: number; y: number }) {
    this.x.setValue(value.x)
    this.y.setValue(value.y)
  }
  setOffset(offset: { x: number; y: number }) {
    this.x.setOffset(offset.x)
    this.y.setOffset(offset.y)
  }
  flattenOffset() {
    this.x.flattenOffset()
    this.y.flattenOffset()
  }
  extractOffset() {
    this.x.extractOffset()
    this.y.extractOffset()
  }
  stopAnimation(cb?: Function) {
    this.x.stopAnimation()
    this.y.stopAnimation()
    cb?.({ x: this.x._value, y: this.y._value })
  }
  addListener() { return '' }
  removeListener() {}
  removeAllListeners() {}
  getLayout() {
    return { left: this.x, top: this.y }
  }
  getTranslateTransform() {
    return [{ translateX: this.x }, { translateY: this.y }]
  }
}

const mockAnimationResult = { start: (cb?: Function) => cb?.({ finished: true }), stop: () => {}, reset: () => {} }

export const Animated = {
  Value: AnimatedValue,
  ValueXY: AnimatedValueXY,
  View: createMockComponent('Animated.View'),
  Text: createMockComponent('Animated.Text'),
  Image: createMockComponent('Animated.Image'),
  ScrollView: createMockComponent('Animated.ScrollView'),
  FlatList: createMockComponent('Animated.FlatList'),
  SectionList: createMockComponent('Animated.SectionList'),
  createAnimatedComponent: (comp: any) => comp,
  timing: (_value: any, _config: any) => mockAnimationResult,
  spring: (_value: any, _config: any) => mockAnimationResult,
  decay: (_value: any, _config: any) => mockAnimationResult,
  parallel: (_animations: any[]) => mockAnimationResult,
  sequence: (_animations: any[]) => mockAnimationResult,
  stagger: (_delay: number, _animations: any[]) => mockAnimationResult,
  delay: (_time: number) => mockAnimationResult,
  loop: (_animation: any, _config?: any) => mockAnimationResult,
  event: (_argMapping: any[], _config?: any) => () => {},
  add: (a: any, b: any) => a,
  subtract: (a: any, b: any) => a,
  divide: (a: any, b: any) => a,
  multiply: (a: any, b: any) => a,
  diffClamp: (a: any, _min: number, _max: number) => a,
}

// ---------------------------------------------------------------------------
// Easing
// ---------------------------------------------------------------------------
export const Easing = {
  linear: (t: number) => t,
  ease: (t: number) => t,
  quad: (t: number) => t * t,
  cubic: (t: number) => t * t * t,
  poly: (_n: number) => (t: number) => t,
  sin: (t: number) => t,
  circle: (t: number) => t,
  exp: (t: number) => t,
  elastic: (_bounciness?: number) => (t: number) => t,
  back: (_s?: number) => (t: number) => t,
  bounce: (t: number) => t,
  bezier: (_x1: number, _y1: number, _x2: number, _y2: number) => (t: number) => t,
  in: (fn: Function) => fn,
  out: (fn: Function) => fn,
  inOut: (fn: Function) => fn,
  step0: (t: number) => t,
  step1: (t: number) => t,
}

// ---------------------------------------------------------------------------
// PixelRatio
// ---------------------------------------------------------------------------
export const PixelRatio = {
  get: () => 2,
  getFontScale: () => 1,
  getPixelSizeForLayoutSize: (size: number) => size * 2,
  roundToNearestPixel: (size: number) => Math.round(size * 2) / 2,
}

// ---------------------------------------------------------------------------
// AppState
// ---------------------------------------------------------------------------
export const AppState = {
  currentState: 'active',
  addEventListener: () => ({ remove: () => {} }),
  removeEventListener: () => {},
}

// ---------------------------------------------------------------------------
// Keyboard
// ---------------------------------------------------------------------------
export const Keyboard = {
  addListener: () => ({ remove: () => {} }),
  removeListener: () => {},
  dismiss: () => {},
  isVisible: () => false,
  metrics: () => undefined,
}

// ---------------------------------------------------------------------------
// Linking
// ---------------------------------------------------------------------------
export const Linking = {
  openURL: async () => {},
  canOpenURL: async () => true,
  getInitialURL: async () => null,
  addEventListener: () => ({ remove: () => {} }),
}

// ---------------------------------------------------------------------------
// BackHandler
// ---------------------------------------------------------------------------
export const BackHandler = {
  addEventListener: () => ({ remove: () => {} }),
  removeEventListener: () => {},
  exitApp: () => {},
}

// ---------------------------------------------------------------------------
// Appearance
// ---------------------------------------------------------------------------
export const Appearance = {
  getColorScheme: () => 'dark',
  addChangeListener: () => ({ remove: () => {} }),
  setColorScheme: () => {},
}

// ---------------------------------------------------------------------------
// PlatformColor (no-op stub)
// ---------------------------------------------------------------------------
export function PlatformColor(..._args: string[]) {
  return ''
}

// ---------------------------------------------------------------------------
// NativeModules
// ---------------------------------------------------------------------------
export const NativeModules = {}

// ---------------------------------------------------------------------------
// AccessibilityInfo
// ---------------------------------------------------------------------------
export const AccessibilityInfo = {
  isScreenReaderEnabled: async () => false,
  addEventListener: () => ({ remove: () => {} }),
  setAccessibilityFocus: () => {},
  announceForAccessibility: () => {},
  isReduceMotionEnabled: async () => false,
  isBoldTextEnabled: async () => false,
  isGrayscaleEnabled: async () => false,
  isInvertColorsEnabled: async () => false,
  prefersCrossFadeTransitions: async () => false,
}

// ---------------------------------------------------------------------------
// I18nManager
// ---------------------------------------------------------------------------
export const I18nManager = {
  isRTL: false,
  doLeftAndRightSwapInRTL: true,
  allowRTL: () => {},
  forceRTL: () => {},
  swapLeftAndRightInRTL: () => {},
}

// ---------------------------------------------------------------------------
// LayoutAnimation
// ---------------------------------------------------------------------------
export const LayoutAnimation = {
  configureNext: () => {},
  create: () => ({}),
  Types: { spring: 'spring', linear: 'linear', easeInEaseOut: 'easeInEaseOut', easeIn: 'easeIn', easeOut: 'easeOut' },
  Properties: { opacity: 'opacity', scaleX: 'scaleX', scaleY: 'scaleY', scaleXY: 'scaleXY' },
  Presets: {
    easeInEaseOut: {},
    linear: {},
    spring: {},
  },
}

// ---------------------------------------------------------------------------
// useColorScheme
// ---------------------------------------------------------------------------
export function useColorScheme() {
  return 'dark'
}

// ---------------------------------------------------------------------------
// Default export (some code does `import RN from 'react-native'`)
// ---------------------------------------------------------------------------
const RN = {
  View,
  Text,
  TextInput,
  Image,
  ImageBackground,
  ScrollView,
  FlatList,
  SectionList,
  SafeAreaView,
  ActivityIndicator,
  TouchableOpacity,
  TouchableHighlight,
  TouchableWithoutFeedback,
  Pressable,
  Modal,
  Switch,
  StatusBar,
  KeyboardAvoidingView,
  RefreshControl,
  StyleSheet,
  Dimensions,
  Platform,
  Alert,
  Animated,
  Easing,
  PixelRatio,
  AppState,
  Keyboard,
  Linking,
  BackHandler,
  Appearance,
  PlatformColor,
  NativeModules,
  AccessibilityInfo,
  I18nManager,
  LayoutAnimation,
  useColorScheme,
  useWindowDimensions,
}

export default RN
