from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as DjangoUserAdmin
from django.contrib import messages
from django.db import transaction
from django.db.models import Count, Q
from .enrollment import issue_course_access
from .forms import AdminUserChangeForm, AdminUserCreationForm
from .models import User, Student, Category, Instructor, Course, Enrollment, Headline, Video, CourseFile, Order, Review

admin.site.site_header = "مدیریت آکادمی"
admin.site.site_title = "پنل مدیریت"
admin.site.index_title = "مدیریت کاربران و دوره‌ها"

class HeadlineInline(admin.TabularInline):
    model = Headline
    extra = 1

class VideoInline(admin.TabularInline):
    model = Video
    extra = 0
    fields = ('order', 'title', 'headline', 'player_url', 'duration', 'is_preview_free', 'is_active')
    ordering = ('headline__order', 'order')
    show_change_link = True
    verbose_name = 'ویدیو دوره'
    verbose_name_plural = 'ویدیوهای دوره — پس از ساخت سرفصل‌ها، ویدیوها را به تعداد دلخواه اضافه کنید'

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == 'headline':
            object_id = request.resolver_match.kwargs.get('object_id') if request.resolver_match else None
            if object_id:
                kwargs['queryset'] = Headline.objects.filter(course_id=object_id)
            else:
                kwargs['queryset'] = Headline.objects.none()
        return super().formfield_for_foreignkey(db_field, request, **kwargs)

class CourseFileInline(admin.TabularInline):
    model = CourseFile
    extra = 1

@admin.register(User)
class UserAdmin(DjangoUserAdmin):
    form = AdminUserChangeForm
    add_form = AdminUserCreationForm
    list_display = ('phone', 'name', 'email', 'is_staff', 'is_active', 'date_joined')
    search_fields = ('phone', 'name', 'email')
    list_filter = ('is_staff', 'is_active', 'date_joined')
    ordering = ('-date_joined',)
    readonly_fields = ('date_joined', 'last_login')
    fieldsets = (
        (None, {'fields': ('phone', 'password')}),
        ('اطلاعات فردی', {'fields': ('name', 'email', 'avatar_url')}),
        ('دسترسی‌ها', {'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions')}),
        ('تاریخ‌ها', {'fields': ('last_login', 'date_joined')}),
    )
    add_fieldsets = ((None, {'classes': ('wide',), 'fields': ('phone', 'password1', 'password2', 'is_staff', 'is_active')}),)


class ActiveCourseFilter(admin.SimpleListFilter):
    title = 'دوره فعال'
    parameter_name = 'active_course'

    def lookups(self, request, model_admin):
        return Course.objects.filter(is_hidden=False).values_list('id', 'name')

    def queryset(self, request, queryset):
        return queryset.filter(enrollments__course_id=self.value()).distinct() if self.value() else queryset


class StudentEnrollmentInline(admin.TabularInline):
    model = Enrollment
    fk_name = 'user'
    extra = 1
    autocomplete_fields = ('course',)
    fields = ('course', 'source', 'created_at')
    readonly_fields = ('created_at',)
    verbose_name = 'دوره فعال'
    verbose_name_plural = 'دوره‌های فعال دانشجو — برای فعال‌سازی، یک دوره جدید انتخاب و ذخیره کنید'


@admin.register(Student)
class StudentAdmin(admin.ModelAdmin):
    form = AdminUserChangeForm
    list_display = ('phone', 'name', 'email', 'active_course_count', 'active_course_names', 'is_active', 'date_joined')
    list_display_links = ('phone', 'name')
    search_fields = ('phone', 'name', 'email', 'enrollments__course__name')
    list_filter = (ActiveCourseFilter, 'is_active', 'date_joined')
    readonly_fields = ('date_joined', 'last_login', 'active_course_names')
    fields = ('phone', 'name', 'email', 'is_active', 'active_course_names', 'last_login', 'date_joined')
    inlines = (StudentEnrollmentInline,)
    ordering = ('-date_joined',)
    list_per_page = 30

    def get_queryset(self, request):
        return super().get_queryset(request).filter(Q(is_staff=False) | Q(enrollments__isnull=False)).distinct().prefetch_related('enrollments__course').annotate(course_total=Count('enrollments', distinct=True))

    @admin.display(description='تعداد دوره فعال', ordering='course_total')
    def active_course_count(self, obj):
        return obj.course_total

    @admin.display(description='دوره‌های فعال')
    def active_course_names(self, obj):
        names = [item.course.name for item in obj.enrollments.all()]
        return '، '.join(names) if names else 'بدون دوره فعال'

    def has_add_permission(self, request):
        return False

@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
    list_display = ('name', 'slug', 'icon')
    prepopulated_fields = {'slug': ('name',)}

@admin.register(Instructor)
class InstructorAdmin(admin.ModelAdmin):
    list_display = ('name', 'title', 'rating', 'students_count')
    search_fields = ('name', 'title')

@admin.register(Course)
class CourseAdmin(admin.ModelAdmin):
    list_display = ('name', 'category', 'instructor', 'price', 'discount_price', 'admin_discount_percent', 'level', 'is_featured', 'is_hidden')
    list_filter = ('is_featured', 'is_hidden', 'level', 'category', 'instructor')
    search_fields = ('name', 'course_id', 'description')
    prepopulated_fields = {'slug': ('name',)}
    inlines = [HeadlineInline, VideoInline, CourseFileInline]
    save_on_top = True
    fieldsets = (
        ('اطلاعات اصلی', {'fields': ('name', 'slug', 'course_id', 'category', 'instructor', 'tagline', 'description')}),
        ('قیمت و تخفیف', {'fields': ('is_free', 'price', 'discount_price'), 'description': 'مبلغ‌ها را به تومان وارد کنید. قیمت با تخفیف باید از قیمت اصلی کمتر باشد.'}),
        ('نمایش دوره', {'fields': ('cover_image', 'cover_url', 'demo_video_url', 'level', 'duration', 'badge_text', 'is_featured', 'is_hidden')}),
        ('آمار', {'fields': ('rating', 'enrolled_count')}),
    )

    @admin.display(description='درصد تخفیف')
    def admin_discount_percent(self, obj):
        return f'{obj.discount_percent}٪' if obj.discount_percent else '—'

@admin.register(Headline)
class HeadlineAdmin(admin.ModelAdmin):
    list_display = ('title', 'course', 'order')
    list_filter = ('course',)
    search_fields = ('title', 'course__name')
    inlines = [VideoInline]

@admin.register(Video)
class VideoAdmin(admin.ModelAdmin):
    list_display = ('order', 'title', 'course', 'headline', 'player_url', 'is_preview_free', 'is_active')
    list_filter = ('course', 'is_preview_free', 'is_active')
    search_fields = ('title', 'course__name')
    list_editable = ('is_preview_free', 'is_active')
    autocomplete_fields = ('course', 'headline')
    ordering = ('course', 'headline__order', 'order')

@admin.register(CourseFile)
class CourseFileAdmin(admin.ModelAdmin):
    list_display = ('title', 'course', 'file_size')
    list_filter = ('course',)

@admin.register(Order)
class OrderAdmin(admin.ModelAdmin):
    list_display = ('id', 'user', 'course', 'amount', 'status', 'gateway_reference', 'short_payment_error', 'created_at')
    list_filter = ('status', 'created_at')
    search_fields = ('user__phone', 'user__name', 'course__name', 'transaction_id')
    readonly_fields = ('created_at', 'gateway_authority', 'gateway_reference', 'payment_error', 'gateway_response')
    actions = ('approve_orders', 'reject_orders')

    @admin.display(description='خطای پرداخت')
    def short_payment_error(self, obj):
        return obj.payment_error[:60] if obj.payment_error else '—'

    def save_model(self, request, obj, form, change):
        super().save_model(request, obj, form, change)
        if obj.status == 'Completed':
            issue_course_access(obj)

    @admin.action(description='تأیید سفارش‌ها و صدور دسترسی دوره')
    def approve_orders(self, request, queryset):
        count = 0
        with transaction.atomic():
            for order in queryset.select_related('user', 'course'):
                if order.status != 'Completed':
                    order.status = 'Completed'
                    order.save(update_fields=['status'])
                issue_course_access(order)
                count += 1
        self.message_user(request, f'{count} سفارش تأیید و دسترسی آن صادر شد.', messages.SUCCESS)

    @admin.action(description='رد کردن سفارش‌های انتخاب‌شده')
    def reject_orders(self, request, queryset):
        updated = queryset.exclude(status='Completed').update(status='Failed')
        self.message_user(request, f'{updated} سفارش رد شد.', messages.WARNING)

@admin.register(Review)
class ReviewAdmin(admin.ModelAdmin):
    list_display = ('student_name', 'student_title', 'course', 'rating', 'created_at')
    list_filter = ('rating', 'course')
    search_fields = ('student_name', 'comment')
