import datetime

from django.http import JsonResponse
from django.utils import timezone
from django.views import generic
from django.views.decorators.http import require_POST
from boardgames.models import BoardGame, BoardGameDesigner, BoardGamePublisher
from scrobbles.models import Scrobble
from scrobbles.views import (
    ChartContextMixin,
    ScrobbleableListView,
    ScrobbleableDetailView,
)


@require_POST
def ajax_create_variant(request):
    name = request.POST.get("name", "").strip()
    board_game_id = request.POST.get("board_game_id")
    description = request.POST.get("description", "").strip()

    if not name or not board_game_id:
        return JsonResponse({"error": "Name and board game are required"}, status=400)

    try:
        board_game_id = int(board_game_id)
    except (ValueError, TypeError):
        return JsonResponse({"error": "Invalid board game"}, status=400)

    from boardgames.models import BoardGameVariant

    variant = BoardGameVariant.objects.filter(
        name__iexact=name,
        board_game_id=board_game_id,
    ).first()
    if variant:
        return JsonResponse({"id": variant.id, "name": variant.name})

    variant = BoardGameVariant.objects.create(
        name=name,
        board_game_id=board_game_id,
        description=description or None,
    )

    return JsonResponse({"id": variant.id, "name": variant.name})


class BoardGameListView(ScrobbleableListView):
    model = BoardGame

    def get_context_data(self, **kwargs):
        context_data = super().get_context_data(**kwargs)
        user = self.request.user
        now = timezone.now()
        start_day_of_week = now - datetime.timedelta(days=now.weekday())
        start_day_of_month = now.replace(day=1)

        scrobbles_this_week = Scrobble.objects.filter(
            user=user,
            board_game__isnull=False,
            timestamp__gte=start_day_of_week,
        ).select_related("board_game")

        scrobbles_this_month = Scrobble.objects.filter(
            user=user,
            board_game__isnull=False,
            timestamp__gte=start_day_of_month,
        ).select_related("board_game")

        designers_this_week = {}
        for scrobble in scrobbles_this_week:
            for designer in scrobble.board_game.designers.all():
                designers_this_week[designer.id] = {
                    "designer": designer,
                    "count": designers_this_week.get(designer.id, {}).get("count", 0)
                    + 1,
                }

        designers_this_month = {}
        for scrobble in scrobbles_this_month:
            for designer in scrobble.board_game.designers.all():
                designers_this_month[designer.id] = {
                    "designer": designer,
                    "count": designers_this_month.get(designer.id, {}).get("count", 0)
                    + 1,
                }

        context_data["designers_this_week"] = sorted(
            designers_this_week.values(),
            key=lambda x: x["count"],
            reverse=True,
        )
        context_data["designers_this_month"] = sorted(
            designers_this_month.values(),
            key=lambda x: x["count"],
            reverse=True,
        )

        return context_data


class BoardGameDetailView(ScrobbleableDetailView, ChartContextMixin):
    model = BoardGame


class BoardGamePublisherDetailView(generic.DetailView):
    model = BoardGamePublisher
    slug_field = "uuid"
