from django.contrib import admin
from django.utils.translation import gettext_lazy as _
from .models import (
    CardTemplate, Card, CardBatch, CardUsageLog,
    ClothingAttributes, PropAttributes, SongAttributes,
    DanceAttributes, FurnitureAttributes, DecorationAttributes
)
from django.utils import timezone
import uuid
import secrets
import string

# Register your models here.

class ClothingAttributesInline(admin.StackedInline):
    model = ClothingAttributes
    can_delete = False
    verbose_name = '服装属性'
    verbose_name_plural = '服装属性'

class PropAttributesInline(admin.StackedInline):
    model = PropAttributes
    can_delete = False
    verbose_name = '道具属性'
    verbose_name_plural = '道具属性'

class SongAttributesInline(admin.StackedInline):
    model = SongAttributes
    can_delete = False
    verbose_name = '音乐属性'
    verbose_name_plural = '音乐属性'

class DanceAttributesInline(admin.StackedInline):
    model = DanceAttributes
    can_delete = False
    verbose_name = '舞蹈属性'
    verbose_name_plural = '舞蹈属性'

class FurnitureAttributesInline(admin.StackedInline):
    model = FurnitureAttributes
    can_delete = False
    verbose_name = '家具属性'
    verbose_name_plural = '家具属性'

class DecorationAttributesInline(admin.StackedInline):
    model = DecorationAttributes
    can_delete = False
    verbose_name = '装饰属性'
    verbose_name_plural = '装饰属性'

@admin.register(CardTemplate)
class CardTemplateAdmin(admin.ModelAdmin):
    list_display = ('name', 'category', 'rarity', 'card_type', 'status', 'price', 'created_at')
    list_filter = ('category', 'rarity', 'card_type', 'status')
    search_fields = ('name', 'description')
    ordering = ('-created_at',)
    readonly_fields = ('published_at',)

    def get_inlines(self, request, obj=None):
        if obj is None:
            return []
        
        category_to_inline = {
            'clothing': ClothingAttributesInline,
            'prop': PropAttributesInline,
            'song': SongAttributesInline,
            'dance': DanceAttributesInline,
            'furniture': FurnitureAttributesInline,
            'decoration': DecorationAttributesInline,
        }
        
        if obj.category in category_to_inline:
            return [category_to_inline[obj.category]]
        return []

    fieldsets = (
        ('基本信息', {
            'fields': ('name', 'category', 'description')
        }),
        ('类型和稀有度', {
            'fields': ('card_type', 'rarity')
        }),
        ('资源信息', {
            'fields': ('image', 'model_url', 'model_version')
        }),
        ('发布信息', {
            'fields': ('status', 'published_at', 'price')
        }),
    )

    actions = ['publish_templates', 'archive_templates']

    class Meta:
        verbose_name = '卡片模板'
        verbose_name_plural = '卡片模板管理'

    def publish_templates(self, request, queryset):
        count = 0
        for template in queryset.filter(status='draft'):
            template.publish()
            count += 1
        self.message_user(request, f'成功发布 {count} 个卡片模板')
    publish_templates.short_description = '发布选中的卡片模板'

    def archive_templates(self, request, queryset):
        count = 0
        for template in queryset.filter(status='published'):
            template.archive()
            count += 1
        self.message_user(request, f'成功归档 {count} 个卡片模板')
    archive_templates.short_description = '归档选中的卡片模板'


class CardUsageLogInline(admin.TabularInline):
    model = CardUsageLog
    extra = 0
    readonly_fields = ('user', 'action', 'details', 'old_status', 'new_status', 'created_at', 'ip_address')
    can_delete = False
    max_num = 10
    verbose_name = _("使用记录")
    verbose_name_plural = _("使用记录")

    def has_add_permission(self, request, obj=None):
        return False


@admin.register(Card)
class CardAdmin(admin.ModelAdmin):
    list_display = ('unique_id', 'name', 'template', 'category', 'status', 'user', 'used_at', 'manufactured')
    list_filter = ('template', 'category', 'status', 'manufactured')
    search_fields = ('unique_id', 'name', 'user__username')
    ordering = ('-created_at',)
    readonly_fields = ('unique_id', 'manufactured_at', 'used_at', 'batch')
    inlines = [CardUsageLogInline]

    fieldsets = (
        ('基本信息', {
            'fields': ('unique_id', 'template', 'name', 'category', 'description', 'price', 'batch')
        }),
        ('状态信息', {
            'fields': ('status', 'manufactured', 'manufactured_at', 'user', 'used_at')
        }),
    )

    class Meta:
        verbose_name = '卡片'
        verbose_name_plural = '卡片管理'

    def save_model(self, request, obj, form, change):
        # Log changes to the card
        if change:  # If this is an update
            old_obj = self.model.objects.get(pk=obj.pk)
            if old_obj.status != obj.status:
                CardUsageLog.objects.create(
                    card=obj,
                    user=request.user if hasattr(request, 'user') else None,
                    action='update',
                    details=f"状态从 {old_obj.get_status_display()} 变更为 {obj.get_status_display()}",
                    old_status=old_obj.status,
                    new_status=obj.status,
                    ip_address=self.get_client_ip(request)
                )
        else:  # If this is a new card
            # 如果是新卡片且没有unique_id，生成一个
            if not obj.unique_id:
                obj.unique_id = self.generate_unique_id()
            
            CardUsageLog.objects.create(
                card=obj,
                user=request.user if hasattr(request, 'user') else None,
                action='create',
                details="卡片创建",
                old_status='',
                new_status=obj.status,
                ip_address=self.get_client_ip(request)
            )
        
        super().save_model(request, obj, form, change)
    
    def get_client_ip(self, request):
        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
        if x_forwarded_for:
            ip = x_forwarded_for.split(',')[0]
        else:
            ip = request.META.get('REMOTE_ADDR')
        return ip
    
    def generate_unique_id(self, length=16):
        """
        生成一个唯一、不可预测的卡片标识
        """
        alphabet = string.ascii_letters + string.digits
        while True:
            # 生成一个随机字符串
            unique_id = ''.join(secrets.choice(alphabet) for _ in range(length))
            
            # 确保唯一
            if not Card.objects.filter(unique_id=unique_id).exists():
                return unique_id


@admin.register(CardBatch)
class CardBatchAdmin(admin.ModelAdmin):
    list_display = ('batch_number', 'template', 'category', 'quantity', 'status', 'exported', 'sent_to_production', 'published')
    list_filter = ('template', 'category', 'status', 'exported', 'sent_to_production', 'published')
    search_fields = ('batch_number', 'description')
    ordering = ('-created_at',)
    readonly_fields = ('batch_number', 'exported_at', 'production_date', 'published_at')

    fieldsets = (
        ('基本信息', {
            'fields': ('batch_number', 'template', 'category', 'quantity', 'description')
        }),
        ('状态信息', {
            'fields': ('status', 'exported', 'exported_at', 'sent_to_production', 'production_date', 'published', 'published_at', 'excel_file')
        }),
    )

    actions = ['mark_batches_manufactured', 'publish_batches']

    class Meta:
        verbose_name = '卡片批次'
        verbose_name_plural = '卡片批次管理'

    def save_model(self, request, obj, form, change):
        if not change:  # If this is a new batch
            # Generate batch number if not provided
            if not obj.batch_number:
                obj.batch_number = f"B{timezone.now().strftime('%Y%m%d%H%M%S')}"
        
        super().save_model(request, obj, form, change)
    
    def mark_batches_manufactured(self, request, queryset):
        count = 0
        for batch in queryset.filter(sent_to_production=False, exported=True):
            batch.mark_produced()
            count += 1
        self.message_user(request, f'成功标记 {count} 个批次为已生产')
    mark_batches_manufactured.short_description = '标记选中的批次为已生产'
    
    def publish_batches(self, request, queryset):
        count = 0
        for batch in queryset.filter(published=False, sent_to_production=True):
            batch.publish()
            count += 1
        self.message_user(request, f'成功发布 {count} 个批次')
    publish_batches.short_description = '发布选中的批次'


@admin.register(CardUsageLog)
class CardUsageLogAdmin(admin.ModelAdmin):
    list_display = ('card', 'user', 'action', 'created_at', 'ip_address')
    list_filter = ('action', 'created_at')
    search_fields = ('card__unique_id', 'user__username', 'ip_address')
    ordering = ('-created_at',)
    readonly_fields = ('card', 'user', 'action', 'details', 'old_status', 'new_status', 'ip_address', 'created_at')

    class Meta:
        verbose_name = '卡片使用记录'
        verbose_name_plural = '卡片使用记录管理'

    def has_add_permission(self, request):
        return False
    
    def has_change_permission(self, request, obj=None):
        return False
