from django.contrib import admin, messages
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth import get_user_model
from django.utils.translation import gettext_lazy as _

from .forms import UserProfileCreationForm, ModeratorUserCreationForm
from .models import PaymentReceipt, MembershipPeriod
from .emails import send_password_reset_email, send_account_activated_email
from django.utils import timezone


User = get_user_model()


@admin.register(User)
class UserProfileAdmin(BaseUserAdmin):
    """
    Administration for custom UserProfile.
    """
    add_form = UserProfileCreationForm
    form = UserProfileCreationForm
    model = User
    actions = ["send_password_creation_link", "activate_accounts"]
    
    list_display = (
        "email", "first_name", "last_name", "is_email_verified",
        "is_staff", "is_active", "is_membership_valid", 
        "is_validated_by_staff", "date_joined"
    )
    list_filter = (
        "is_staff", "is_active", "is_email_verified",
        "is_validated_by_staff", "is_superuser", "speciality"
    )
    search_fields = ("email", "first_name", "last_name", "phone_number", "membership_id")
    ordering = ("-date_joined",)
    readonly_fields = ("date_joined", "last_login", "membership_id")

    fieldsets = (
        (None, {"fields": ("email", "password")}),
        (_("Informations personnelles"), {
            "fields": (
                "first_name", "last_name", "speciality",
                "phone_number", "document", "profile_image","address",
                "membership_id", "qr_code"
            )
        }),
        (_("Statuts de vérification"), {
            "fields": (
                "is_email_verified", "is_validated_by_staff"
            )
        }),
        (_("Dates importantes et Adhésion"), {"fields": ("last_login", "date_joined", "membership_period")}),
        (_("Permissions"), {
            "fields": (
                "is_active", "is_staff", "is_superuser",
                "groups", "user_permissions"
            )
        }),
    )

    add_fieldsets = (
        (None, {
            "classes": ("wide",),
            "fields": (
                "email", "first_name", "last_name", "speciality",
                "phone_number", "document", "profile_image",
                "password1", "password2",
                "is_active", "is_staff", "is_superuser", "groups",
                "membership_period"
            ),
        }),
    )

    def get_form(self, request, obj=None, **kwargs):
        if request.user.groups.filter(name="Moderateur").exists():
            self.add_form = ModeratorUserCreationForm
            self.form = ModeratorUserCreationForm
        else:
            self.add_form = UserProfileCreationForm
            self.form = UserProfileCreationForm
        return super().get_form(request, obj, **kwargs)

    @admin.action(description="Envoyer le lien de création/réinitialisation de mot de passe")
    def send_password_creation_link(self, request, queryset):
        emails_sent = 0
        for user in queryset:
            try:
                send_password_reset_email(user)
                emails_sent += 1
            except Exception as e:
                self.message_user(
                    request,
                    f"❌ Erreur lors de l'envoi à {user.email}: {e}",
                    level=messages.ERROR,
                )

        if emails_sent > 0:
            self.message_user(
                request,
                f"✅ {emails_sent} e-mails envoyés avec succès.",
                level=messages.SUCCESS,
            )

    @admin.action(description="Activer les comptes et notifier par email")
    def activate_accounts(self, request, queryset):
        activated = 0
        current_period = MembershipPeriod.get_current()

        if not current_period:
            self.message_user(
                request,
                "❌ Aucune période d'adhésion active. Activez d'abord une "
                "MembershipPeriod avant d'activer des comptes.",
                level=messages.ERROR,
            )
            return

        for user in queryset:
            if user.is_active:
                continue
            if not user.has_paid_current_period:
                self.message_user(
                    request,
                    f"⚠️ {user.email} ignoré : aucun reçu validé pour la période "
                    f"'{current_period.label}'. Ajoutez un reçu lié à cette "
                    f"période et marquez-le 'Validé' avant d'activer.",
                    level=messages.WARNING,
                )
                continue
            user.is_active = True
            user.is_validated_by_staff = True
            user.membership_activated_at = timezone.now()
            user.membership_period = current_period
            user.save(update_fields=[
                'is_active', 'is_validated_by_staff',
                'membership_activated_at', 'membership_period',
            ])
            try:
                send_account_activated_email(user)
                activated += 1
            except Exception as e:
                self.message_user(
                    request,
                    f"❌ Erreur email pour {user.email}: {e}",
                    level=messages.ERROR,
                )

        self.message_user(
            request,
            f"✅ {activated} compte(s) activé(s) pour '{current_period.label}'.",
            level=messages.SUCCESS,
        )

    def save_model(self, request, obj, form, change):
        """
        Custom save logic to handle state changes and emails.
        """
        is_new = not change

        if change:
            old_obj = User.objects.get(pk=obj.pk)
            
            # Moderateurs cannot change active status
            if request.user.groups.filter(name="Moderateur").exists():
                obj.is_active = old_obj.is_active

            # Keep password if not changed in form
            if "password" not in form.changed_data:
                obj.password = old_obj.password

            # Check if just activated
            if not old_obj.is_active and obj.is_active:
                current_period = MembershipPeriod.get_current()
                if not current_period:
                    obj.is_active = False
                    self.message_user(
                        request,
                        f"❌ Activation refusée : aucune période d'adhésion "
                        f"active. Activez d'abord une MembershipPeriod.",
                        level=messages.ERROR,
                    )
                    super().save_model(request, obj, form, change)
                    return
                if not obj.has_paid_current_period:
                    obj.is_active = False
                    self.message_user(
                        request,
                        f"❌ Activation refusée pour {obj.email} : aucun reçu "
                        f"validé pour la période '{current_period.label}'. "
                        f"Ajoutez un reçu lié à cette période (rubrique "
                        f"'Reçus de paiement') et marquez-le 'Validé', "
                        f"puis réessayez.",
                        level=messages.ERROR,
                    )
                    super().save_model(request, obj, form, change)
                    return
                obj.is_validated_by_staff = True
                obj.membership_activated_at = timezone.now()
                if not obj.membership_period_id:
                    obj.membership_period = current_period
                super().save_model(request, obj, form, change)
                try:
                    send_account_activated_email(obj)
                except Exception:
                    pass
                return

        super().save_model(request, obj, form, change)


@admin.register(PaymentReceipt)
class PaymentReceiptAdmin(admin.ModelAdmin):
    list_display = (
        "user", "membership_period", "payment_date",
        "amount", "is_validated", "created_at",
    )
    list_filter = ("is_validated", "membership_period", "payment_date")
    list_select_related = ("user", "membership_period")
    search_fields = ["user__email", "user__first_name", "user__last_name"]
    autocomplete_fields = ["user"]
    actions = ["validate_payments"]

    def get_changeform_initial_data(self, request):
        """Pré-remplit le formulaire de création avec la période active."""
        initial = super().get_changeform_initial_data(request)
        current_period = MembershipPeriod.get_current()
        if current_period:
            initial.setdefault('membership_period', current_period.pk)
        return initial

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        """Force le champ membership_period à être requis dans le form admin."""
        if db_field.name == 'membership_period':
            kwargs['required'] = True
            kwargs.setdefault('empty_label', None)
        return super().formfield_for_foreignkey(db_field, request, **kwargs)

    @admin.action(description="Valider les paiements sélectionnés")
    def validate_payments(self, request, queryset):
        updated = queryset.update(is_validated=True)
        self.message_user(request, f"✅ {updated} reçus de paiement validés.", level=messages.SUCCESS)


@admin.register(MembershipPeriod)
class MembershipPeriodAdmin(admin.ModelAdmin):
    """
    Administration de la période d'adhésion globale.
    """
    list_display = ('label', 'start_date', 'end_date', 'is_active', 'is_expired', 'members_count', 'updated_at')
    list_filter = ('is_active',)
    search_fields = ('label',)
    readonly_fields = ('created_at', 'updated_at', 'members_count')
    actions = ['assign_active_members_to_period']

    fieldsets = (
        (None, {'fields': ('label', 'start_date', 'end_date', 'is_active')}),
        (_("Informations"), {'fields': ('members_count', 'created_at', 'updated_at')}),
    )

    def is_expired(self, obj):
        return obj.is_expired
    is_expired.boolean = True
    is_expired.short_description = "Expirée"

    def members_count(self, obj):
        return obj.members.count()
    members_count.short_description = "Nombre d'adhérents"

    @admin.action(description="Assigner tous les membres actifs à cette période")
    def assign_active_members_to_period(self, request, queryset):
        if queryset.count() != 1:
            self.message_user(request, "❌ Sélectionnez une seule période.", level=messages.ERROR)
            return
        period = queryset.first()
        updated = User.objects.filter(is_active=True).update(membership_period=period)
        self.message_user(
            request,
            f"✅ {updated} membres actifs assignés à '{period.label}'.",
            level=messages.SUCCESS,
        )