import { useCallback } from 'react';
import { StyleSheet, Text, View, ViewStyle } from 'react-native';
import { Gesture, GestureDetector, GestureHandlerRootView } from 'react-native-gesture-handler';
import Animated, { runOnJS, useAnimatedStyle, useSharedValue, withSpring } from 'react-native-reanimated';

interface Props {
  onConfirm: () => void;
  label?: string;
  color?: string;
  threshold?: number;
  disabled?: boolean;
  style?: ViewStyle;
}

const TRACK_HEIGHT  = 60;
const HANDLE_SIZE   = 48;
const TRACK_PADDING = 5;

export function SlideToConfirm({
  onConfirm,
  label = 'Slide to confirm',
  color = '#059669',
  threshold = 0.82,
  disabled = false,
  style,
}: Props) {
  const translateX = useSharedValue(0);
  const maxX       = useSharedValue(200); // updated on layout

  const triggerConfirm = useCallback(() => { onConfirm(); }, [onConfirm]);

  const pan = Gesture.Pan()
    .enabled(!disabled)
    .minDistance(0)
    .activeOffsetX([-5, 5])
    .onUpdate((e) => {
      'worklet';
      translateX.value = Math.max(0, Math.min(e.translationX, maxX.value));
    })
    .onEnd(() => {
      'worklet';
      if (translateX.value >= maxX.value * threshold) {
        translateX.value = withSpring(maxX.value, { damping: 20, stiffness: 200, mass: 0.8 });
        runOnJS(triggerConfirm)();
      } else {
        translateX.value = withSpring(0, { damping: 20, stiffness: 200, mass: 0.8 });
      }
    });

  const animatedHandle = useAnimatedStyle(() => ({
    transform: [{ translateX: translateX.value }],
  }));

  const animatedFill = useAnimatedStyle(() => ({
    width: translateX.value + HANDLE_SIZE + TRACK_PADDING,
  }));

  const animatedLabel = useAnimatedStyle(() => ({
    opacity: Math.max(0, 1 - (translateX.value / Math.max(maxX.value * 0.5, 1))),
  }));

  return (
    // GestureHandlerRootView inside Modal is REQUIRED on iOS New Arch
    // Modal creates a new UIWindow — RNGH's gesture manager must be re-rooted here
    <GestureHandlerRootView style={[styles.root, style]}>
      <View
        style={[styles.track, { borderColor: color + '50' }]}
        onLayout={(e) => {
          const w = e.nativeEvent.layout.width;
          maxX.value = w - HANDLE_SIZE - TRACK_PADDING * 2;
        }}
      >
        {/* Colored fill that grows behind the handle */}
        <Animated.View style={[styles.fill, { backgroundColor: color + '28' }, animatedFill]} />

        {/* Label fades as handle moves right */}
        <Animated.Text
          style={[styles.label, { paddingLeft: HANDLE_SIZE + TRACK_PADDING * 3 }, animatedLabel]}
          numberOfLines={1}
        >
          {label}
        </Animated.Text>

        {/* Draggable handle */}
        <GestureDetector gesture={pan}>
          <Animated.View style={[
            styles.handle,
            { backgroundColor: disabled ? '#CBD5E1' : color, width: HANDLE_SIZE, height: HANDLE_SIZE, borderRadius: HANDLE_SIZE / 2, top: (TRACK_HEIGHT - HANDLE_SIZE) / 2, left: TRACK_PADDING },
            animatedHandle,
          ]}>
            <Text style={styles.arrow}>›</Text>
          </Animated.View>
        </GestureDetector>
      </View>
    </GestureHandlerRootView>
  );
}

const styles = StyleSheet.create({
  root:  { width: '100%' },
  track: {
    height: TRACK_HEIGHT, borderRadius: TRACK_HEIGHT / 2,
    backgroundColor: '#F1F5F9', borderWidth: 1.5,
    justifyContent: 'center', alignItems: 'center',
    overflow: 'hidden', position: 'relative',
  },
  fill: {
    position: 'absolute', left: 0, top: 0,
    height: TRACK_HEIGHT, zIndex: 1,
  },
  label: {
    position: 'absolute', zIndex: 2,
    fontSize: 14, fontWeight: '700', color: '#64748B',
    textAlign: 'center', width: '100%', paddingRight: 16,
  },
  handle: {
    position: 'absolute', zIndex: 3,
    justifyContent: 'center', alignItems: 'center',
    shadowColor: '#000', shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.18, shadowRadius: 4, elevation: 4,
  },
  arrow: { fontSize: 26, color: '#fff', fontWeight: '800', marginLeft: 2 },
});
