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


@dataclass
class Difficulty:
    diff_id: str
    name: str
    overall_difficulty: float
    star_rating: float
    star_rating_nc: float
    star_rating_ht: float
    note_count: int
    hold_count: int
    length: float
    play_count: int = 0
    top_score: Optional[LeaderboardScore] = None

    @classmethod
    def from_dict(cls, data: dict) -> "Difficulty":
        ts = data.get("topScore")
        return cls(
            diff_id=data.get("diffId", ""),
            name=data.get("name", ""),
            overall_difficulty=data.get("overallDifficulty", 0.0),
            star_rating=data.get("starRating", 0.0),
            star_rating_nc=data.get("starRatingNC", 0.0),
            star_rating_ht=data.get("starRatingHT", 0.0),
            note_count=data.get("noteCount", data.get("tapCount", 0)),
            hold_count=data.get("holdCount", 0),
            length=data.get("length", 0.0),
            play_count=data.get("playCount", 0),
            top_score=LeaderboardScore.from_dict(ts) if ts else None,
        )


@dataclass
class Beatmap:
    id: str
    mapset_id: str
    title: str          # songName
    artist: str         # artistName
    mapper: str
    mapper_id: str
    description: str
    tags: str
    language: str
    bpm: int
    status: str
    ranked: bool
    explicit: bool
    has_video: bool
    has_custom_hitsounds: bool
    background_image_url: str
    audio_preview_url: str
    rtm_url: str
    play_count: int
    favorite_count: int
    upload_date: str    # uploadedAt
    ranked_date: Optional[str]
    difficulties: list[Difficulty]

    @classmethod
    def from_dict(cls, data: dict) -> "Beatmap":
        return cls(
            id=data.get("id", ""),
            mapset_id=data.get("mapsetId", ""),
            title=data.get("songName", ""),
            artist=data.get("artistName", ""),
            mapper=data.get("mapper", ""),
            mapper_id=data.get("mapperId", ""),
            description=data.get("description", ""),
            tags=data.get("tags", ""),
            language=data.get("language", ""),
            bpm=data.get("bpm", 0),
            status=data.get("status", ""),
            ranked=data.get("ranked", False),
            explicit=data.get("explicit", False),
            has_video=data.get("hasVideo", False),
            has_custom_hitsounds=data.get("hasCustomHitsounds", False),
            background_image_url=data.get("backgroundImageUrl", ""),
            audio_preview_url=data.get("audioPreviewUrl", ""),
            rtm_url=data.get("rtmUrl", ""),
            play_count=data.get("playCount", 0),
            favorite_count=data.get("favoriteCount", 0),
            upload_date=data.get("uploadedAt", ""),
            ranked_date=data.get("rankedDate"),
            difficulties=[Difficulty.from_dict(d) for d in data.get("difficulties", [])],
        )


@dataclass
class Comment:
    id: str
    beatmap_id: str
    user_id: str
    username: str
    comment: str
    likes: int
    created_at: str
    profile_picture_url: str

    @classmethod
    def from_dict(cls, data: dict) -> "Comment":
        return cls(
            id=data.get("id", ""),
            beatmap_id=data.get("beatmapId", ""),
            user_id=data.get("uid", ""),
            username=data.get("username", ""),
            comment=data.get("comment", ""),
            likes=data.get("likes", 0),
            created_at=data.get("createdAt", ""),
            profile_picture_url=data.get("profilePictureUrl", ""),
        )