/**
 * ✔ percent 进度百分比 0-100
 * ✘ show-info 在进度条右侧显示百分比
 * ✘ border-radius 圆角大小
 * ✘ font-size 右侧百分比字体大小
 * ✔ stroke-width 进度条线的宽度
 * ✔ color 进度条颜色（请使用activeColor）
 * ✔ activeColor 已选择的进度条的颜色
 * ✔ backgroundColor 未选择的进度条的颜色
 * ✔ active 进度条从左往右的动画
 * ✔ active-mode backwards: 动画从头播；forwards：动画从上次结束点接着播
 * ✔ duration 进度增加1%所需毫秒数
 * ✔ bindactiveend 动画完成事件
 */
import { useRef, forwardRef, useEffect, useState, createElement } from 'react';
import { View } from 'react-native';
import Animated, { useSharedValue, useAnimatedStyle, withTiming, Easing, runOnJS } from 'react-native-reanimated';
import useInnerProps from './getInnerListeners';
import useNodesRef from './useNodesRef';
import { useLayout, useTransformStyle, extendObject, useRunOnJSCallback } from './utils';
import Portal from './mpx-portal';
const Progress = forwardRef((props, ref) => {
    const { percent = 0, 'stroke-width': strokeWidth = 6, color, activeColor = color || '#09BB07', backgroundColor = '#EBEBEB', active = false, 'active-mode': activeMode = 'backwards', duration = 30, style = {}, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight } = props;
    const nodeRef = useRef(null);
    const propsRef = useRef(props);
    propsRef.current = props;
    // 进度值状态
    const [lastPercent, setLastPercent] = useState(0);
    const progressWidth = useSharedValue(0);
    const { normalStyle, hasSelfPercent, setWidth, setHeight, hasPositionFixed } = useTransformStyle(style, {
        enableVar,
        externalVarContext,
        parentFontSize,
        parentWidth,
        parentHeight
    });
    const { layoutRef, layoutStyle, layoutProps } = useLayout({
        props,
        hasSelfPercent,
        setWidth,
        setHeight,
        nodeRef
    });
    useNodesRef(props, ref, nodeRef, {
        style: normalStyle
    });
    // 使用 useRunOnJSCallback 处理动画回调
    const runOnJSCallbackRef = useRef({
        triggerActiveEnd: (percent) => {
            const currentProps = propsRef.current;
            if (currentProps.bindactiveend) {
                currentProps.bindactiveend({
                    type: 'activeend',
                    detail: {
                        percent: percent
                    }
                });
            }
        }
    });
    const runOnJSCallback = useRunOnJSCallback(runOnJSCallbackRef);
    // 进度条动画函数
    const startProgressAnimation = (targetPercent, startPercent, animationDuration, onFinished) => {
        // 根据 active-mode 设置起始位置
        progressWidth.value = startPercent;
        progressWidth.value = withTiming(targetPercent, {
            duration: animationDuration,
            easing: Easing.linear
        }, (finished) => {
            if (finished && onFinished) {
                // 在动画回调中，执行传入的worklet函数
                onFinished();
            }
        });
    };
    // 进度变化时的动画效果
    useEffect(() => {
        const targetPercent = Math.max(0, Math.min(100, percent));
        if (active) {
            // 根据 active-mode 确定起始位置
            let startPercent;
            if (activeMode === 'backwards') {
                startPercent = 0;
            }
            else {
                // forwards 模式：使用上次记录的百分比作为起始位置
                startPercent = lastPercent;
            }
            // 计算动画持续时间
            const percentDiff = Math.abs(targetPercent - startPercent);
            const animationDuration = percentDiff * duration;
            // 执行动画
            startProgressAnimation(targetPercent, startPercent, animationDuration, () => {
                'worklet';
                // 在worklet函数内部执行runOnJS调用runOnJSCallback
                runOnJS(runOnJSCallback)('triggerActiveEnd', targetPercent);
            });
        }
        else {
            progressWidth.value = targetPercent;
        }
        setLastPercent(targetPercent);
    }, [percent, active, activeMode, duration]);
    // 初始化时设置进度值
    useEffect(() => {
        if (!active) {
            progressWidth.value = Math.max(0, Math.min(100, percent));
        }
    }, []);
    // 进度条动画样式
    const animatedProgressStyle = useAnimatedStyle(() => {
        return {
            width: `${progressWidth.value}%`
        };
    });
    // 确保数值类型正确
    const strokeWidthNum = typeof strokeWidth === 'number' ? strokeWidth : parseInt(strokeWidth, 10) || 6;
    // 容器样式
    const containerStyle = extendObject({}, {
        flexDirection: 'row',
        alignItems: 'center',
        width: '100%',
        minHeight: Math.max(strokeWidthNum, 20)
    }, normalStyle, layoutStyle);
    // 进度条背景样式
    const progressBgStyle = {
        width: '100%',
        height: strokeWidthNum,
        backgroundColor,
        overflow: 'hidden'
    };
    // 进度条填充样式
    const progressFillStyle = {
        height: '100%',
        backgroundColor: activeColor
    };
    const innerProps = useInnerProps(extendObject({}, props, layoutProps, {
        ref: nodeRef
    }), [
        'percent',
        'stroke-width',
        'color',
        'activeColor',
        'backgroundColor',
        'active',
        'active-mode',
        'duration',
        'bindactiveend'
    ], { layoutRef });
    const progressComponent = createElement(View, extendObject({}, innerProps, { style: containerStyle }), 
    // 进度条背景
    createElement(View, { style: progressBgStyle }, 
    // 进度条填充
    createElement(Animated.View, {
        style: [progressFillStyle, animatedProgressStyle]
    })));
    if (hasPositionFixed) {
        return createElement(Portal, null, progressComponent);
    }
    return progressComponent;
});
Progress.displayName = 'MpxProgress';
export default Progress;
