"""
Админка для приложения inventory.
Все модели tenant-only, поэтому используют TenantAdminOnlyMixin
для скрытия от public admin (localhost/admin/).
"""
from django.contrib import admin
from django.utils.html import format_html
from django.urls import reverse
from django.db.models import Sum
from decimal import Decimal

from inventory.models import (
    Warehouse, StockBatch, Sale, WriteOff,
    Inventory, InventoryLine, Reservation, Stock,
    SaleBatchAllocation, Showcase, WriteOffDocument, WriteOffDocumentItem,
    IncomingDocument, IncomingDocumentItem, Transformation, TransformationInput,
    TransformationOutput, TransferDocument, TransferDocumentItem
)
from tenants.admin_mixins import TenantAdminOnlyMixin


# ===== SHOWCASE =====
@admin.register(Showcase)
class ShowcaseAdmin(TenantAdminOnlyMixin, admin.ModelAdmin):
    list_display = ('name', 'warehouse', 'is_default', 'is_active', 'created_at')
    list_filter = ('is_active', 'is_default', 'warehouse', 'created_at')
    search_fields = ('name', 'warehouse__name')
    date_hierarchy = 'created_at'
    fieldsets = (
        ('Основная информация', {
            'fields': ('name', 'warehouse', 'description', 'is_active', 'is_default')
        }),
        ('Даты', {
            'fields': ('created_at', 'updated_at'),
            'classes': ('collapse',)
        }),
    )
    readonly_fields = ('created_at', 'updated_at')

    def delete_model(self, request, obj):
        """
        Защита от удаления последней активной витрины склада через админку.
        Рекомендуется использовать деактивацию (is_active=False) вместо удаления.
        """
        from django.contrib import messages

        # Проверка: это последняя активная витрина склада?
        active_showcases_count = Showcase.objects.filter(
            warehouse=obj.warehouse,
            is_active=True
        ).count()

        if active_showcases_count <= 1 and obj.is_active:
            messages.error(
                request,
                f'Невозможно удалить последнюю активную витрину склада "{obj.warehouse.name}" через админку. '
                'Используйте деактивацию (is_active=False) вместо удаления.'
            )
            return

        super().delete_model(request, obj)

    def delete_queryset(self, request, queryset):
        """
        Защита от массового удаления всех витрин склада через админку.
        """
        from django.contrib import messages

        # Группируем витрины по складам
        warehouses = {}
        for showcase in queryset:
            if showcase.warehouse_id not in warehouses:
                warehouses[showcase.warehouse_id] = {
                    'warehouse': showcase.warehouse,
                    'deleting_active': 0,
                    'total_active': Showcase.objects.filter(
                        warehouse=showcase.warehouse,
                        is_active=True
                    ).count()
                }
            if showcase.is_active:
                warehouses[showcase.warehouse_id]['deleting_active'] += 1

        # Проверяем, не удаляем ли мы все витрины какого-либо склада
        for wh_data in warehouses.values():
            remaining = wh_data['total_active'] - wh_data['deleting_active']
            if remaining < 1:
                messages.error(
                    request,
                    f'Невозможно удалить все витрины склада "{wh_data["warehouse"].name}". '
                    'Хотя бы одна активная витрина должна остаться на каждом складе.'
                )
                return

        super().delete_queryset(request, queryset)


# ===== WAREHOUSE =====
@admin.register(Warehouse)
class WarehouseAdmin(TenantAdminOnlyMixin, admin.ModelAdmin):
    list_display = ('name', 'is_default_display', 'is_active', 'created_at')
    list_filter = ('is_active', 'is_default', 'created_at')
    search_fields = ('name',)
    fieldsets = (
        ('Основная информация', {
            'fields': ('name', 'description', 'is_active', 'is_default')
        }),
        ('Даты', {
            'fields': ('created_at', 'updated_at'),
            'classes': ('collapse',)
        }),
    )
    readonly_fields = ('created_at', 'updated_at')

    def is_default_display(self, obj):
        if obj.is_default:
            return format_html('<span style="color: #ff9900; font-weight: bold;">★ По умолчанию</span>')
        return '-'
    is_default_display.short_description = 'По умолчанию'

    def delete_model(self, request, obj):
        """
        Защита от удаления последнего активного склада через админку.
        Рекомендуется использовать деактивацию (is_active=False) вместо удаления.
        """
        from django.contrib import messages

        # Проверка: это последний активный склад?
        active_warehouses_count = Warehouse.objects.filter(is_active=True).count()

        if active_warehouses_count <= 1 and obj.is_active:
            messages.error(
                request,
                'Невозможно удалить последний активный склад через админку. '
                'Система требует наличия хотя бы одного активного склада для работы. '
                'Используйте деактивацию (is_active=False) вместо удаления.'
            )
            return

        super().delete_model(request, obj)

    def delete_queryset(self, request, queryset):
        """
        Защита от массового удаления всех складов через админку.
        """
        from django.contrib import messages

        # Подсчитываем текущее количество активных складов
        active_count = Warehouse.objects.filter(is_active=True).count()
        # Подсчитываем, сколько активных складов хотим удалить
        deleting_active_count = queryset.filter(is_active=True).count()

        # Проверяем, останется ли хотя бы один активный склад
        if active_count - deleting_active_count < 1:
            messages.error(
                request,
                'Невозможно удалить все активные склады. '
                'Система требует наличия хотя бы одного активного склада для работы. '
                'Используйте деактивацию (is_active=False) вместо удаления.'
            )
            return

        super().delete_queryset(request, queryset)


# ===== STOCK BATCH =====
@admin.register(StockBatch)
class StockBatchAdmin(TenantAdminOnlyMixin, admin.ModelAdmin):
    list_display = ('product', 'warehouse', 'quantity_display', 'cost_price', 'created_at', 'is_active')
    list_filter = ('warehouse', 'is_active', 'created_at')
    search_fields = ('product__name', 'product__sku', 'warehouse__name')
    date_hierarchy = 'created_at'
    fieldsets = (
        ('Партия', {
            'fields': ('product', 'warehouse', 'quantity', 'is_active')
        }),
        ('Финансы', {
            'fields': ('cost_price',)
        }),
        ('Даты', {
            'fields': ('created_at', 'updated_at'),
            'classes': ('collapse',)
        }),
    )
    readonly_fields = ('created_at', 'updated_at')

    def quantity_display(self, obj):
        if obj.quantity <= 0:
            color = '#ff0000'  # красный
        elif obj.quantity < 10:
            color = '#ff9900'  # оранжевый
        else:
            color = '#008000'  # зелёный

        return format_html(
            '<span style="color: {}; font-weight: bold;">{}</span>',
            color,
            f'{obj.quantity} шт'
        )
    quantity_display.short_description = 'Количество'


# ===== SALE BATCH ALLOCATION (INLINE) =====
class SaleBatchAllocationInline(admin.TabularInline):
    model = SaleBatchAllocation
    extra = 0
    readonly_fields = ('batch', 'quantity', 'cost_price')
    can_delete = False
    fields = ('batch', 'quantity', 'cost_price')


# ===== SALE =====
@admin.register(Sale)
class SaleAdmin(TenantAdminOnlyMixin, admin.ModelAdmin):
    list_display = ('product', 'warehouse', 'quantity', 'sale_price', 'order_display', 'processed_display', 'date')
    list_filter = ('warehouse', 'processed', 'date')
    search_fields = ('product__name', 'order__order_number')
    date_hierarchy = 'date'
    fieldsets = (
        ('Продажа', {
            'fields': ('product', 'warehouse', 'quantity', 'sale_price', 'order')
        }),
        ('Статус', {
            'fields': ('processed',)
        }),
        ('Документ', {
            'fields': ('document_number',)
        }),
        ('Дата', {
            'fields': ('date',),
            'classes': ('collapse',)
        }),
    )
    readonly_fields = ('date',)
    inlines = [SaleBatchAllocationInline]

    def order_display(self, obj):
        if obj.order:
            return f"ORD-{obj.order.order_number}"
        return "-"
    order_display.short_description = 'Заказ'

    def processed_display(self, obj):
        if obj.processed:
            return format_html('<span style="color: green;">✓ Обработана</span>')
        return format_html('<span style="color: red;">✗ Ожидает</span>')
    processed_display.short_description = 'Статус'


# ===== WRITE OFF =====
@admin.register(WriteOff)
class WriteOffAdmin(TenantAdminOnlyMixin, admin.ModelAdmin):
    list_display = ('batch', 'quantity', 'reason_display', 'cost_price', 'date')
    list_filter = ('reason', 'date', 'batch__warehouse')
    search_fields = ('batch__product__name', 'document_number')
    date_hierarchy = 'date'
    fieldsets = (
        ('Списание', {
            'fields': ('batch', 'quantity', 'reason', 'cost_price')
        }),
        ('Документ', {
            'fields': ('document_number', 'notes')
        }),
        ('Дата', {
            'fields': ('date',),
            'classes': ('collapse',)
        }),
    )
    readonly_fields = ('date', 'cost_price')

    def reason_display(self, obj):
        return obj.get_reason_display()
    reason_display.short_description = 'Причина'


# ===== INVENTORY LINE (INLINE) =====
class InventoryLineInline(admin.TabularInline):
    model = InventoryLine
    extra = 1
    fields = ('product', 'quantity_system', 'quantity_fact', 'difference', 'processed')
    readonly_fields = ('difference', 'processed')


# ===== INVENTORY =====
@admin.register(Inventory)
class InventoryAdmin(TenantAdminOnlyMixin, admin.ModelAdmin):
    list_display = ('warehouse', 'status_display', 'date', 'conducted_by')
    list_filter = ('status', 'date', 'warehouse')
    search_fields = ('warehouse__name', 'conducted_by')
    date_hierarchy = 'date'
    fieldsets = (
        ('Инвентаризация', {
            'fields': ('warehouse', 'status', 'conducted_by', 'notes')
        }),
        ('Дата', {
            'fields': ('date',),
            'classes': ('collapse',)
        }),
    )
    readonly_fields = ('date',)
    inlines = [InventoryLineInline]
    actions = ['process_inventory']

    def status_display(self, obj):
        colors = {
            'draft': '#ff9900',      # оранжевый
            'processing': '#0099ff', # синий
            'completed': '#008000'   # зелёный
        }
        return format_html(
            '<span style="color: {}; font-weight: bold;">{}</span>',
            colors.get(obj.status, '#000000'),
            obj.get_status_display()
        )
    status_display.short_description = 'Статус'

    def process_inventory(self, request, queryset):
        from inventory.services import InventoryProcessor

        for inventory in queryset:
            result = InventoryProcessor.process_inventory(inventory.id)
            msg_parts = [
                f"Инвентаризация {inventory.warehouse.name}: "
                f"обработано {result['processed_lines']} строк."
            ]
            
            if result.get('writeoff_document'):
                msg_parts.append(
                    f"Создан документ списания: {result['writeoff_document'].document_number} (черновик)."
                )
            
            if result.get('incoming_document'):
                msg_parts.append(
                    f"Создан документ оприходования: {result['incoming_document'].document_number} (черновик)."
                )
            
            self.message_user(request, ' '.join(msg_parts))

    process_inventory.short_description = 'Обработать инвентаризацию'


# ===== RESERVATION =====
@admin.register(Reservation)
class ReservationAdmin(TenantAdminOnlyMixin, admin.ModelAdmin):
    list_display = ('product', 'warehouse', 'quantity', 'status_display', 'context_info', 'reserved_at')
    list_filter = ('status', 'reserved_at', 'warehouse', 'showcase')
    search_fields = ('product__name', 'order_item__order__order_number', 'showcase__name')
    date_hierarchy = 'reserved_at'
    fieldsets = (
        ('Резерв', {
            'fields': ('product', 'warehouse', 'quantity', 'status', 'order_item', 'showcase')
        }),
        ('Даты', {
            'fields': ('reserved_at', 'released_at', 'converted_at')
        }),
    )
    readonly_fields = ('reserved_at', 'released_at', 'converted_at')

    def status_display(self, obj):
        colors = {
            'reserved': '#0099ff',         # синий
            'released': '#ff0000',         # красный
            'converted_to_sale': '#008000' # зелёный
        }
        return format_html(
            '<span style="color: {}; font-weight: bold;">{}</span>',
            colors.get(obj.status, '#000000'),
            obj.get_status_display()
        )
    status_display.short_description = 'Статус'

    def context_info(self, obj):
        if obj.order_item:
            return format_html(
                '<span style="color: #0066cc;">📎 Заказ ORD-{}</span>',
                obj.order_item.order.order_number
            )
        elif obj.showcase:
            return format_html(
                '<span style="color: #ff9900;">🌺 Витрина: {}</span>',
                obj.showcase.name
            )
        return "-"
    context_info.short_description = 'Контекст'


# ===== STOCK =====
@admin.register(Stock)
class StockAdmin(TenantAdminOnlyMixin, admin.ModelAdmin):
    list_display = ('product', 'warehouse', 'quantity_available', 'quantity_reserved', 'quantity_free', 'updated_at')
    list_filter = ('warehouse', 'updated_at')
    search_fields = ('product__name', 'product__sku', 'warehouse__name')
    fieldsets = (
        ('Остаток', {
            'fields': ('product', 'warehouse', 'quantity_available', 'quantity_reserved')
        }),
        ('Дата', {
            'fields': ('updated_at',),
            'classes': ('collapse',)
        }),
    )
    readonly_fields = ('quantity_available', 'quantity_reserved', 'updated_at')


# ===== WRITEOFF DOCUMENT (документы списания) =====
class WriteOffDocumentItemInline(admin.TabularInline):
    model = WriteOffDocumentItem
    extra = 0
    fields = ('product', 'quantity', 'reason', 'notes', 'reservation')
    readonly_fields = ('reservation',)
    raw_id_fields = ('product',)


@admin.register(WriteOffDocument)
class WriteOffDocumentAdmin(TenantAdminOnlyMixin, admin.ModelAdmin):
    list_display = ('document_number', 'warehouse', 'status_display', 'date', 'items_count', 'total_quantity_display', 'created_by', 'created_at')
    list_filter = ('status', 'warehouse', 'date', 'created_at')
    search_fields = ('document_number', 'warehouse__name')
    date_hierarchy = 'date'
    readonly_fields = ('document_number', 'created_at', 'updated_at', 'confirmed_at', 'confirmed_by')
    inlines = [WriteOffDocumentItemInline]

    fieldsets = (
        ('Документ', {
            'fields': ('document_number', 'warehouse', 'status', 'date', 'notes')
        }),
        ('Аудит', {
            'fields': ('created_by', 'created_at', 'confirmed_by', 'confirmed_at', 'updated_at'),
            'classes': ('collapse',)
        }),
    )

    def status_display(self, obj):
        colors = {
            'draft': '#ff9900',
            'confirmed': '#008000',
            'cancelled': '#ff0000',
        }
        return format_html(
            '<span style="color: {}; font-weight: bold;">{}</span>',
            colors.get(obj.status, '#000000'),
            obj.get_status_display()
        )
    status_display.short_description = 'Статус'

    def items_count(self, obj):
        return obj.items.count()
    items_count.short_description = 'Позиций'

    def total_quantity_display(self, obj):
        return f"{obj.total_quantity} шт"
    total_quantity_display.short_description = 'Всего'


@admin.register(WriteOffDocumentItem)
class WriteOffDocumentItemAdmin(TenantAdminOnlyMixin, admin.ModelAdmin):
    list_display = ('document', 'product', 'quantity', 'reason', 'created_at')
    list_filter = ('reason', 'document__status', 'created_at')
    search_fields = ('product__name', 'document__document_number')
    raw_id_fields = ('product', 'document', 'reservation')


# ===== INCOMING DOCUMENT (документы поступления) =====
class IncomingDocumentItemInline(admin.TabularInline):
    model = IncomingDocumentItem
    extra = 0
    fields = ('product', 'quantity', 'cost_price', 'notes')
    raw_id_fields = ('product',)


@admin.register(IncomingDocument)
class IncomingDocumentAdmin(TenantAdminOnlyMixin, admin.ModelAdmin):
    list_display = ('document_number', 'warehouse', 'status_display', 'receipt_type_display', 'date', 'items_count', 'total_quantity_display', 'created_by', 'created_at')
    list_filter = ('status', 'warehouse', 'receipt_type', 'date', 'created_at')
    search_fields = ('document_number', 'warehouse__name', 'supplier_name')
    date_hierarchy = 'date'
    readonly_fields = ('document_number', 'created_at', 'updated_at', 'confirmed_at', 'confirmed_by')
    inlines = [IncomingDocumentItemInline]

    fieldsets = (
        ('Документ', {
            'fields': ('document_number', 'warehouse', 'status', 'date', 'receipt_type', 'supplier_name', 'notes')
        }),
        ('Аудит', {
            'fields': ('created_by', 'created_at', 'confirmed_by', 'confirmed_at', 'updated_at'),
            'classes': ('collapse',)
        }),
    )

    def status_display(self, obj):
        colors = {
            'draft': '#ff9900',
            'confirmed': '#008000',
            'cancelled': '#ff0000',
        }
        return format_html(
            '<span style="color: {}; font-weight: bold;">{}</span>',
            colors.get(obj.status, '#000000'),
            obj.get_status_display()
        )
    status_display.short_description = 'Статус'

    def receipt_type_display(self, obj):
        colors = {
            'supplier': '#0d6efd',
            'inventory': '#0dcaf0',
            'adjustment': '#198754',
        }
        return format_html(
            '<span style="color: {}; font-weight: bold;">{}</span>',
            colors.get(obj.receipt_type, '#6c757d'),
            obj.get_receipt_type_display()
        )
    receipt_type_display.short_description = 'Тип поступления'

    def items_count(self, obj):
        return obj.items.count()
    items_count.short_description = 'Позиций'

    def total_quantity_display(self, obj):
        return f"{obj.total_quantity} шт"
    total_quantity_display.short_description = 'Всего'


@admin.register(IncomingDocumentItem)
class IncomingDocumentItemAdmin(TenantAdminOnlyMixin, admin.ModelAdmin):
    list_display = ('document', 'product', 'quantity', 'cost_price', 'total_cost_display', 'created_at')
    list_filter = ('document__status', 'document__receipt_type', 'created_at')
    search_fields = ('product__name', 'document__document_number')
    raw_id_fields = ('product', 'document')

    def total_cost_display(self, obj):
        return f"{obj.total_cost:.2f}"
    total_cost_display.short_description = 'Сумма'


# ===== TRANSFORMATION =====

class TransformationInputInline(admin.TabularInline):
    model = TransformationInput
    extra = 1
    fields = ['product', 'quantity']
    autocomplete_fields = ['product']


class TransformationOutputInline(admin.TabularInline):
    model = TransformationOutput
    extra = 1
    fields = ['product', 'quantity', 'stock_batch']
    autocomplete_fields = ['product']
    readonly_fields = ['stock_batch']


@admin.register(Transformation)
class TransformationAdmin(TenantAdminOnlyMixin, admin.ModelAdmin):
    list_display = ['document_number', 'warehouse', 'status_display', 'date', 'employee', 'inputs_count', 'outputs_count']
    list_filter = ['status', 'warehouse', 'date']
    search_fields = ['document_number', 'comment']
    readonly_fields = ['document_number', 'date', 'created_at', 'updated_at']
    inlines = [TransformationInputInline, TransformationOutputInline]
    autocomplete_fields = ['warehouse', 'employee']

    fieldsets = (
        ('Основная информация', {
            'fields': ('document_number', 'warehouse', 'status', 'employee')
        }),
        ('Детали', {
            'fields': ('comment', 'date', 'created_at', 'updated_at')
        }),
    )

    def save_model(self, request, obj, form, change):
        if not obj.pk:
            # Генерируем номер документа при создании
            from inventory.models import DocumentCounter
            next_num = DocumentCounter.get_next_value('transformation')
            obj.document_number = f"TR-{next_num:05d}"
            obj.employee = request.user
        super().save_model(request, obj, form, change)

    def status_display(self, obj):
        colors = {
            'draft': '#6c757d',
            'completed': '#28a745',
            'cancelled': '#dc3545',
        }
        return format_html(
            '<span style="color: {}; font-weight: bold;">{}</span>',
            colors.get(obj.status, '#6c757d'),
            obj.get_status_display()
        )
    status_display.short_description = 'Статус'

    def inputs_count(self, obj):
        return obj.inputs.count()
    inputs_count.short_description = 'Входов'

    def outputs_count(self, obj):
        return obj.outputs.count()
    outputs_count.short_description = 'Выходов'
