from django.contrib import admin
from django.contrib.admin import action
from django.utils.safestring import mark_safe
from . import models, services


class StockAdminBase(admin.ModelAdmin):
    """库存管理基础类，定义通用配置"""

    def get_list_filter(self, request):
        result = super().get_list_filter(request)
        result = list(result) + ['created_at']
        return result

@admin.register(models.Inventory)
class InventoryAdmin(StockAdminBase):
    list_display = (
        'id',
        'product',
        'product_color',
        'warehouse',
        'quantity',
        'num_of_rolls',
        'frozen_quantity',
        'updated_at',
    )
    search_fields = ('product__name', 'warehouse__name')
    list_filter = ('warehouse',)
    ordering = ('-updated_at',)

    @admin.display(description='冻结中数量')
    def frozen_quantity(self, obj):
        return services.get_frozen_stock_count(
            product_id=obj.product_id,
            warehouse_id=obj.warehouse_id
        )

    @admin.display(description='颜色')
    def product_color(self, obj):
        return obj.product.color


@admin.register(models.StockSnapshot)
class StockSnapshotAdmin(admin.ModelAdmin):
    list_display = (
        'id',
        'product__name',
        'warehouse__name',
        'delta',
        'quantity_before',
        'quantity_after',
        'stock_change_record',
        'created_at',
    )
    search_fields = ('product', 'warehouse', 'stock_change_record__id')
    list_filter = ('stock_change_record__type',)
    ordering = ('-created_at', )

    def has_add_permission(self, request):
        # 禁止通过admin界面添加库存快照
        return False

    def has_change_permission(self, request, obj = ...):
        # 禁止通过admin界面修改库存快照
        return False

    def has_delete_permission(self, request, obj = ...):
        # 禁止通过admin界面删除库存快照
        return True

    def get_readonly_fields(self, request, obj = ...):
        # 所有字段均为只读
        return [field.name for field in self.model._meta.fields]


@admin.register(models.StockChangeDetail)
class StockChangeDetailAdmin(admin.ModelAdmin):
    list_display = (
        'id',
        'stock_change_record',
        'product',
        'quantity',
        'direction',
        'consume_with',
        'consumer',
        'unit',
    )
    search_fields = ('stock_change_record__id', 'product__name')
    list_filter = ('stock_change_record', 'stock_change_record__type', 'is_consumed')
    ordering = ('-created_at',)

    @admin.display(description='消耗者')
    def consumer(self, obj: models.StockChangeDetail):
        return obj.consumed_by_detail

    @admin.display(description='出入方向')
    def direction(self, obj):
        return '入库' if obj.stock_change_record.is_incoming else '出库'


@admin.register(models.StockChangeRecord)
class StockChangeRecordAdmin(admin.ModelAdmin):
    list_display = (
        'id',
        'type',
        'warehouse',
        'details',
        'source_type',
        'source_id',
        'num_of_rolls',
        'is_finished',
        'finished_at',
        'created_by',
        'created_at',
    )
    search_fields = ('warehouse__name', 'source_id')
    list_filter = ('type', 'source_type', 'type', 'is_finished', 'created_at')
    ordering = ('-created_at', '-updated_at')
    readonly_fields = ('created_by', 'is_finished', 'finished_at')

    def save_model(self, request, obj: models.StockChangeRecord, form, change):
        if not change:
            if obj.is_finished is True:
                # Prevent setting is_finished to True on creation
                obj.is_finished = False
            if not obj.created_by:
                # 新建记录时，设置创建人
                obj.created_by = request.user
        return super().save_model(request, obj, form, change)

    @action(description='标记选中的库存变动记录为已完成')
    def make_selected_stock_changes_completed(self, request, queryset):
        if queryset.count() > 1:
            self.message_user(request, '一次只能处理一条库存变动记录。', level='error')
            return
        record = queryset.first()
        services.make_stock_change_completed(record)

    @admin.display(description='匹数')
    def num_of_rolls(self, obj: models.StockChangeRecord):
        return obj.num_of_rolls

    @admin.display(description='明细概览')
    def details(self, obj):
        details = obj.details.all()
        detail_list = [
            f'{detail.product.name}, {detail.quantity}/{detail.get_unit_display()}'
            for detail in details
        ]
        return mark_safe('<br>'.join(detail_list))

    actions = [make_selected_stock_changes_completed]


@admin.register(models.StockFreeze)
class StockFreezeAdmin(admin.ModelAdmin):
    list_display = (
        'id',
        'product',
        'warehouse',
        'quantity',
        'reason',
        'created_at',
    )
    readonly_fields = (
        'frozen_by',
        'created_at',
        'updated_at',
        'cancelled_at',
        'cancelled_by',
        'completed_at',
        'completed_by',
        'completed_with',
    )
    search_fields = ('product__name', 'warehouse__name', 'reason')
    list_filter = ('warehouse', 'created_at')
    ordering = ('-created_at',)
