from django.contrib import admin
from django.utils.html import format_html
from django.urls import reverse
from django.db.models import Count

from .models import (
    UnidadMedida,
    FormaPago,
    EmpaqueCompra,
    EmpaqueProduccion,
    ClasificacionProducto,
    GrupoProducto,
    SubgrupoProducto
)

# Base Admin class con funcionalidades comunes
class BaseConfigAdmin(admin.ModelAdmin):
    """
    Clase base para todos los modelos de configuración
    Proporciona funcionalidades comunes como filtros, búsqueda y acciones
    """
    list_per_page = 20
    save_on_top = True
    show_full_result_count = True
    
    # Acción para duplicar registros
    actions = ['duplicate_selected']
    
    def duplicate_selected(self, request, queryset):
        count = 0
        for obj in queryset:
            obj.id = None
            obj.nombre = f"{obj.nombre} (Copia)"
            # Si tiene atributo abreviatura
            if hasattr(obj, 'abreviatura'):
                obj.abreviatura = f"{obj.abreviatura}_c"
            obj.save()
            count += 1
        
        self.message_user(request, f"{count} registros duplicados correctamente.")
    duplicate_selected.short_description = "Duplicar los registros seleccionados"
    
    # Muestra el número de registros asociados si hay una relación
    def get_queryset(self, request):
        qs = super().get_queryset(request)
        return qs


@admin.register(UnidadMedida)
class UnidadMedidaAdmin(BaseConfigAdmin):
    list_display = ['nombre', 'abreviatura', 'tipo', 'colored_tipo']
    list_filter = ['tipo']
    search_fields = ['nombre', 'abreviatura']
    list_display_links = ['nombre', 'abreviatura']
    fieldsets = [
        (None, {
            'fields': [('nombre', 'abreviatura'), 'tipo']
        }),
    ]
    
    def colored_tipo(self, obj):
        """Muestra el tipo con un color distintivo según su valor"""
        colors = {
            'peso': 'green',
            'longitud': 'blue',
            'volumen': 'purple',
            'unidad': 'orange',
        }
        color = colors.get(obj.tipo, 'gray')
        return format_html('<span style="color: {}; font-weight: bold;">{}</span>', 
                          color, obj.get_tipo_display())
    
    colored_tipo.short_description = "Tipo de Unidad"


@admin.register(FormaPago)
class FormaPagoAdmin(BaseConfigAdmin):
    list_display = ['nombre', 'plazo_dias', 'tipo_pago', 'descripcion_corta']
    list_filter = ['plazo_dias']
    search_fields = ['nombre', 'descripcion']
    fieldsets = [
        (None, {
            'fields': ['nombre', 'plazo_dias']
        }),
        ('Información Adicional', {
            'fields': ['descripcion'],
            'classes': ['collapse']
        }),
    ]
    
    def tipo_pago(self, obj):
        """Muestra si es contado o crédito con formato distintivo"""
        if obj.plazo_dias == 0:
            return format_html('<span style="background-color: #c8e6c9; padding: 3px 8px; border-radius: 4px; color: #2e7d32;">Contado</span>')
        else:
            return format_html('<span style="background-color: #ffcdd2; padding: 3px 8px; border-radius: 4px; color: #c62828;">Crédito</span>')
    
    tipo_pago.short_description = "Tipo"
    
    def descripcion_corta(self, obj):
        """Muestra una versión abreviada de la descripción"""
        if obj.descripcion and len(obj.descripcion) > 50:
            return f"{obj.descripcion[:50]}..."
        return obj.descripcion
    
    descripcion_corta.short_description = "Descripción"


@admin.register(EmpaqueCompra)
class EmpaqueCompraAdmin(BaseConfigAdmin):
    list_display = ['nombre', 'descripcion_corta']
    search_fields = ['nombre', 'descripcion']
    fieldsets = [
        (None, {
            'fields': ['nombre']
        }),
        ('Detalles', {
            'fields': ['descripcion'],
            'classes': ['collapse']
        }),
    ]
    
    def descripcion_corta(self, obj):
        """Muestra una versión abreviada de la descripción"""
        if obj.descripcion and len(obj.descripcion) > 50:
            return f"{obj.descripcion[:50]}..."
        return obj.descripcion
    
    descripcion_corta.short_description = "Descripción"


@admin.register(EmpaqueProduccion)
class EmpaqueProduccionAdmin(BaseConfigAdmin):
    list_display = ['nombre', 'descripcion_corta']
    search_fields = ['nombre', 'descripcion']
    fieldsets = [
        (None, {
            'fields': ['nombre']
        }),
        ('Detalles', {
            'fields': ['descripcion'],
            'classes': ['collapse']
        }),
    ]
    
    def descripcion_corta(self, obj):
        """Muestra una versión abreviada de la descripción"""
        if obj.descripcion and len(obj.descripcion) > 50:
            return f"{obj.descripcion[:50]}..."
        return obj.descripcion
    
    descripcion_corta.short_description = "Descripción"


@admin.register(ClasificacionProducto)
class ClasificacionProductoAdmin(BaseConfigAdmin):
    list_display = ['nombre']
    search_fields = ['nombre']


class SubgrupoInline(admin.TabularInline):
    model = SubgrupoProducto
    extra = 1
    verbose_name = "Subgrupo"
    verbose_name_plural = "Subgrupos"


@admin.register(GrupoProducto)
class GrupoProductoAdmin(BaseConfigAdmin):
    list_display = ['nombre', 'contar_subgrupos']
    search_fields = ['nombre']
    inlines = [SubgrupoInline]
    
    def get_queryset(self, request):
        qs = super().get_queryset(request)
        return qs.annotate(subgrupos_count=Count('subgrupos'))
    
    def contar_subgrupos(self, obj):
        """Muestra el número de subgrupos asociados a este grupo"""
        count = obj.subgrupos_count
        url = reverse('admin:listas_configuracion_subgrupoproducto_changelist') + f'?grupo__id__exact={obj.id}'
        return format_html('<a href="{}">{} subgrupo{}</a>', url, count, 's' if count != 1 else '')
    
    contar_subgrupos.short_description = "Subgrupos"
    contar_subgrupos.admin_order_field = 'subgrupos_count'


@admin.register(SubgrupoProducto)
class SubgrupoProductoAdmin(BaseConfigAdmin):
    list_display = ['nombre', 'grupo_link']
    list_filter = ['grupo']
    search_fields = ['nombre', 'grupo__nombre']
    autocomplete_fields = ['grupo']
    
    def grupo_link(self, obj):
        """Muestra un enlace al grupo al que pertenece este subgrupo"""
        url = reverse('admin:listas_configuracion_grupoproducto_change', args=[obj.grupo.id])
        return format_html('<a href="{}">{}</a>', url, obj.grupo)
    
    grupo_link.short_description = "Grupo"
    grupo_link.admin_order_field = 'grupo__nombre'


# Personalización a nivel de Admin Site
class ListasConfiguracionAdminSite(admin.AdminSite):
    site_header = "IAP Planner - Configuración"
    site_title = "Panel de Administración"
    index_title = "Gestión de Configuraciones"
    
    def each_context(self, request):
        context = super().each_context(request)
        context['categories'] = {
            'Unidades y Medidas': [
                {'name': 'Unidades de Medida', 'url': reverse('admin:listas_configuracion_unidadmedida_changelist')},
            ],
            'Pagos y Facturación': [
                {'name': 'Formas de Pago', 'url': reverse('admin:listas_configuracion_formapago_changelist')},
            ],
            'Empaques': [
                {'name': 'Empaques de Compra', 'url': reverse('admin:listas_configuracion_empaquecompra_changelist')},
                {'name': 'Empaques de Producción', 'url': reverse('admin:listas_configuracion_empaqueproduccion_changelist')},
            ],
            'Categorización de Productos': [
                {'name': 'Clasificaciones', 'url': reverse('admin:listas_configuracion_clasificacionproducto_changelist')},
                {'name': 'Grupos', 'url': reverse('admin:listas_configuracion_grupoproducto_changelist')},
                {'name': 'Subgrupos', 'url': reverse('admin:listas_configuracion_subgrupoproducto_changelist')},
            ],
        }
        return context


# Este es un ejemplo de cómo registrar todo con un admin site personalizado
# Para usar esto, necesitarías configurar tu urls.py adecuadamente
# listas_admin_site = ListasConfiguracionAdminSite(name='listas_admin')
# listas_admin_site.register(UnidadMedida, UnidadMedidaAdmin)
# listas_admin_site.register(FormaPago, FormaPagoAdmin)
# ... etc.
