from charts.models import ChartRecord
from django.db.models import Count
from django.views import generic
from music.models import Album, Artist, Track
from scrobbles.stats import get_scrobble_count_qs
from scrobbles.views import ScrobbleableDetailView, ScrobbleableListView


class TrackListView(ScrobbleableListView):
    model = Track


class TrackDetailView(ScrobbleableDetailView):
    model = Track


class ArtistListView(generic.ListView):
    model = Artist
    paginate_by = 100

    def get_queryset(self):
        qs = super().get_queryset().annotate(scrobble_count=Count("track__scrobble"))
        genre = self.request.GET.get("genre")
        if genre:
            qs = qs.filter(theaudiodb_genre=genre)
        mood = self.request.GET.get("mood")
        if mood:
            qs = qs.filter(theaudiodb_mood=mood)
        return qs.order_by("-scrobble_count")

    def get_context_data(self, *, object_list=None, **kwargs):
        context_data = super().get_context_data(object_list=object_list, **kwargs)
        context_data["view"] = self.request.GET.get("view")
        genre = self.request.GET.get("genre")
        if genre:
            context_data["active_filter"] = f"genre: {genre}"
        mood = self.request.GET.get("mood")
        if mood:
            context_data["active_filter"] = f"mood: {mood}"
        return context_data


class ArtistDetailView(generic.DetailView):
    model = Artist
    slug_field = "uuid"

    def get_context_data(self, **kwargs):
        context_data = super().get_context_data(**kwargs)
        artist = context_data["object"]

        ranked_tracks = sorted(
            artist.tracks.all(), key=lambda t: t.scrobble_count, reverse=True
        )[:10]

        tracks_ranked = [
            (rank, track) for rank, track in enumerate(ranked_tracks, start=1)
        ]

        context_data["tracks_ranked"] = tracks_ranked

        charts_qs = ChartRecord.objects.filter(
            artist=self.object, rank__in=[1, 2, 3]
        ).exclude(day__isnull=False)
        from collections import OrderedDict

        grouped = OrderedDict()
        for chart in charts_qs:
            grouped.setdefault(chart.period_type, []).append(chart)
        context_data["charts"] = grouped

        from scrobbles.models import Scrobble

        context_data["recent_scrobbles"] = (
            Scrobble.objects.filter(track__artists=artist)
            .select_related("track", "track__album")
            .order_by("-timestamp")[:100]
        )

        similar = artist.similar_artists or []
        if similar:
            top = similar[:10]
            mbids = [sa["artist_mbid"] for sa in top if sa.get("artist_mbid")]
            local_artists = {
                a.musicbrainz_id: a
                for a in Artist.objects.filter(musicbrainz_id__in=mbids)
            }
            for sa in top:
                local = local_artists.get(sa.get("artist_mbid"))
                sa["local_url"] = local.get_absolute_url() if local else None
                sa["musicbrainz_url"] = (
                    f"https://musicbrainz.org/artist/{sa['artist_mbid']}"
                    if sa.get("artist_mbid")
                    else None
                )
            context_data["similar_artists"] = top

        if artist.theaudiodb_genre:
            context_data["genre_count"] = Artist.objects.filter(
                theaudiodb_genre=artist.theaudiodb_genre
            ).count()
        if artist.theaudiodb_mood:
            context_data["mood_count"] = Artist.objects.filter(
                theaudiodb_mood=artist.theaudiodb_mood
            ).count()

        return context_data


class AlbumListView(generic.ListView):
    model = Album

    def get_queryset(self):
        return (
            super()
            .get_queryset()
            .annotate(scrobble_count=Count("track__scrobble"))
            .order_by("-scrobble_count")
        )


class AlbumDetailView(generic.DetailView):
    model = Album
    slug_field = "uuid"

    def get_context_data(self, **kwargs):
        context_data = super().get_context_data(**kwargs)
        # context_data['charts'] = ChartRecord.objects.filter(
        #    track__album=self.object, rank__in=[1, 2, 3]
        # )
        return context_data
