use anymotion::ecs::{AnimationClipAssets, SkeletonAssets};
use anymotion::error::Result as AnimationResult;
use anymotion::prelude::*;
use archetype_ecs::*;

#[test]
fn test_animation_sampling_integration() {
    let mut world = World::new();

    // 1. Setup Assets
    let mut skeleton_assets = SkeletonAssets::new();
    let mut clip_assets = AnimationClipAssets::new();

    let skeleton = create_test_skeleton();
    let skeleton_handle = skeleton_assets.add(skeleton.clone());

    let clip = create_test_walk_clip().unwrap();
    let clip_handle = clip_assets.add(clip);

    world.insert_resource(skeleton_assets);
    world.insert_resource(clip_assets);

    // 2. Spawn entities
    let animator_entity = world.spawn((
        Animator::new(skeleton_handle, clip_handle),
        Transform::default(),
    ));

    // Spawn bone entities
    let mut bone_entities = Vec::new();
    for i in 0..skeleton.bones.len() {
        let bone_entity = world.spawn((
            BoneJoint {
                bone_index: i,
                skeleton: skeleton_handle,
            },
            Transform::default(),
        ));
        bone_entities.push(bone_entity);
    }

    // 3. Run sampling system
    // Simulate 0.5s playback (Hips should bob up to 0.1)
    animation_sampling_system(&mut world, 0.5);

    // 4. Verify results
    // Find Hips bone (index 1 in create_test_skeleton)
    let hips_entity = bone_entities[1];
    let hips_transform = world.get_component::<Transform>(hips_entity).unwrap();

    assert!(hips_transform.position.y > 0.05); // Should be around 0.1

    // Verify animator time updated
    let animator = world.get_component::<Animator>(animator_entity).unwrap();
    assert_eq!(animator.player.time, 0.5);
}

// Helper functions (copied or imported if public)
fn create_test_skeleton() -> Skeleton {
    let mut skeleton = Skeleton::new();
    skeleton.add_bone("Root".to_string(), None, glam::Mat4::IDENTITY);
    skeleton.add_bone("Hips".to_string(), Some(0), glam::Mat4::IDENTITY);
    skeleton
}

fn create_test_walk_clip() -> AnimationResult<AnimationClip> {
    use std::collections::HashMap;
    let mut bone_tracks = HashMap::new();
    let mut hips_track = anymotion::core::TransformTrack::new();
    hips_track.positions = vec![
        anymotion::core::Keyframe {
            time: 0.0,
            value: glam::Vec3::ZERO,
            interpolation: anymotion::core::InterpolationMode::Linear,
        },
        anymotion::core::Keyframe {
            time: 1.0,
            value: glam::Vec3::new(0.0, 0.2, 0.0),
            interpolation: anymotion::core::InterpolationMode::Linear,
        },
    ];
    bone_tracks.insert("Hips".to_string(), hips_track);
    AnimationClip::new("Walk".to_string(), 1.0, bone_tracks)
}
