from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin
from django.utils import timezone


class SoftDeleteQuerySet(models.QuerySet):
    def delete(self):
        """Soft delete en lote"""
        return super().update(deleted_at=timezone.now())

    def hard_delete(self):
        """Borrado físico en lote"""
        return super().delete()

    def alive(self):
        return self.filter(deleted_at__isnull=True)

    def dead(self):
        return self.exclude(deleted_at__isnull=True)


class SoftDeleteManager(models.Manager):
    def get_queryset(self):
        # Por defecto solo devuelve no eliminados
        return SoftDeleteQuerySet(self.model, using=self._db).alive()


class Department(models.Model):
    """Department Model"""
    name = models.CharField(max_length=100, unique=True, verbose_name="Nombre del departamento")
    description = models.TextField(blank=True, null=True, verbose_name="Descripción")
    created_at = models.DateTimeField(auto_now_add=True)

    # Soft delete
    deleted_at = models.DateTimeField(null=True, blank=True)

    # Managers
    objects = SoftDeleteManager()
    all_objects = SoftDeleteQuerySet.as_manager()

    class Meta:
        verbose_name = "Departamento"
        verbose_name_plural = "Departamentos"
        ordering = ["name"]

    def __str__(self):
        return self.name

    def delete(self, using=None, keep_parents=False):
        """Soft delete"""
        self.deleted_at = timezone.now()
        self.save(update_fields=["deleted_at"])

    def hard_delete(self, using=None, keep_parents=False):
        """Borrado físico"""
        super().delete(using=using, keep_parents=keep_parents)

    def restore(self):
        """Restaurar un departamento eliminado"""
        self.deleted_at = None
        self.save(update_fields=["deleted_at"])


class UserManager(BaseUserManager):
    """Custom user manager con soporte para soft delete"""

    def get_queryset(self):
        return SoftDeleteQuerySet(self.model, using=self._db).alive()

    def create_user(self, email, password=None, **extra_fields):
        """Create and save a regular user"""
        if not email:
            raise ValueError('El email es obligatorio')

        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password=None, **extra_fields):
        """Create and save a superuser"""
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        extra_fields.setdefault('is_active', True)

        # Esto asegura que los superusuarios puedan hacer todo
        for perm_field in [
            'can_add_documents', 'can_create_folders', 'can_download',
            'can_share_by_email',
            'can_view', 'can_edit_folders', 'can_edit_documents',
            'can_delete_documents', 'can_delete_folders', 'can_create_users'
        ]:
            extra_fields.setdefault(perm_field, True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('Superuser must have is_staff=True.')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')

        return self.create_user(email, password, **extra_fields)


class User(AbstractBaseUser, PermissionsMixin):
    """Custom user model with granular permissions and soft delete"""

    department = models.ForeignKey(
        'Department',
        on_delete=models.PROTECT,
        null=True, blank=True,
        related_name='users',
        verbose_name='Departamento'
    )

    email = models.EmailField(unique=True, verbose_name='Correo electrónico')
    name = models.CharField(max_length=255, verbose_name='Nombre')

    # Granular permissions
    can_add_documents = models.BooleanField(default=False, verbose_name='Puede agregar documentos')
    can_create_folders = models.BooleanField(default=False, verbose_name='Puede crear carpetas')
    can_download = models.BooleanField(default=False, verbose_name='Puede descargar')
    can_share_by_email = models.BooleanField(default=False, verbose_name='Puede compartir por email')
    can_view = models.BooleanField(default=True, verbose_name='Puede visualizar')
    can_edit_folders = models.BooleanField(default=False, verbose_name='Puede editar carpetas')
    can_edit_documents = models.BooleanField(default=False, verbose_name='Puede editar documentos')
    can_delete_documents = models.BooleanField(default=False, verbose_name='Puede eliminar documentos')
    can_delete_folders = models.BooleanField(default=False, verbose_name='Puede eliminar carpetas')
    can_create_users = models.BooleanField(default=False, verbose_name='Puede crear usuarios')

    # Django required fields
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    date_joined = models.DateTimeField(auto_now_add=True)

    # Soft delete
    deleted_at = models.DateTimeField(null=True, blank=True)

    # Managers
    objects = UserManager()
    all_objects = SoftDeleteQuerySet.as_manager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['name']

    class Meta:
        verbose_name = 'Usuario'
        verbose_name_plural = 'Usuarios'
        ordering = ['-date_joined']

    def __str__(self):
        return self.email

    def get_permissions_dict(self):
        """Return a dictionary of user permissions"""
        return {
            'can_add_documents': self.can_add_documents,
            'can_create_folders': self.can_create_folders,
            'can_download': self.can_download,
            'can_share_by_email': self.can_share_by_email,
            'can_view': self.can_view,
            'can_edit_folders': self.can_edit_folders,
            'can_edit_documents': self.can_edit_documents,
            'can_delete_documents': self.can_delete_documents,
            'can_delete_folders': self.can_delete_folders,
            'can_create_users': self.can_create_users,
        }

    def delete(self, using=None, keep_parents=False):
        """Soft delete"""
        self.deleted_at = timezone.now()
        self.save(update_fields=["deleted_at"])

    def hard_delete(self, using=None, keep_parents=False):
        """Borrado físico"""
        super().delete(using=using, keep_parents=keep_parents)

    def restore(self):
        """Restaurar un usuario eliminado"""
        self.deleted_at = None
        self.save(update_fields=["deleted_at"])
