//! Database model structs

use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};

/// Playlist item entry
#[allow(dead_code)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PlaylistItem {
    pub id: Option<i64>,
    pub playlist_id: String,
    pub item_id: String,
    pub sort_order: i32,
    pub added_at: Option<DateTime<Utc>>,
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_playlist_item_creation() {
        let item = PlaylistItem {
            id: Some(1),
            playlist_id: "playlist-123".to_string(),
            item_id: "item-456".to_string(),
            sort_order: 0,
            added_at: None,
        };

        assert_eq!(item.id, Some(1));
        assert_eq!(item.playlist_id, "playlist-123");
        assert_eq!(item.item_id, "item-456");
        assert_eq!(item.sort_order, 0);
        assert!(item.added_at.is_none());
    }

    #[test]
    fn test_playlist_item_without_id() {
        let item = PlaylistItem {
            id: None,
            playlist_id: "playlist-789".to_string(),
            item_id: "item-999".to_string(),
            sort_order: 5,
            added_at: None,
        };

        assert!(item.id.is_none());
        assert_eq!(item.sort_order, 5);
    }

    #[test]
    fn test_playlist_item_serialization() {
        let item = PlaylistItem {
            id: Some(42),
            playlist_id: "pl-001".to_string(),
            item_id: "it-001".to_string(),
            sort_order: 10,
            added_at: None,
        };

        let json = serde_json::to_string(&item);
        assert!(json.is_ok());
        let serialized = json.unwrap();
        assert!(serialized.contains("pl-001"));
        assert!(serialized.contains("it-001"));
        assert!(serialized.contains("10"));
    }

    #[test]
    fn test_playlist_item_clone() {
        let item = PlaylistItem {
            id: Some(99),
            playlist_id: "clone-playlist".to_string(),
            item_id: "clone-item".to_string(),
            sort_order: 3,
            added_at: None,
        };

        let cloned = item.clone();
        assert_eq!(item.id, cloned.id);
        assert_eq!(item.playlist_id, cloned.playlist_id);
        assert_eq!(item.item_id, cloned.item_id);
        assert_eq!(item.sort_order, cloned.sort_order);
    }

    #[test]
    fn test_playlist_item_with_timestamp() {
        let now = Utc::now();
        let item = PlaylistItem {
            id: Some(100),
            playlist_id: "time-playlist".to_string(),
            item_id: "time-item".to_string(),
            sort_order: 7,
            added_at: Some(now),
        };

        assert!(item.added_at.is_some());
        assert_eq!(item.added_at, Some(now));
    }

    #[test]
    fn test_playlist_item_multiple_sort_orders() {
        let sort_orders = vec![0, 1, 5, 10, 100, 999];

        for order in sort_orders {
            let item = PlaylistItem {
                id: Some(1),
                playlist_id: "pl".to_string(),
                item_id: "it".to_string(),
                sort_order: order,
                added_at: None,
            };

            assert_eq!(item.sort_order, order);
        }
    }

    #[test]
    fn test_playlist_item_debug() {
        let item = PlaylistItem {
            id: Some(200),
            playlist_id: "debug-pl".to_string(),
            item_id: "debug-it".to_string(),
            sort_order: 15,
            added_at: None,
        };

        let debug_str = format!("{:?}", item);
        assert!(debug_str.contains("PlaylistItem"));
        assert!(debug_str.contains("debug-pl"));
    }
}
