import React, { memo, useEffect, useMemo, useRef, useState } from 'react';
import { Animated, Easing, LayoutChangeEvent, StyleSheet, Text, View, ViewStyle } from 'react-native';

type ProgressBarProps = {
  progress: number; // 0 - 1
  height?: number;
  style?: ViewStyle;
  trackColor?: string;
  fillColor?: string;
  animated?: boolean;
  showLabel?: boolean;
};

function ProgressBarImpl({
  progress,
  height = 18,
  style,
  trackColor = '#EDEDED',
  fillColor = '#BBF246',
  animated = true,
  showLabel = true,
}: ProgressBarProps) {
  const [trackWidth, setTrackWidth] = useState(0);
  const animatedValue = useRef(new Animated.Value(0)).current;

  const clamped = useMemo(() => {
    if (Number.isNaN(progress)) return 0;
    return Math.min(1, Math.max(0, progress));
  }, [progress]);

  useEffect(() => {
    if (!animated) {
      animatedValue.setValue(clamped);
      return;
    }
    Animated.timing(animatedValue, {
      toValue: clamped,
      duration: 650,
      easing: Easing.out(Easing.cubic),
      useNativeDriver: false,
    }).start();
  }, [clamped, animated, animatedValue]);

  const lastWidthRef = useRef<number>(0);
  const onLayout = (e: LayoutChangeEvent) => {
    const w = e.nativeEvent.layout.width || 0;
    // 仅在宽度发生明显变化时才更新，避免渲染-布局循环
    const next = Math.round(w);
    if (next > 0 && next !== lastWidthRef.current) {
      lastWidthRef.current = next;
      setTrackWidth(next);
    }
  };

  const fillWidth = Animated.multiply(animatedValue, trackWidth || 1);
  const percent = Math.round(clamped * 100);

  return (
    <View style={[styles.container, { height }, style]} onLayout={onLayout}>
      <View style={[styles.track, { backgroundColor: trackColor }]} />
      <Animated.View style={[styles.fill, { width: fillWidth, backgroundColor: fillColor }]}>
        {showLabel && (
          <Text style={styles.label}>{percent}%</Text>
        )}
      </Animated.View>
    </View>
  );
}

export const ProgressBar = memo(ProgressBarImpl, (prev, next) => {
  // 仅在这些关键属性变化时重新渲染，忽略 style 的引用变化
  return (
    prev.progress === next.progress &&
    prev.height === next.height &&
    prev.trackColor === next.trackColor &&
    prev.fillColor === next.fillColor &&
    prev.animated === next.animated &&
    prev.showLabel === next.showLabel
  );
});

const styles = StyleSheet.create({
  container: {
    width: '100%',
    borderRadius: 10,
    overflow: 'hidden',
    backgroundColor: 'transparent',
  },
  track: {
    ...StyleSheet.absoluteFillObject,
    borderRadius: 10,
  },
  fill: {
    height: '100%',
    borderRadius: 10,
    justifyContent: 'center',
    paddingHorizontal: 10,
  },
  label: {
    color: '#192126',
    fontWeight: '700',
    fontSize: 12,
  },
});


