//! artist 详情 / artist 专辑列表端点的响应结构。

use serde::Deserialize;

use super::de::string_or_null;
use super::song::{AlbumSong, Artist};

/// `/weapi/v1/artist/{id}` 的响应(顶层即此结构,非 `result` 包裹)。
#[derive(Debug, Deserialize)]
pub struct ArtistDetailResult {
    /// artist 信息。
    pub artist: ArtistInfo,

    /// 热门曲目(ar/al/dt 字段风格,与专辑/歌单 detail 同构)。
    #[serde(default, rename = "hotSongs")]
    pub hot_songs: Vec<AlbumSong>,
}

/// 详情 / 专辑列表端点里的 artist 信息。
#[derive(Debug, Deserialize)]
pub struct ArtistInfo {
    /// artist 数字 ID。
    pub id: i64,

    /// artist 名。
    #[serde(default, deserialize_with = "string_or_null")]
    pub name: String,

    /// 头像 URL。
    #[serde(default, rename = "picUrl")]
    pub pic_url: Option<String>,

    /// 简介(可能缺失或 null)。
    #[serde(default, rename = "briefDesc", deserialize_with = "string_or_null")]
    pub brief_desc: String,

    /// 名下 album 总数(顶层 `albumSize`,部分端点不带 → `None`）。
    #[serde(default, rename = "albumSize")]
    pub album_size: Option<u64>,

    /// 名下歌曲总数(顶层 `musicSize`,部分端点不带 → `None`)。
    #[serde(default, rename = "musicSize")]
    pub music_size: Option<u64>,
}

/// `/api/artist/follow/count/get` 响应。artist 详情端点顶层不带粉丝数,粉丝数只此端点给,
/// 故 `artist_detail` 并发补打它再聚合。
#[derive(Debug, Deserialize)]
pub struct FollowCountResult {
    /// 业务数据块(异常时可能缺)。
    #[serde(default)]
    pub data: Option<FollowCountData>,
}

/// follow/count `data` 块,本结构只取粉丝数。
#[derive(Debug, Deserialize)]
pub struct FollowCountData {
    /// 粉丝数(字段名 `fansCnt`)。
    #[serde(default, rename = "fansCnt")]
    pub fans_cnt: u64,
}

/// `/api/artist/albums/{id}` 的响应。
#[derive(Debug, Deserialize)]
pub struct ArtistAlbumsResult {
    /// 专辑列表(网易云字段名如此,不只"热门",分页翻完即全集)。
    #[serde(default, rename = "hotAlbums")]
    pub hot_albums: Vec<ArtistAlbum>,
}

/// artist 专辑列表里的专辑项。
#[derive(Debug, Deserialize)]
pub struct ArtistAlbum {
    /// 专辑数字 ID。
    pub id: i64,

    /// 专辑名。
    #[serde(default, deserialize_with = "string_or_null")]
    pub name: String,

    /// 封面 URL。
    #[serde(default, rename = "picUrl")]
    pub pic_url: Option<String>,

    /// 发行时间(毫秒时间戳)。
    #[serde(default, rename = "publishTime")]
    pub publish_time: i64,

    /// 曲目数。
    #[serde(default)]
    pub size: u64,

    /// 发行方(唱片公司 / 厂牌),可为 null。
    #[serde(default)]
    pub company: Option<String>,

    /// 主 artist(部分响应只给这个;`artists` 是全列表,优先后者)。
    #[serde(default)]
    pub artist: Option<Artist>,

    /// 全部 artist(多人 album 用;缺失时退回 `artist`)。
    #[serde(default)]
    pub artists: Vec<Artist>,
}

#[cfg(test)]
mod tests {
    use super::{ArtistAlbumsResult, ArtistDetailResult};
    use crate::wire::de::from_value;

    /// artist 详情:artist 元信息 + hotSongs(ar/al/dt 风格)整体解析。
    #[test]
    fn parses_artist_detail_with_hot_songs() -> color_eyre::Result<()> {
        let raw = serde_json::json!({
            "artist": {
                "id": 11127, "name": "Beyond", "picUrl": "https://p1.music.126.net/x.jpg",
                "briefDesc": "香港摇滚乐队",
                "albumSize": 146, "musicSize": 2570
            },
            "hotSongs": [
                { "id": 1, "name": "海阔天空", "ar": [{ "id": 11127, "name": "Beyond" }],
                  "al": { "id": 9, "name": "乐与怒" }, "dt": 323_000 }
            ]
        });
        let r: ArtistDetailResult = from_value(raw)?;
        mineral_test::assert_snap_debug!("artist 详情(Beyond + 热门曲海阔天空)解析结构", r);
        Ok(())
    }

    /// 详情容错:briefDesc null、无 fansCount、hotSongs 缺失 → 空串/0/空列表。
    #[test]
    fn artist_detail_tolerates_missing_fields() -> color_eyre::Result<()> {
        let raw = serde_json::json!({
            "artist": { "id": 1, "name": "X", "briefDesc": null }
        });
        let r: ArtistDetailResult = from_value(raw)?;
        assert_eq!(r.artist.brief_desc, "");
        assert!(r.artist.album_size.is_none());
        assert!(r.artist.music_size.is_none());
        assert!(r.hot_songs.is_empty());
        Ok(())
    }

    /// follow/count 端点:取出 `data.fansCnt` 作粉丝数;`data` 缺则降级 0。
    #[test]
    fn parses_follow_count() -> color_eyre::Result<()> {
        use super::FollowCountResult;

        let raw =
            serde_json::json!({ "code": 200, "data": { "fansCnt": 176_396, "follow": true } });
        let r: FollowCountResult = from_value(raw)?;
        assert_eq!(r.data.map(|d| d.fans_cnt), Some(176_396));

        let empty: FollowCountResult = from_value(serde_json::json!({ "code": 200 }))?;
        assert!(empty.data.is_none(), "data 缺 → None(调用方降级 0)");
        Ok(())
    }

    /// artist 的 album 列表:hotAlbums 解析(发行时间 / size / company / 全 artists)。
    #[test]
    fn parses_artist_albums() -> color_eyre::Result<()> {
        let raw = serde_json::json!({
            "hotAlbums": [
                { "id": 9, "name": "乐与怒", "picUrl": "https://p1.music.126.net/a.jpg",
                  "publishTime": 736_185_600_000_i64, "size": 10, "company": "滚石",
                  "artists": [{ "id": 11127, "name": "Beyond" }] },
                // size/company/artist 全缺 → 0 / None / 空。
                { "id": 8, "name": "继续革命", "publishTime": 715_000_000_000_i64 }
            ],
            "more": false
        });
        let r: ArtistAlbumsResult = from_value(raw)?;
        mineral_test::assert_snap_debug!(
            "artist 的 album 列表(乐与怒 带 size/company/artists / 继续革命 缺字段)解析结构",
            r
        );
        Ok(())
    }
}
