from django.contrib import admin
from django.contrib.auth import get_user_model
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.db.models import Count, Q, Sum
from django.urls import reverse
from django.utils.html import format_html

from .models import CustomerProfile

User = get_user_model()


class SubscriberTypeFilter(admin.SimpleListFilter):
    title = 'subscriber type'
    parameter_name = 'type'

    def lookups(self, request, model_admin):
        return (
            ('magazine', 'Magazine readers'),
            ('shop', 'Shop customers'),
            ('both', 'Magazine + shop'),
            ('newsletter', 'Newsletter only'),
            ('none', 'No purchases yet'),
        )

    def queryset(self, request, qs):
        v = self.value()
        if v == 'magazine':
            return qs.filter(_mags__gt=0)
        if v == 'shop':
            return qs.filter(_orders__gt=0)
        if v == 'both':
            return qs.filter(_mags__gt=0, _orders__gt=0)
        if v == 'newsletter':
            return qs.filter(wants_newsletter=True, _mags=0, _orders=0)
        if v == 'none':
            return qs.filter(_mags=0, _orders=0)
        return qs


@admin.register(CustomerProfile)
class CustomerProfileAdmin(admin.ModelAdmin):
    list_display = ('name', 'email', 'phone', 'subscriber_type', 'magazines', 'orders', 'spent',
                    'wants_newsletter', 'email_verified', 'joined', 'last_seen')
    list_filter = (SubscriberTypeFilter, 'wants_newsletter', 'email_verified', 'created_at')
    search_fields = ('user__first_name', 'user__last_name', 'user__email', 'phone')
    readonly_fields = ('user_link', 'created_at', 'purchases')
    fields = ('user_link', 'phone', 'alt_phone', 'division', 'district', 'area', 'address', 'wants_newsletter', 'email_verified', 'created_at', 'purchases')
    date_hierarchy = 'created_at'
    list_per_page = 50

    def get_queryset(self, request):
        return super().get_queryset(request).select_related('user').annotate(
            _mags=Count('user__magazine_access', filter=Q(user__magazine_access__status='approved'), distinct=True),
            _orders=Count('user__shop_orders', filter=~Q(user__shop_orders__status='cancelled'), distinct=True),
            _spent=Sum('user__shop_orders__total_amount', filter=~Q(user__shop_orders__status='cancelled')),
        )

    def has_add_permission(self, request):
        return False  # readers create their own accounts

    @admin.display(description='Name', ordering='user__first_name')
    def name(self, obj):
        return obj.user.get_full_name() or '—'

    @admin.display(description='Email', ordering='user__email')
    def email(self, obj):
        return obj.user.email

    @admin.display(description='Type')
    def subscriber_type(self, obj):
        tags = []
        if obj._mags:
            tags.append(('Magazine', '#2e7d32'))
        if obj._orders:
            tags.append(('Shop', '#1a56b8'))
        if not tags and obj.wants_newsletter:
            tags.append(('Newsletter', '#8a6d1d'))
        if not tags:
            return format_html('<span style="color:#888">—</span>')
        return format_html(' '.join(
            f'<span style="background:{c};color:#fff;padding:2px 7px;border-radius:9px;font-size:11px">{t}</span>'
            for t, c in tags))

    @admin.display(description='Magazines', ordering='_mags')
    def magazines(self, obj):
        return obj._mags

    @admin.display(description='Orders', ordering='_orders')
    def orders(self, obj):
        return obj._orders

    @admin.display(description='Spent (shop)', ordering='_spent')
    def spent(self, obj):
        return f'৳{obj._spent:,.0f}' if obj._spent else '—'

    @admin.display(description='Joined', ordering='created_at')
    def joined(self, obj):
        return obj.created_at.date()

    @admin.display(description='Last sign-in', ordering='user__last_login')
    def last_seen(self, obj):
        return obj.user.last_login.date() if obj.user.last_login else '—'

    @admin.display(description='User account')
    def user_link(self, obj):
        url = reverse('admin:auth_user_change', args=[obj.user_id])
        return format_html('<a href="{}">{}</a>', url, obj.user.email or obj.user.username)

    @admin.display(description='Purchases')
    def purchases(self, obj):
        rows = []
        for a in obj.user.magazine_access.select_related('product'):
            url = reverse('admin:store_digitalaccess_change', args=[a.pk])
            rows.append(format_html('📖 <a href="{}">{}</a> — {} ({})', url, a.product.title,
                                    a.get_status_display(), a.created_at.date()))
        for o in obj.user.shop_orders.all():
            url = reverse('admin:store_order_change', args=[o.pk])
            rows.append(format_html('🛍️ <a href="{}">Order #{}</a> — ৳{} {} ({})', url, o.pk,
                                    f'{o.total_amount:,.0f}', o.get_status_display(), o.created_at.date()))
        return format_html('<br>'.join(str(r) for r in rows)) if rows else 'No purchases yet.'


class ProfileInline(admin.StackedInline):
    model = CustomerProfile
    can_delete = False
    fields = ('phone', 'alt_phone', 'division', 'district', 'area', 'address', 'wants_newsletter', 'email_verified')


admin.site.unregister(User)


@admin.register(User)
class UserAdmin(BaseUserAdmin):
    inlines = [ProfileInline]
