from django.db import models
from datetime import date
from django.core.validators import MinValueValidator
from decimal import Decimal
from django.utils import timezone

# --- 1. Tablas de Catálogo de Metadatos ------------------------------------

class TipoActivo(models.Model):
    """Corresponde a la tabla `tipo_activo` (Portátil, Monitor, Mouse)."""
    
    nombre = models.CharField(max_length=100, unique=True)
    descripcion = models.TextField(null=True, blank=True)

    class Meta:
        db_table = 'tipo_activo'
        verbose_name = "Tipo de Activo"

    def __str__(self):
        return self.nombre

class Marca(models.Model):
    """Corresponde a la tabla `marcas` (Dell, Lenovo, Logitech)."""
    
    nombre = models.CharField(max_length=100, unique=True)
    descripcion = models.TextField(null=True, blank=True)

    class Meta:
        db_table = 'marcas'
        verbose_name_plural = "Marcas"

    def __str__(self):
        return self.nombre

class Modelo(models.Model):
    """Corresponde a la tabla `modelos` (ThinkPad X1, OptiPlex 3000)."""
    
    nombre = models.CharField(max_length=100, unique=True)
    descripcion = models.TextField(null=True, blank=True)

    class Meta:
        db_table = 'modelos'
        verbose_name_plural = "Modelos"

    def __str__(self):
        return self.nombre

# --- 2. Tabla Principal: Equipos (Inventario) --------------------------------

class Equipo(models.Model):
    """Corresponde a la tabla `equipos` (Inventario de activos)."""
    
    # ==================== RELACIONES ====================
    id_modelo = models.ForeignKey(Modelo, on_delete=models.SET_NULL, null=True, blank=True)
    id_marca = models.ForeignKey(Marca, on_delete=models.SET_NULL, null=True, blank=True)
    id_tipo_activo = models.ForeignKey(TipoActivo, on_delete=models.SET_NULL, null=True, blank=True)
    
    # ==================== IDENTIFICADORES ====================
    cod_activo = models.CharField(max_length=100, unique=True, db_index=True) 
    numero_activo = models.IntegerField(null=True, unique=True, db_index=True)
    serial = models.CharField(max_length=100, null=True, blank=True, db_index=True)
    asset_id = models.IntegerField(null=True, blank=True)
    uuid = models.CharField(max_length=100, null=True, blank=True, verbose_name="UUID")
    
    # ==================== ESPECIFICACIONES TÉCNICAS ====================
    ram = models.CharField(max_length=50, null=True, blank=True, verbose_name="RAM")
    disco = models.CharField(max_length=50, null=True, blank=True)
    procesador = models.CharField(max_length=100, null=True, blank=True)
    cpu_cores = models.IntegerField(null=True, blank=True, verbose_name="Núcleos CPU")
    descripcion = models.TextField(null=True, blank=True)
    
    # ==================== SISTEMA OPERATIVO ====================
    SO = models.CharField(max_length=100, null=True, blank=True, verbose_name="Sistema Operativo")
    version_so = models.CharField(max_length=50, null=True, blank=True, verbose_name="Versión SO")
    
    # ==================== ESTADO Y CLASIFICACIÓN ====================
    tipo = models.CharField(max_length=50, null=True, blank=True)
    estado_uso = models.CharField(
        max_length=50, 
        null=True, 
        blank=True,
        choices=[
            ('En Uso', 'En Uso'),
            ('Disponible', 'Disponible'),
            ('En Reparación', 'En Reparación'),
            ('Dado de Baja', 'Dado de Baja'),
            ('En Bodega', 'En Bodega'),
        ]
    )
    prestamo = models.BooleanField(default=False)
    impact = models.CharField(
        max_length=20,
        choices=[
            ('low', 'Bajo'),
            ('medium', 'Medio'),
            ('high', 'Alto'),
            ('critical', 'Crítico'),
        ],
        default='low',
        verbose_name="Nivel de Impacto",
        help_text="Criticidad del equipo para operaciones del negocio"
    )
    
    # ==================== INFORMACIÓN FINANCIERA ====================
    costo = models.DecimalField(
        max_digits=12, 
        decimal_places=2, 
        null=True, 
        blank=True,
        validators=[MinValueValidator(Decimal('0.01'))],
        verbose_name="Costo de Adquisición"
    )
    tipo_propiedad = models.CharField(
        max_length=50,
        choices=[
            ('Compra', 'Compra'),
            ('Arriendo', 'Arriendo'),
            ('Leasing', 'Leasing'),
            ('Comodato', 'Comodato'),
        ],
        null=True,
        blank=True,
        verbose_name="Tipo de Propiedad"
    )
    fecha_adquisicion = models.DateField(null=True, blank=True, verbose_name="Fecha de Adquisición")
    
    # Garantía/Leasing
    meses_garantia = models.IntegerField(
        null=True, 
        blank=True,
        validators=[MinValueValidator(0)],
        verbose_name="Meses de Garantía/Leasing"
    )
    fecha_vencimiento_garantia = models.DateField(
        null=True, 
        blank=True,
        verbose_name="Fecha Vencimiento Garantía/Leasing"
    )
    
    # ==================== UBICACIÓN ====================
    departamento = models.CharField(max_length=100, null=True, blank=True)
    ciudad = models.CharField(max_length=100, null=True, blank=True)
    sede = models.CharField(max_length=100, null=True, blank=True)
    bodega = models.CharField(max_length=100, null=True, blank=True)
    piso = models.CharField(max_length=50, null=True, blank=True)
    detalle_ubicacion = models.CharField(max_length=200, null=True, blank=True)
    
    # ==================== RED ====================
    IP = models.GenericIPAddressField(null=True, blank=True, verbose_name="Dirección IP")
    MAC = models.CharField(max_length=17, null=True, blank=True, verbose_name="Dirección MAC")
    hostName = models.CharField(max_length=100, null=True, blank=True, verbose_name="Hostname")
    dominio = models.CharField(max_length=100, null=True, blank=True)
    ultimo_login = models.CharField(
        max_length=100, 
        null=True, 
        blank=True,
        verbose_name="Último Usuario Login"
    )
    
    # ==================== AUDITORÍA ====================
    fecha_inv = models.DateField(default=date.today, verbose_name="Fecha de Inventario")
    fecha_ultima_auditoria = models.DateTimeField(
        null=True, 
        blank=True,
        verbose_name="Última Auditoría"
    )
    ruta_qr = models.CharField(max_length=255, null=True, blank=True)
    
    # ==================== METADATA ====================
    activo = models.BooleanField(default=True, verbose_name="Activo en Sistema")
    fecha_creacion = models.DateTimeField(
        auto_now_add=True,
        null=True,
        blank=True,
        verbose_name="Fecha de Creación"
    )
    fecha_actualizacion = models.DateTimeField(
        auto_now=True,
        null=True,
        blank=True,
        verbose_name="Última Actualización"
    )
    notas = models.TextField(null=True, blank=True, verbose_name="Notas Adicionales")

    class Meta:
        db_table = 'equipos'
        verbose_name_plural = "Equipos"
        ordering = ['-fecha_actualizacion']
        indexes = [
            models.Index(fields=['cod_activo']),
            models.Index(fields=['serial']),
            models.Index(fields=['estado_uso']),
            models.Index(fields=['impact']),
            models.Index(fields=['fecha_vencimiento_garantia']),
        ]

    def __str__(self):
        return f"{self.cod_activo} - {self.serial or 'Sin Serial'}"
    
    @property
    def garantia_activa(self):
        """Verifica si la garantía está vigente."""
        if self.fecha_vencimiento_garantia:
            return self.fecha_vencimiento_garantia >= date.today()
        return None
    
    @property
    def dias_hasta_vencimiento(self):
        """Calcula días restantes de garantía."""
        if self.fecha_vencimiento_garantia:
            delta = self.fecha_vencimiento_garantia - date.today()
            return delta.days if delta.days > 0 else 0
        return None
    
    @property
    def alerta_vencimiento(self):
        """Alerta si la garantía vence pronto (menos de 30 días)."""
        dias = self.dias_hasta_vencimiento
        if dias is not None and dias <= 30:
            return True
        return False
    
    @property
    def dias_sin_auditar(self):
        """Calcula días desde la última auditoría."""
        if self.fecha_ultima_auditoria:
            delta = date.today() - self.fecha_ultima_auditoria.date()
            return delta.days
        return None
    
    @property
    def requiere_auditoria(self):
        """Indica si necesita auditoría según días transcurridos."""
        dias = self.dias_sin_auditar
        
        if dias is None:  # Nunca auditado
            return True
        
        # Equipos críticos: cada 60 días
        if self.impact in ['critical', 'high'] and dias > 60:
            return True
        
        # Equipos normales: cada 180 días
        if dias > 180:
            return True
        
        return False
    
    def save(self, *args, **kwargs):
        # Normalizar MAC address
        if self.MAC:
            self.MAC = self.MAC.upper().replace('-', ':')
        super().save(*args, **kwargs)