from django.views.generic import TemplateView
from django.urls import reverse_lazy
from django.views.generic import UpdateView, DeleteView, CreateView, ListView, DetailView
from cards.models import Card
from trades.models import TradeOffer
from common.mixins import ReusablePaginationMixin

class CardDetailView(DetailView):
    model = Card
    template_name = "cards/card_detail.html"
    context_object_name = "card"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        card = self.get_object()
        # Count of trade offers where the card appears as a "have" in a trade.
        context['trade_offer_have_count'] = TradeOffer.objects.filter(
            trade_offer_have_cards__card=card
        ).distinct().count()
        # Count of trade offers where the card appears as a "want" in a trade.
        context['trade_offer_want_count'] = TradeOffer.objects.filter(
            trade_offer_want_cards__card=card
        ).distinct().count()
        return context


class TradeOfferHaveCardListView(ListView):
    model = TradeOffer
    template_name = "trades/_trade_offer_list.html"
    context_object_name = "offers"
    paginate_by = 2

    def get_queryset(self):
        card_id = self.kwargs.get("pk")
        order_param = self.request.GET.get("order", "newest")
        ordering = "-updated_at" if order_param == "newest" else "updated_at"
        return TradeOffer.objects.filter(
            trade_offer_have_cards__card_id=card_id
        ).order_by(ordering).distinct()

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['side'] = 'have'
        return context


class TradeOfferWantCardListView(ListView):
    model = TradeOffer
    template_name = "trades/_trade_offer_list.html"
    context_object_name = "offers"
    paginate_by = 2

    def get_queryset(self):
        card_id = self.kwargs.get("pk")
        order_param = self.request.GET.get("order", "newest")
        ordering = "-updated_at" if order_param == "newest" else "updated_at"
        return TradeOffer.objects.filter(
            trade_offer_want_cards__card_id=card_id
        ).order_by(ordering).distinct()

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['side'] = 'want'
        return context

class CardListView(ReusablePaginationMixin, ListView):
    model = Card
    # Removed built-in pagination; using custom mixin instead
    context_object_name = "cards"

    def get_template_names(self):
        if self.request.headers.get("x-requested-with") == "XMLHttpRequest":
            return ["cards/_card_list.html"]
        return ["cards/card_list.html"]

    def get_ordering(self):
        order = self.request.GET.get("order", "absolute")
        if order == "alphabetical":
            return "name"
        elif order == "rarity":
            return "-rarity_level"
        else:  # absolute ordering
            return "id"

    def get_queryset(self):
        qs = super().get_queryset()
        ordering = self.get_ordering()
        qs = qs.order_by(ordering)
        return qs.prefetch_related("decks").distinct()

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        order = self.request.GET.get("order", "absolute")
        group_by = self.request.GET.get("group_by")
        context["order"] = order
        context["group_by"] = group_by

        if group_by in ("deck", "cardset", "rarity"):
            full_qs = self.get_queryset()
            all_cards = list(full_qs)
            flat_cards = []
            if group_by == "deck":
                for card in all_cards:
                    for deck in card.decks.all():
                        flat_cards.append({"group": deck.name, "card": card})
                flat_cards.sort(key=lambda x: x["group"].lower())
            elif group_by == "cardset":
                for card in all_cards:
                    flat_cards.append({"group": card.cardset, "card": card})
                flat_cards.sort(key=lambda x: x["group"].lower())
            elif group_by == "rarity":
                for card in all_cards:
                    flat_cards.append({"group": card.rarity_icon, "sort_group": card.rarity_level, "card": card})
                flat_cards.sort(key=lambda x: x["sort_group"], reverse=True)

            page_number = self.get_page_number()
            self.per_page = 36
            page_flat_cards, pagination_context = self.paginate_data(flat_cards, page_number)

            page_groups = []
            for item in page_flat_cards:
                group_value = item["group"]
                card_obj = item["card"]
                if page_groups and page_groups[-1]["group"] == group_value:
                    page_groups[-1]["cards"].append(card_obj)
                else:
                    page_groups.append({"group": group_value, "cards": [card_obj]})
            context["groups"] = page_groups
            context["page_obj"] = pagination_context
            context["total_cards"] = len(flat_cards)
            context["object_list"] = full_qs
        else:
            page_number = self.get_page_number()
            self.per_page = 36
            paginated_cards, pagination_context = self.paginate_data(self.get_queryset(), page_number)
            context["cards"] = paginated_cards
            context["page_obj"] = pagination_context
            context["object_list"] = self.get_queryset()
        return context