from src.Library import *

from typing import Any, Iterable
import json

from datetime import datetime
from pathlib import Path


def get_artists_str(artists_pack):
    track_artists = [artist['name'] for artist in artists_pack]
    artists = " ".join(track_artists)
    return artists


class Parser:
    def __init__(self):
        self.track_map: dict[str, Track] = {}
        self.artist_map: dict[str, Artist] = {}
        self.album_map: dict[str, Album] = {}
        self.library = Library()

    def parse(self, playlists: Path, tracks: Path, top_tracks: Path, top_artists: Path) -> Library:
        self.library = Library()

        self.parse_tracks(json.loads(tracks.read_text()))
        self.parse_playlists(json.loads(playlists.read_text()))

        self.parse_top_artists(json.loads(top_artists.read_text()))
        self.parse_top_tracks(json.loads(top_tracks.read_text()))

        self.library.update_cache()
        self.library.name = "Spotify"
        self.library.auto_score()

        self.score_tracks()

        return self.library


    def parse_playlists(self, data):
        for name,  tracks in data.items():
            playlist = Playlist()
            playlist.title = name
            for track in tracks:
                track_data = track.get("track")
                if track_data:
                    track_id = track_data.get("id")
                    playlist.tracks.append(self.parse_track(track_data, track.get("added_at")))

            self.library.playlists.append(playlist)

    def parse_top_tracks(self, data):
        for track in data:
            if track.get("id") in self.track_map:
                self.library.top_tracks.append(self.track_map.get(track.get("id")))

    def parse_top_artists(self, data):
        for artist in data:
            if artist.get("id") in self.artist_map:
                self.library.top_artists.append(self.artist_map.get(artist.get("id")))

    def parse_tracks(self, data):
        for track in data:
            self.parse_track(track.get("track"), track.get("added_at"))

        for track in data:
            self.library.liked_tracks.append(self.track_map.get(track.get("track").get("id")))

    def parse_track(self, data: dict[str, Any], added_time : datetime) -> Track:
        track_id = data.get("id")

        if track_id in self.track_map:
            return self.track_map[track_id]

        track = Track()

        self.track_map[track_id] = track

        track.id = track_id
        track.title = data.get("name")
        track.artists = [] + self.parse_album(data.get("album")).artists
        track.album = self.parse_album(data.get("album"))
        track.duration_ms = data.get("duration_ms")

        self.library.tracks.append(track)

        return track

    def parse_album(self, data):
        album_id = data.get("id")

        if album_id in self.album_map:
            return self.album_map[album_id]

        album = Album()

        self.album_map[album_id] = album

        album.id = data.get("id")
        album.title = data.get("name")
        album.artists = [self.parse_artist(artist) for artist in data.get("artists")]

        self.library.albums.append(album)

        return album

    def parse_artist(self, data: dict[str, Any]) -> Artist:
        artist_id = data.get("id")

        if artist_id in self.artist_map:
            return self.artist_map[artist_id]

        artist = Artist()

        self.artist_map[artist_id] = artist

        artist.id = data.get("id")
        artist.title = data.get("name")

        if artist.title is None:
            artist.title = "err_no_title"

        self.library.artists.append(artist)

        return artist

    def score_tracks(self):
        for idx, track in enumerate(self.library.top_tracks):
            score = len(self.library.top_tracks) - idx
            track.auto_score = score