"""
Smooth Schedule Custom User Model
Implements strict role hierarchy and multi-tenant user management
"""
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.utils.translation import gettext_lazy as _


class User(AbstractUser):
    """
    Custom User model with strict role-based access control.
    Replaces Django's default User model.
    """
    
    # Role Choices - Strict Hierarchy
    class Role(models.TextChoices):
        # Platform-level roles (access across all tenants)
        SUPERUSER = 'SUPERUSER', _('Platform Superuser')
        PLATFORM_MANAGER = 'PLATFORM_MANAGER', _('Platform Manager')
        PLATFORM_SALES = 'PLATFORM_SALES', _('Platform Sales')
        PLATFORM_SUPPORT = 'PLATFORM_SUPPORT', _('Platform Support')
        
        # Tenant-level roles (access within single tenant)
        TENANT_OWNER = 'TENANT_OWNER', _('Tenant Owner')
        TENANT_MANAGER = 'TENANT_MANAGER', _('Tenant Manager')
        TENANT_STAFF = 'TENANT_STAFF', _('Tenant Staff')
        
        # Customer role (end users of the tenant)
        CUSTOMER = 'CUSTOMER', _('Customer')
    
    # Core fields
    role = models.CharField(
        max_length=20,
        choices=Role.choices,
        default=Role.CUSTOMER,
        help_text="User's role in the system hierarchy"
    )
    
    # For multi-tenancy: link users to their tenant
    # Note: This is only for tenant-level users. Platform users can access all tenants.
    tenant = models.ForeignKey(
        'core.Tenant',
        on_delete=models.CASCADE,
        null=True,
        blank=True,
        related_name='users',
        help_text="Tenant this user belongs to (null for platform-level users)"
    )
    
    # Special flags
    is_temporary = models.BooleanField(
        default=False,
        help_text="True for sales demo accounts - can be masqueraded by Platform Sales"
    )
    
    # Additional profile fields
    phone = models.CharField(max_length=20, blank=True)
    job_title = models.CharField(max_length=100, blank=True)
    
    # Metadata
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    last_login_ip = models.GenericIPAddressField(null=True, blank=True)
    
    class Meta:
        ordering = ['email']
        indexes = [
            models.Index(fields=['role', 'tenant']),
            models.Index(fields=['email', 'is_active']),
        ]
    
    def __str__(self):
        return f"{self.email} ({self.get_role_display()})"
    
    def is_platform_user(self):
        """Check if user has platform-level access"""
        return self.role in [
            self.Role.SUPERUSER,
            self.Role.PLATFORM_MANAGER,
            self.Role.PLATFORM_SALES,
            self.Role.PLATFORM_SUPPORT,
        ]
    
    def is_tenant_user(self):
        """Check if user is tenant-scoped"""
        return self.role in [
            self.Role.TENANT_OWNER,
            self.Role.TENANT_MANAGER,
            self.Role.TENANT_STAFF,
            self.Role.CUSTOMER,
        ]
    
    def can_manage_users(self):
        """Check if user can manage other users"""
        return self.role in [
            self.Role.SUPERUSER,
            self.Role.PLATFORM_MANAGER,
            self.Role.TENANT_OWNER,
            self.Role.TENANT_MANAGER,
        ]
    
    def can_access_billing(self):
        """Check if user can access billing information"""
        return self.role in [
            self.Role.SUPERUSER,
            self.Role.PLATFORM_MANAGER,
            self.Role.TENANT_OWNER,
        ]
    
    def get_accessible_tenants(self):
        """
        Get list of tenants this user can access.
        Platform users can access all tenants.
        Tenant users can only access their own tenant.
        """
        from core.models import Tenant
        
        if self.is_platform_user():
            return Tenant.objects.all()
        elif self.tenant:
            return Tenant.objects.filter(pk=self.tenant.pk)
        else:
            return Tenant.objects.none()
    
    def save(self, *args, **kwargs):
        """
        Override save to enforce business rules
        """
        # Superusers must be staff and have is_superuser flag
        if self.role == self.Role.SUPERUSER:
            self.is_staff = True
            self.is_superuser = True
        
        # Platform users should not be tied to a tenant
        if self.is_platform_user():
            self.tenant = None
        
        # Tenant users must have a tenant
        if self.is_tenant_user() and not self.tenant:
            raise ValueError(f"Users with role {self.role} must be assigned to a tenant")
        
        super().save(*args, **kwargs)
