import { MotionStyle } from "../../motion/types"
import { motionValue } from "../../value"
import { isMotionValue } from "../../value/utils/is-motion-value"
import { VisualElement } from "../types"

export function updateMotionValuesFromProps(
    element: VisualElement,
    next: MotionStyle,
    prev: MotionStyle
) {
    for (const key in next) {
        const nextValue = next[key]
        const prevValue = prev[key]

        if (isMotionValue(nextValue)) {
            /**
             * If this is a motion value found in props or style, we want to add it
             * to our visual element's motion value map.
             */
            element.addValue(key, nextValue)
        } else if (isMotionValue(prevValue)) {
            /**
             * If we're swapping to a new motion value, create a new motion value
             * from that
             */
            element.addValue(key, motionValue(nextValue))
        } else if (prevValue !== nextValue) {
            /**
             * If this is a flat value that has changed, update the motion value
             * or create one if it doesn't exist. We only want to do this if we're
             * not handling the value with our animation state.
             */
            if (element.hasValue(key)) {
                const existingValue = element.getValue(key)!
                // TODO: Only update values that aren't being animated or even looked at
                !existingValue.hasAnimated && existingValue.set(nextValue)
            } else {
                element.addValue(
                    key,
                    motionValue(element.getStaticValue(key) ?? nextValue)
                )
            }
        }
    }

    // Handle removed values
    for (const key in prev) {
        if (next[key] === undefined) element.removeValue(key)
    }

    return next
}
