use sunocore::models::feed::FeedResponse;

#[test]
fn deserialize_feed_v3_example() {
    let data = include_str!("data/feed_example.json");
    let feed: FeedResponse = serde_json::from_str(data).expect("valid FeedResponse json");

    assert_eq!(feed.clips.len(), 2);
    assert_eq!(feed.has_more, Some(false));
    assert!(feed.num_total_results.is_none());

    // Check first clip
    let clip1 = &feed.clips[0];
    assert_eq!(clip1.status, "complete");
    assert_eq!(clip1.play_count, 1);
    assert_eq!(clip1.id.to_string(), "140239c1-6d65-474f-b692-78f08f118526");
    assert_eq!(clip1.entity_type, "song_schema");
    assert_eq!(clip1.major_model_version, "v5");
    assert_eq!(clip1.model_name, "chirp-crow");
    assert_eq!(clip1.metadata.duration, 179.64);
    assert_eq!(
        clip1.metadata.negative_tags,
        Some("screamo, metal, aggressive".to_string())
    );
    assert_eq!(clip1.metadata.has_vocal, Some(true));
    assert_eq!(clip1.metadata.can_publish_with_vocal, Some(false));
    assert!(clip1.metadata.control_sliders.is_some());
    assert_eq!(clip1.display_name, "neil746");
    assert!(clip1.project.is_some());
    assert_eq!(
        clip1.project.as_ref().unwrap().name,
        "Spontaneous Song Prompt"
    );
    assert!(clip1.reaction.is_some());
    assert!(clip1.ownership.is_some());
    assert_eq!(clip1.explicit, Some(false));
    assert_eq!(
        clip1.display_tags,
        Some("avant-garde folk, synth, sound collage".to_string())
    );
    assert!(!clip1.is_contest_clip);
    assert!(!clip1.has_hook);

    // Check second clip with BPM and key
    let clip2 = &feed.clips[1];
    assert_eq!(clip2.play_count, 2);
    assert_eq!(clip2.id.to_string(), "68351f62-8172-41dd-a034-6c7b9c729602");
    assert_eq!(clip2.metadata.duration, 172.96);
    assert_eq!(clip2.metadata.negative_tags, None);
    assert_eq!(clip2.metadata.has_vocal, None);
    assert_eq!(clip2.metadata.can_publish_with_vocal, None);
    assert!(clip2.metadata.max_bpm.is_some());
    assert_eq!(clip2.metadata.max_bpm.unwrap(), 103.45);
    assert_eq!(clip2.metadata.min_bpm.unwrap(), 88.24);
    assert_eq!(clip2.metadata.avg_bpm.unwrap(), 96.16);
    assert_eq!(clip2.metadata.key, Some("Ab_minor".to_string()));

    // Check model badges
    assert!(clip1.metadata.model_badges.is_some());
    let badges = clip1.metadata.model_badges.as_ref().unwrap();
    assert!(badges.songcard.is_some());
    assert_eq!(badges.songrow.display_name, "v5");
}

#[test]
fn deserialize_feed_v2_example() {
    let data = include_str!("data/feed_v2_example.json");
    let feed: FeedResponse = serde_json::from_str(data).expect("valid FeedResponse json");

    assert_eq!(feed.clips.len(), 1);
    assert!(feed.has_more.is_none());
    assert_eq!(feed.num_total_results, Some(42));

    // Check clip with missing optional fields
    let clip = &feed.clips[0];
    assert_eq!(clip.status, "complete");
    assert_eq!(clip.title, "Test Song");
    assert_eq!(clip.play_count, 5);
    assert_eq!(clip.upvote_count, 2);
    assert_eq!(clip.id.to_string(), "a1b2c3d4-e5f6-4789-a012-3456789abcde");
    assert_eq!(clip.major_model_version, "v4");
    assert_eq!(clip.model_name, "chirp-v4");

    // These optional fields should be None
    assert!(clip.reaction.is_none());
    assert!(clip.ownership.is_none());
    assert_eq!(clip.explicit, Some(false));
    assert!(clip.display_tags.is_none());

    // Metadata with some optional fields present
    assert_eq!(clip.metadata.refund_credits, Some(false));
    assert_eq!(clip.metadata.stream, Some(true));
    assert_eq!(clip.metadata.priority, Some(5));

    // Metadata without some optional fields
    assert!(clip.metadata.control_sliders.is_none());
    assert!(clip.metadata.negative_tags.is_none());
    assert!(clip.metadata.has_vocal.is_none());
    assert!(clip.metadata.can_publish_with_vocal.is_none());
    assert!(clip.metadata.max_bpm.is_none());
    assert!(clip.metadata.min_bpm.is_none());
    assert!(clip.metadata.avg_bpm.is_none());
    assert!(clip.metadata.key.is_none());

    // Model badges without songcard
    assert!(clip.metadata.model_badges.is_some());
    let badges = clip.metadata.model_badges.as_ref().unwrap();
    assert!(badges.songcard.is_none());
    assert_eq!(badges.songrow.display_name, "v4");
}
