use thiserror::Error;

pub type Result<T> = std::result::Result<T, AnimationError>;

#[derive(Debug, Error)]
pub enum AnimationError {
    // Skeleton errors
    #[error("Skeleton topology invalid: parent index {parent} >= child index {child}")]
    InvalidTopology { parent: usize, child: usize },

    #[error("Skeleton has no bones")]
    EmptySkeleton,

    #[error("Bone index {0} out of bounds (skeleton has {1} bones)")]
    BoneIndexOutOfBounds(usize, usize),

    // Animation clip errors
    #[error("Animation clip duration must be positive, got {0}")]
    InvalidDuration(f32),

    #[error("No keyframes provided for bone '{0}'")]
    NoKeyframes(String),

    #[error("Keyframes not sorted by time for bone '{0}'")]
    UnsortedKeyframes(String),

    // Asset loading errors
    #[error("Failed to load asset from '{path}': {source}")]
    AssetLoadError {
        path: String,
        source: Box<dyn std::error::Error + Send + Sync>,
    },

    #[error("Invalid asset format: {0}")]
    InvalidFormat(String),

    // Runtime errors
    #[error("Bone '{bone}' not found in skeleton")]
    BoneNotFound { bone: String },

    #[error("Animation clip handle invalid or expired")]
    InvalidClipHandle,

    #[error("Skeleton handle invalid or expired")]
    InvalidSkeletonHandle,

    #[error("Renderer error: {0}")]
    RendererError(String),
}
