from django.contrib import admin, messages
from django.utils.translation import ngettext
from django.utils.html import format_html
from django.urls import reverse
from django.db.models import Count, Q
from django.utils import timezone
from .models import Customer


@admin.register(Customer)
class CustomerAdmin(admin.ModelAdmin):
    """Administration avancée pour les clients de la coopérative."""

    list_display = (
        "user_email",
        "user_full_name",
        "phone_number",
        "age",
        "membership_status",
        "documents_count",
        "is_active",
        "created_at",
    )

    list_filter = (
        "is_active",
        "created_at",
        "birth_date",
        ("identity_documents", admin.RelatedOnlyFieldListFilter),
    )

    search_fields = (
        "user__email",
        "user__first_name",
        "user__last_name",
        "user__username",
        "phone_number",
        "id_card_number",
        "address",
    )

    readonly_fields = (
        "id",
        "membership_status",
        "age",
        "documents_count",
        "created_at",
        "updated_at",
        "view_user_link",
        "view_member_link",
    )

    fieldsets = (
        (
            "Informations utilisateur",
            {"fields": ("view_user_link", "user"), "classes": ("wide",)},
        ),
        (
            "Informations personnelles",
            {
                "fields": (
                    "address",
                    "phone_number",
                    "id_card_number",
                    "birth_date",
                    "age",
                ),
                "classes": ("wide",),
            },
        ),
        (
            "Documents",
            {
                "fields": ("identity_documents", "documents_count"),
                "classes": ("collapse",),
            },
        ),
        (
            "Statut membre",
            {"fields": ("membership_status", "view_member_link"), "classes": ("wide",)},
        ),
        (
            "Métadonnées",
            {
                "fields": (
                    "id",
                    "is_active",
                    "created_at",
                    "updated_at",
                    "created_by",
                    "updated_by",
                ),
                "classes": ("collapse",),
            },
        ),
    )

    filter_horizontal = ("identity_documents",)
    date_hierarchy = "created_at"
    actions = ["promote_to_member", "deactivate_customers", "activate_customers"]
    list_per_page = 25

    # Méthodes personnalisées pour l'affichage
    def user_email(self, obj):
        """Affiche l'email de l'utilisateur avec lien."""
        if obj.user:
            return format_html(
                '<a href="{}">{}</a>',
                reverse("admin:authentication_user_change", args=[obj.user.pk]),
                obj.user.email,
            )
        return "Aucun utilisateur"

    user_email.short_description = "Email"
    user_email.admin_order_field = "user__email"

    def user_full_name(self, obj):
        """Affiche le nom complet de l'utilisateur."""
        if obj.user.first_name or obj.user.last_name:
            return f"{obj.user.first_name} {obj.user.last_name}".strip()
        return obj.user.username or "Nom non défini"

    user_full_name.short_description = "Nom complet"
    user_full_name.admin_order_field = "user__last_name"

    def age(self, obj):
        """Calcule et affiche l'âge du client."""
        if obj.birth_date:
            today = timezone.now().date()
            age = today.year - obj.birth_date.year
            if today.month < obj.birth_date.month or (
                today.month == obj.birth_date.month and today.day < obj.birth_date.day
            ):
                age -= 1
            return f"{age} ans"
        return "Non renseigné"

    age.short_description = "Âge"

    def membership_status(self, obj):
        """Affiche le statut de membre avec style."""
        if obj.is_member:
            return format_html(
                '<span style="color: green; font-weight: bold;">✓ Membre</span>'
            )
        return format_html('<span style="color: orange;">👤 Client</span>')

    membership_status.short_description = "Statut"

    def documents_count(self, obj):
        """Compte le nombre de documents d'identité."""
        count = obj.identity_documents.count()
        if count > 0:
            return format_html(
                '<span style="color: green;">{} document{}</span>',
                count,
                "s" if count > 1 else "",
            )
        return format_html('<span style="color: red;">Aucun document</span>')

    documents_count.short_description = "Documents"

    def view_user_link(self, obj):
        """Lien vers la page d'administration de l'utilisateur."""
        if obj.user:
            url = reverse("admin:authentication_user_change", args=[obj.user.pk])
            return format_html(
                '<a href="{}" class="button" target="_blank">👤 Voir l\'utilisateur</a>',
                url,
            )
        return "Aucun utilisateur"

    view_user_link.short_description = "Utilisateur lié"

    def view_member_link(self, obj):
        """Lien vers le profil membre si disponible."""
        if obj.is_member:
            url = reverse("admin:members_member_change", args=[obj.member.pk])
            return format_html(
                '<a href="{}" class="button" target="_blank">👑 Voir le profil membre</a>',
                url,
            )
        return format_html('<span style="color: gray;">Pas encore membre</span>')

    view_member_link.short_description = "Profil membre"

    def promote_to_member(self, request, queryset):
        """Action pour promouvoir les clients sélectionnés en membres."""
        updated_count = 0
        error_customers = []

        # Filtrer les clients qui ne sont pas déjà membres
        customers_to_promote = [c for c in queryset if not c.is_member]

        for customer in customers_to_promote:
            try:
                customer.promote_to_member(by_user=request.user)
                updated_count += 1
            except ValueError as e:
                error_customers.append(f"{customer.user.email}: {e}")

        if updated_count > 0:
            self.message_user(
                request,
                ngettext(
                    "👑 %d client a été promu en membre.",
                    "👑 %d clients ont été promus en membres.",
                    updated_count,
                )
                % updated_count,
                messages.SUCCESS,
            )

        if error_customers:
            self.message_user(
                request,
                f"❌ Erreurs lors de la promotion : {', '.join(error_customers)}",
                messages.ERROR,
            )

        already_members_count = len(queryset) - len(customers_to_promote)
        if already_members_count > 0:
            self.message_user(
                request,
                ngettext(
                    "ℹ️ %d client sélectionné était déjà membre.",
                    "ℹ️ %d clients sélectionnés étaient déjà membres.",
                    already_members_count,
                )
                % already_members_count,
                messages.WARNING,
            )

    promote_to_member.short_description = "👑 Promouvoir en membres"

    def deactivate_customers(self, request, queryset):
        """Action pour désactiver les clients sélectionnés."""
        updated = queryset.update(is_active=False, updated_by=request.user)
        self.message_user(
            request,
            ngettext(
                "🚫 %d client a été désactivé.",
                "🚫 %d clients ont été désactivés.",
                updated,
            )
            % updated,
            messages.SUCCESS,
        )

    deactivate_customers.short_description = "🚫 Désactiver les clients"

    def activate_customers(self, request, queryset):
        """Action pour activer les clients sélectionnés."""
        updated = queryset.update(is_active=True, updated_by=request.user)
        self.message_user(
            request,
            ngettext(
                "✅ %d client a été activé.",
                "✅ %d clients ont été activés.",
                updated,
            )
            % updated,
            messages.SUCCESS,
        )

    activate_customers.short_description = "✅ Activer les clients"

    # Optimisations et méthodes utilitaires
    def get_queryset(self, request):
        """Optimise les requêtes avec select_related et prefetch_related."""
        return (
            super()
            .get_queryset(request)
            .select_related("user", "created_by", "updated_by")
            .prefetch_related("identity_documents")
            .annotate(documents_count_annotation=Count("identity_documents"))
        )

    def save_model(self, request, obj, form, change):
        """Définit l'utilisateur qui effectue la modification."""
        if not change:  # Création
            obj.created_by = request.user
        obj.updated_by = request.user
        super().save_model(request, obj, form, change)

    def get_readonly_fields(self, request, obj=None):
        """Rend certains champs readonly selon les permissions."""
        readonly = list(self.readonly_fields)
        if not request.user.is_superuser:
            readonly.extend(["created_by", "updated_by"])
        return readonly
