from dataclasses import dataclass, field
from typing import Optional
from .score import Score


@dataclass
class Grades:
    ss: int = 0
    s: int = 0
    a: int = 0
    b: int = 0
    c: int = 0
    d: int = 0
    f: int = 0

    @classmethod
    def from_dict(cls, data: dict) -> "Grades":
        return cls(
            ss=data.get("ss", 0),
            s=data.get("s", 0),
            a=data.get("a", 0),
            b=data.get("b", 0),
            c=data.get("c", 0),
            d=data.get("d", 0),
            f=data.get("f", 0),
        )


@dataclass
class RankHistoryEntry:
    date: str
    rank: int
    pp: float

    @classmethod
    def from_dict(cls, data: dict) -> "RankHistoryEntry":
        return cls(
            date=data.get("date", ""),
            rank=data.get("rank", 0),
            pp=data.get("pp", 0.0),
        )


@dataclass
class Topbar:
    username: str
    profile_picture_url: str
    global_rank: int
    total_pp: float
    country: str

    @classmethod
    def from_dict(cls, data: dict) -> "Topbar":
        return cls(
            username=data.get("displayUsername", ""),
            profile_picture_url=data.get("profilePictureUrl", ""),
            global_rank=data.get("globalRank", 0),
            total_pp=data.get("totalPP", 0.0),
            country=data.get("country", ""),
        )


@dataclass
class Profile:
    user_id: str
    username: str
    country: str
    level: int
    pp: float
    total_pp: float
    raw_pp: float
    accuracy: float
    global_rank: int
    country_rank: int
    ranked_score: int
    total_score: int
    play_count: int
    play_time: int
    grades: Grades
    top_plays: list[Score]
    recent_plays: list[Score]
    rank_history: list[RankHistoryEntry]
    play_heatmap: dict[str, int]
    profile_description: str
    profile_picture_url: str
    follower_count: int
    following_count: int

    @classmethod
    def from_dict(cls, data: dict) -> "Profile":
        return cls(
            user_id=data.get("userId", ""),
            username=data.get("username", ""),
            country=data.get("country", ""),
            level=data.get("level", 0),
            pp=data.get("pp", 0.0),
            total_pp=data.get("totalPP", 0.0),
            raw_pp=data.get("rawPP", 0.0),
            accuracy=data.get("accuracy", 0.0),
            global_rank=data.get("globalRank", 0),
            country_rank=data.get("countryRank", 0),
            ranked_score=data.get("rankedScore", 0),
            total_score=data.get("totalScore", 0),
            play_count=data.get("playCount", 0),
            play_time=data.get("playTime", 0),
            grades=Grades.from_dict(data.get("grades", {})),
            top_plays=[Score.from_dict(s) for s in data.get("topPlays", [])],
            recent_plays=[Score.from_dict(s) for s in data.get("recentPlays", [])],
            rank_history=[RankHistoryEntry.from_dict(r) for r in data.get("rankHistory", [])],
            play_heatmap=data.get("playHeatmap", {}),
            profile_description=data.get("profileDescription", ""),
            profile_picture_url=data.get("profilePictureUrl", ""),
            follower_count=data.get("followerCount", 0),
            following_count=data.get("followingCount", 0),
        )


@dataclass
class UserSearchResult:
    user_id: str
    username: str
    total_pp: float
    global_rank: int
    country: str

    @classmethod
    def from_dict(cls, data: dict) -> "UserSearchResult":
        return cls(
            user_id=data.get("userId", ""),
            username=data.get("username", ""),
            total_pp=data.get("totalPP", 0.0),
            global_rank=data.get("globalRank", 0),
            country=data.get("country", ""),
        )


@dataclass
class MostPlayedEntry:
    beatmap_id: str
    mapset_id: str
    artist: str
    title: str
    difficulty_name: str
    background_image_url: str
    play_count: int

    @classmethod
    def from_dict(cls, data: dict) -> "MostPlayedEntry":
        return cls(
            beatmap_id=data.get("beatmapId", ""),
            mapset_id=data.get("mapsetId", ""),
            artist=data.get("artist", ""),
            title=data.get("title", ""),
            difficulty_name=data.get("difficultyName", ""),
            background_image_url=data.get("backgroundImageUrl", ""),
            play_count=data.get("playCount", 0),
        )