/**
 * SlideToConfirm — No RNGH dependency.
 * Uses Reanimated useSharedValue (JSI-direct, sets on UI thread immediately)
 * + onTouchStart/Move/End on the handle for gesture capture.
 */
import { useRef } from 'react';
import { StyleSheet, Text, View, ViewStyle } from 'react-native';
import Animated, {
  runOnJS,
  useAnimatedStyle,
  useSharedValue,
  withSpring,
} from 'react-native-reanimated';

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

const HANDLE_SIZE = 56;
const THRESHOLD   = 0.80; // 80% of track

export function SlideToConfirm({ onConfirm, label = 'Slide to confirm', disabled = false, style }: Props) {
  const trackWidth   = useRef(0);
  const startX       = useRef(0);
  const confirmed    = useRef(false);
  const translateX   = useSharedValue(0);

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

  const labelStyle = useAnimatedStyle(() => {
    const maxX  = Math.max(trackWidth.current - HANDLE_SIZE, 1);
    const ratio = translateX.value / maxX;
    return { opacity: 1 - ratio * 1.5 };
  });

  const onTouchStart = (e: any) => {
    if (disabled) return;
    confirmed.current = false;
    startX.current = e.nativeEvent.pageX - translateX.value;
  };

  const onTouchMove = (e: any) => {
    if (disabled) return;
    const maxX  = Math.max(trackWidth.current - HANDLE_SIZE, 1);
    const raw   = e.nativeEvent.pageX - startX.current;
    const clamped = Math.min(Math.max(raw, 0), maxX);
    translateX.value = clamped;

    if (!confirmed.current && clamped / maxX >= THRESHOLD) {
      confirmed.current = true;
      translateX.value = withSpring(maxX, { damping: 18, stiffness: 220 });
      runOnJS(onConfirm)();
    }
  };

  const onTouchEnd = () => {
    if (disabled || confirmed.current) return;
    translateX.value = withSpring(0, { damping: 18, stiffness: 220 });
  };

  return (
    <View
      style={[styles.track, disabled && styles.trackDisabled, style]}
      onLayout={e => { trackWidth.current = e.nativeEvent.layout.width; }}
    >
      {/* Label fades as handle moves right */}
      <Animated.View style={[StyleSheet.absoluteFill, styles.labelWrap, labelStyle]} pointerEvents="none">
        <Text style={styles.label}>{label}</Text>
      </Animated.View>

      {/* Sliding handle */}
      <Animated.View
        style={[styles.handle, disabled && styles.handleDisabled, handleStyle]}
        onTouchStart={onTouchStart}
        onTouchMove={onTouchMove}
        onTouchEnd={onTouchEnd}
        onTouchCancel={onTouchEnd}
      >
        <Text style={styles.arrow}>›</Text>
      </Animated.View>
    </View>
  );
}

const styles = StyleSheet.create({
  track: {
    height: 60,
    backgroundColor: '#0E7490',
    borderRadius: 30,
    justifyContent: 'center',
    overflow: 'hidden',
  },
  trackDisabled: {
    backgroundColor: '#94A3B8',
  },
  labelWrap: {
    alignItems: 'center',
    justifyContent: 'center',
  },
  label: {
    color: 'rgba(255,255,255,0.85)',
    fontSize: 15,
    fontWeight: '600',
    letterSpacing: 0.3,
  },
  handle: {
    width: HANDLE_SIZE,
    height: HANDLE_SIZE,
    borderRadius: HANDLE_SIZE / 2,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
    marginLeft: 3,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.18,
    shadowRadius: 4,
    elevation: 4,
  },
  handleDisabled: {
    backgroundColor: '#E2E8F0',
  },
  arrow: {
    fontSize: 28,
    color: '#0891B2',
    fontWeight: '800',
    lineHeight: 32,
  },
});
