import { useEffect } from 'react'
import { StyleSheet, Text, View } from 'react-native'
import { Gesture, GestureDetector } from 'react-native-gesture-handler'
import Animated, {
  cancelAnimation,
  runOnJS,
  useAnimatedStyle,
  useSharedValue,
  withRepeat,
  withSequence,
  withSpring,
  withTiming,
  type SharedValue,
} from 'react-native-reanimated'
import { Ionicons } from '@expo/vector-icons'
import type { Marker } from '@repo/types'
import type { MapSize } from './FloorMap'

const ICON_SIZE = 20
const BADGE_OFFSET = -5
const RING_SIZE = 38

interface MapMarkerProps {
  marker: Marker
  mapSize: MapSize
  mapScale: SharedValue<number>
  itemCount?: number
  isSelected?: boolean
  onPress: () => void
  onDragEnd: (x: number, y: number) => void
}

export function MapMarker({ marker, mapSize, mapScale, itemCount = 0, isSelected = false, onPress, onDragEnd }: MapMarkerProps) {
  const left = marker.x * mapSize.width - ICON_SIZE / 2
  const top = marker.y * mapSize.height - ICON_SIZE

  // 拖动状态
  const offsetX = useSharedValue(0)
  const offsetY = useSharedValue(0)
  const dragScale = useSharedValue(1)
  const isDragging = useSharedValue(false)

  // 对焦脉冲动画
  const pulseScale = useSharedValue(1)
  const pulseOpacity = useSharedValue(0)

  useEffect(() => {
    if (isSelected) {
      // 每次选中从初始状态重新开始脉冲
      pulseScale.value = withRepeat(
        withSequence(
          withTiming(1, { duration: 0 }),
          withTiming(2.4, { duration: 1100 }),
        ),
        -1,
        false,
      )
      pulseOpacity.value = withRepeat(
        withSequence(
          withTiming(0.7, { duration: 0 }),
          withTiming(0, { duration: 1100 }),
        ),
        -1,
        false,
      )
    } else {
      cancelAnimation(pulseScale)
      cancelAnimation(pulseOpacity)
      pulseOpacity.value = withTiming(0, { duration: 150 })
    }
  }, [isSelected])

  const tap = Gesture.Tap().onEnd(() => {
    runOnJS(onPress)()
  })

  const pan = Gesture.Pan()
    .activateAfterLongPress(400)
    .onStart(() => {
      dragScale.value = withSpring(1.3)
      isDragging.value = true
    })
    .onUpdate((e) => {
      offsetX.value = e.translationX
      offsetY.value = e.translationY
    })
    .onEnd((e) => {
      const s = mapScale.value
      const newX = Math.max(0, Math.min(1, marker.x + e.translationX / (mapSize.width * s)))
      const newY = Math.max(0, Math.min(1, marker.y + e.translationY / (mapSize.height * s)))
      runOnJS(onDragEnd)(newX, newY)
    })
    .onFinalize(() => {
      dragScale.value = withSpring(1)
      isDragging.value = false
      offsetX.value = 0
      offsetY.value = 0
    })

  const gesture = Gesture.Race(tap, pan)

  const containerStyle = useAnimatedStyle(() => ({
    transform: [
      { translateX: offsetX.value },
      { translateY: offsetY.value },
      { scale: dragScale.value / mapScale.value },
    ],
    zIndex: isDragging.value ? 999 : isSelected ? 10 : 1,
    shadowColor: '#000',
    shadowOpacity: isDragging.value ? 0.3 : 0,
    shadowRadius: isDragging.value ? 8 : 0,
    shadowOffset: { width: 0, height: 4 },
    elevation: isDragging.value ? 8 : 0,
  }))

  const pulseStyle = useAnimatedStyle(() => ({
    transform: [{ scale: pulseScale.value }],
    opacity: pulseOpacity.value,
  }))

  const markerColor = marker.color ?? '#3B82F6'

  return (
    <GestureDetector gesture={gesture}>
      <Animated.View style={[styles.container, { left, top }, containerStyle]}>
        {/* 脉冲光环（选中时持续扩散） */}
        <Animated.View
          style={[
            styles.pulseRing,
            { borderColor: markerColor },
            pulseStyle,
          ]}
        />

        <Ionicons name="location" size={ICON_SIZE} color={markerColor} />

        {itemCount > 0 && (
          <View style={styles.badge}>
            <Text style={styles.badgeText}>{itemCount}</Text>
          </View>
        )}
      </Animated.View>
    </GestureDetector>
  )
}

const RING_OFFSET = -(RING_SIZE - ICON_SIZE) / 2  // 居中到图标中心

const styles = StyleSheet.create({
  container: {
    position: 'absolute',
  },
  pulseRing: {
    position: 'absolute',
    width: RING_SIZE,
    height: RING_SIZE,
    borderRadius: RING_SIZE / 2,
    borderWidth: 2,
    top: RING_OFFSET,
    left: RING_OFFSET,
  },
  badge: {
    position: 'absolute',
    top: BADGE_OFFSET,
    right: BADGE_OFFSET,
    minWidth: 12,
    height: 12,
    borderRadius: 6,
    backgroundColor: '#EF4444',
    alignItems: 'center',
    justifyContent: 'center',
    paddingHorizontal: 2,
  },
  badgeText: {
    color: '#fff',
    fontSize: 8,
    fontWeight: '700',
  },
})
