from django.contrib import admin
from django.db.models import Avg, Count

from .models import Game, GameCard, Play


class GameCardInline(admin.StackedInline):
    model = GameCard
    extra = 0
    fields = ('title', 'year', 'year_label', 'clues', 'wrong_options', 'is_true', 'explanation', 'image',
              'article', 'source', 'is_active')
    raw_id_fields = ('article',)
    show_change_link = True


@admin.register(Game)
class GameAdmin(admin.ModelAdmin):
    list_display = ('title', 'kind', 'cards_count', 'plays_count', 'reward_summary', 'order', 'is_active')
    list_editable = ('order', 'is_active')
    prepopulated_fields = {'slug': ('title_en',)}
    filter_horizontal = ('reward_products',)
    inlines = [GameCardInline]
    fieldsets = (
        (None, {'fields': ('kind', 'title', 'title_en', 'slug', 'tagline', 'image', 'rounds', 'order', 'is_active')}),
        ('Page text', {'fields': ('description', 'how_to_play', 'physical_note', 'meta_description')}),
        ('Score → discount', {
            'fields': ('reward_enabled', 'reward_min_score', 'reward_max_percent', 'reward_max_taka', 'reward_min_order',
                       'reward_applies_to', 'reward_products', 'reward_valid_days', 'reward_cooldown_days'),
            'description': 'Signed-in players get a personal one-time coupon. The discount grows with the score: '
                           'e.g. "Discount at 100% score" = 20 → a 70% score gives 14% off. '
                           'Coupons appear in Store → Coupons with source "Game reward".'}),
    )

    def get_queryset(self, request):
        return super().get_queryset(request).annotate(n_cards=Count('cards', distinct=True),
                                                      n_plays=Count('plays', distinct=True))

    @admin.display(description='Cards', ordering='n_cards')
    def cards_count(self, obj):
        return obj.n_cards

    @admin.display(description='Plays', ordering='n_plays')
    def plays_count(self, obj):
        return obj.n_plays

    @admin.display(description='Reward')
    def reward_summary(self, obj):
        if not obj.reward_enabled:
            return 'Off'
        return f"up to {obj.reward_max_percent}% from {obj.reward_min_score}% score · {obj.get_reward_applies_to_display()}"


@admin.register(GameCard)
class GameCardAdmin(admin.ModelAdmin):
    list_display = ('title', 'game', 'year', 'is_true', 'is_active')
    list_filter = ('game', 'is_active')
    search_fields = ('title', 'clues', 'explanation')
    raw_id_fields = ('article',)


@admin.register(Play)
class PlayAdmin(admin.ModelAdmin):
    list_display = ('game', 'user', 'score', 'max_score', 'percent_display', 'finished', 'coupon', 'created_at')
    list_filter = ('game', 'finished', 'created_at')
    search_fields = ('user__email', 'coupon__code')
    readonly_fields = [f.name for f in Play._meta.fields]

    @admin.display(description='%')
    def percent_display(self, obj):
        return f'{obj.percent}%'

    def has_add_permission(self, request):
        return False

    def has_change_permission(self, request, obj=None):
        return False
