/**
 * Route-calculating loader — shown in RoutePreview while computeRoute() is in
 * flight (or before the first result lands). An indeterminate signal-blue
 * segment sweeps along a track, plus a live label. Uses the native driver so
 * it stays smooth even while the route request resolves on the JS thread.
 */
import React, { useEffect, useRef, useState } from "react";
import { Animated, Easing, StyleSheet, Text, View } from "react-native";
import { radius, spacing, theme, typeScale } from "../../theme";

const SEGMENT_FRACTION = 0.4; // sweeping bar is 40% of the track
const SWEEP_MS = 1150;

export function RouteCalculating(): React.JSX.Element {
  const sweep = useRef(new Animated.Value(0)).current;
  const [trackWidth, setTrackWidth] = useState(0);

  useEffect(() => {
    const loop = Animated.loop(
      Animated.timing(sweep, {
        toValue: 1,
        duration: SWEEP_MS,
        easing: Easing.inOut(Easing.cubic),
        useNativeDriver: true,
      })
    );
    loop.start();
    return () => loop.stop();
  }, [sweep]);

  const segmentWidth = trackWidth * SEGMENT_FRACTION;
  const translateX = sweep.interpolate({
    inputRange: [0, 1],
    outputRange: [-segmentWidth, trackWidth],
  });

  return (
    <View style={styles.wrap} testID="route-calculating">
      <Text style={styles.label}>Calculating route…</Text>
      <View
        style={styles.track}
        onLayout={(e) => setTrackWidth(e.nativeEvent.layout.width)}
      >
        {trackWidth > 0 && (
          <Animated.View
            style={[styles.segment, { width: segmentWidth, transform: [{ translateX }] }]}
          />
        )}
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  wrap: {
    paddingVertical: spacing[4],
    gap: spacing[3],
  },
  label: {
    fontSize: typeScale.body.fontSize,
    fontWeight: "600",
    color: theme.textPrimary,
  },
  track: {
    height: 6,
    borderRadius: radius.pill,
    backgroundColor: theme.surfaceAlt,
    overflow: "hidden",
  },
  segment: {
    height: "100%",
    borderRadius: radius.pill,
    backgroundColor: theme.signal,
  },
});
