from django.contrib import admin

from .models import (
    AppliedDiscount,
    Cart,
    CartItem,
    Discount,
    Invoice,
    Order,
    OrderLine,
    Payment,
    Product,
)


class ClubScopedFKMixin:
    """Restrict club-scoped FK dropdowns to the edited object's (or parent's) club.

    ``scoped_fk_fields`` names FKs whose target is a club-scoped model. The club
    is taken from the object being edited (or, for inlines, the parent object).
    Enforcement still lives in each model's ``clean()``; this just keeps invalid
    options out of the dropdowns.
    """

    scoped_fk_fields = ()

    def get_form(self, request, obj=None, **kwargs):
        request._club_obj = obj
        return super().get_form(request, obj, **kwargs)

    def get_formset(self, request, obj=None, **kwargs):
        request._club_obj = obj
        return super().get_formset(request, obj, **kwargs)

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name in self.scoped_fk_fields:
            club_id = getattr(getattr(request, "_club_obj", None), "club_id", None)
            if club_id is not None:
                kwargs["queryset"] = db_field.related_model._default_manager.filter(club_id=club_id)
        return super().formfield_for_foreignkey(db_field, request, **kwargs)


@admin.register(Product)
class ProductAdmin(ClubScopedFKMixin, admin.ModelAdmin):
    scoped_fk_fields = ("season", "staff_role")
    list_display = ["name", "product_type", "club", "is_active", "is_public"]
    list_filter = ["club", "product_type", "is_active", "is_public"]
    search_fields = ["name", "slug"]
    prepopulated_fields = {"slug": ["name"]}


class CartItemInline(ClubScopedFKMixin, admin.TabularInline):
    model = CartItem
    scoped_fk_fields = ("product", "team")
    extra = 0
    raw_id_fields = ["beneficiary"]


@admin.register(Cart)
class CartAdmin(admin.ModelAdmin):
    list_display = ["user", "status", "club"]
    list_filter = ["club", "status"]
    search_fields = ["user__email"]
    raw_id_fields = ["user"]
    inlines = [CartItemInline]


@admin.register(CartItem)
class CartItemAdmin(admin.ModelAdmin):
    list_display = ["cart", "product", "quantity", "beneficiary"]
    search_fields = ["product__name"]
    raw_id_fields = ["cart", "product", "beneficiary", "team"]


class OrderLineInline(ClubScopedFKMixin, admin.TabularInline):
    model = OrderLine
    scoped_fk_fields = ("product", "team")
    extra = 0
    raw_id_fields = ["beneficiary"]


class AppliedDiscountInline(ClubScopedFKMixin, admin.TabularInline):
    model = AppliedDiscount
    scoped_fk_fields = ("discount",)
    extra = 0
    raw_id_fields = ["applied_by"]


class PaymentInline(admin.TabularInline):
    model = Payment
    extra = 0


@admin.register(Order)
class OrderAdmin(admin.ModelAdmin):
    list_display = ["number", "purchaser", "status", "total", "club", "created"]
    list_filter = ["club", "status"]
    search_fields = ["number", "purchaser__first_name", "purchaser__last_name"]
    raw_id_fields = ["purchaser"]
    readonly_fields = ["number", "created", "modified"]
    inlines = [OrderLineInline, AppliedDiscountInline, PaymentInline]


@admin.register(OrderLine)
class OrderLineAdmin(admin.ModelAdmin):
    list_display = ["order", "product", "quantity", "line_total"]
    search_fields = ["product__name", "order__number"]
    raw_id_fields = ["order", "product", "beneficiary", "team"]


@admin.register(Discount)
class DiscountAdmin(admin.ModelAdmin):
    list_display = ["name", "discount_type", "discount_amount", "club", "is_active"]
    list_filter = ["club", "discount_type", "is_active"]
    search_fields = ["name", "slug"]
    prepopulated_fields = {"slug": ["name"]}


@admin.register(AppliedDiscount)
class AppliedDiscountAdmin(admin.ModelAdmin):
    list_display = ["order", "discount", "discount_type", "discount_amount"]
    search_fields = ["order__number", "discount__name"]
    raw_id_fields = ["order", "discount", "applied_by"]


@admin.register(Payment)
class PaymentAdmin(admin.ModelAdmin):
    list_display = ["order", "amount", "method", "status", "paid_at"]
    list_filter = ["method", "status"]
    search_fields = ["order__number", "reference"]
    raw_id_fields = ["order"]


@admin.register(Invoice)
class InvoiceAdmin(ClubScopedFKMixin, admin.ModelAdmin):
    scoped_fk_fields = ("order",)
    list_display = ["number", "order", "club", "issued_at", "due_date"]
    list_filter = ["club"]
    search_fields = ["number", "order__number"]
    readonly_fields = ["number", "issued_at"]
