"""
Smooth Schedule Core Models
Multi-tenancy, Domain management, and Permission Grant system
"""
from django.db import models
from django.utils import timezone
from django_tenants.models import TenantMixin, DomainMixin
from datetime import timedelta


class Tenant(TenantMixin):
    """
    Tenant model for multi-schema architecture.
    Each tenant gets their own PostgreSQL schema for complete data isolation.
    """
    name = models.CharField(max_length=100)
    created_on = models.DateField(auto_now_add=True)
    
    # Subscription & billing
    is_active = models.BooleanField(default=True)
    subscription_tier = models.CharField(
        max_length=50,
        choices=[
            ('FREE', 'Free Trial'),
            ('STARTER', 'Starter'),
            ('PROFESSIONAL', 'Professional'),
            ('ENTERPRISE', 'Enterprise'),
        ],
        default='FREE'
    )
    
    # Feature flags
    max_users = models.IntegerField(default=5)
    max_resources = models.IntegerField(default=10)
    
    # Metadata
    contact_email = models.EmailField(blank=True)
    phone = models.CharField(max_length=20, blank=True)
    
    # Auto-created fields from TenantMixin:
    # - schema_name (unique, indexed)
    # - auto_create_schema
    # - auto_drop_schema
    
    class Meta:
        ordering = ['name']
        
    def __str__(self):
        return self.name


class Domain(DomainMixin):
    """
    Domain model for tenant routing.
    Supports both subdomain (tenant.chronoflow.com) and custom domains.
    """
    # Inherited from DomainMixin:
    # - domain (unique, primary key)
    # - tenant (ForeignKey to Tenant)
    # - is_primary (boolean)
    
    # Route53 integration fields for custom domains
    is_custom_domain = models.BooleanField(
        default=False,
        help_text="True if this is a custom domain (not a subdomain of smoothschedule.com)"
    )
    
    route53_zone_id = models.CharField(
        max_length=100,
        blank=True,
        null=True,
        help_text="AWS Route53 Hosted Zone ID for this custom domain"
    )
    
    route53_record_set_id = models.CharField(
        max_length=100,
        blank=True,
        null=True,
        help_text="Route53 Record Set ID for DNS verification"
    )
    
    # SSL certificate management (for future AWS ACM integration)
    ssl_certificate_arn = models.CharField(
        max_length=200,
        blank=True,
        null=True,
        help_text="AWS ACM Certificate ARN for HTTPS"
    )
    
    verified_at = models.DateTimeField(
        null=True,
        blank=True,
        help_text="When the custom domain was verified via DNS"
    )
    
    class Meta:
        ordering = ['domain']
    
    def __str__(self):
        domain_type = "Custom" if self.is_custom_domain else "Subdomain"
        return f"{self.domain} ({domain_type})"
    
    def is_verified(self):
        """Check if custom domain is verified"""
        if not self.is_custom_domain:
            return True  # Subdomains are always verified
        return self.verified_at is not None


class PermissionGrant(models.Model):
    """
    Time-limited permission grants (30-minute window).
    Used for temporary elevated access without permanently changing user permissions.
    
    Example use cases:
    - Support agent needs temporary access to tenant data
    - Sales demo requiring elevated permissions
    - Cross-tenant operations during migrations
    """
    grantor = models.ForeignKey(
        'users.User',
        on_delete=models.CASCADE,
        related_name='granted_permissions',
        help_text="User who granted the permission"
    )
    
    grantee = models.ForeignKey(
        'users.User',
        on_delete=models.CASCADE,
        related_name='received_permissions',
        help_text="User who received the permission"
    )
    
    action = models.CharField(
        max_length=100,
        help_text="Specific action or permission being granted (e.g., 'view_billing', 'edit_settings')"
    )
    
    reason = models.TextField(
        blank=True,
        help_text="Justification for granting this permission (audit trail)"
    )
    
    granted_at = models.DateTimeField(auto_now_add=True)
    
    expires_at = models.DateTimeField(
        help_text="When this permission grant expires"
    )
    
    revoked_at = models.DateTimeField(
        null=True,
        blank=True,
        help_text="If manually revoked before expiration"
    )
    
    # Audit metadata
    ip_address = models.GenericIPAddressField(
        null=True,
        blank=True,
        help_text="IP address where grant was created"
    )
    
    user_agent = models.TextField(
        blank=True,
        help_text="Browser/client user agent"
    )
    
    class Meta:
        ordering = ['-granted_at']
        indexes = [
            models.Index(fields=['grantee', 'expires_at']),
            models.Index(fields=['grantor', 'granted_at']),
        ]
    
    def __str__(self):
        return f"{self.grantor} → {self.grantee}: {self.action} (expires {self.expires_at})"
    
    def is_active(self):
        """
        Check if this permission grant is currently active.
        Returns False if expired or revoked.
        """
        now = timezone.now()
        
        # Check if revoked
        if self.revoked_at is not None:
            return False
        
        # Check if expired
        if now >= self.expires_at:
            return False
        
        return True
    
    def revoke(self):
        """Manually revoke this permission grant"""
        if self.revoked_at is None:
            self.revoked_at = timezone.now()
            self.save(update_fields=['revoked_at'])
    
    def time_remaining(self):
        """Get timedelta of remaining active time (or None if expired/revoked)"""
        if not self.is_active():
            return None
        
        now = timezone.now()
        return self.expires_at - now
    
    @classmethod
    def create_grant(cls, grantor, grantee, action, reason="", duration_minutes=30, ip_address=None, user_agent=""):
        """
        Factory method to create a time-limited permission grant.
        
        Args:
            grantor: User granting the permission
            grantee: User receiving the permission
            action: Permission action string
            reason: Justification for audit trail
            duration_minutes: How long the grant is valid (default 30)
            ip_address: IP address of the request
            user_agent: Browser user agent
        
        Returns:
            PermissionGrant instance
        """
        now = timezone.now()
        expires_at = now + timedelta(minutes=duration_minutes)
        
        return cls.objects.create(
            grantor=grantor,
            grantee=grantee,
            action=action,
            reason=reason,
            expires_at=expires_at,
            ip_address=ip_address,
            user_agent=user_agent
        )


class TierLimit(models.Model):
    """
    Defines resource limits for each subscription tier.
    Used by HasQuota permission to enforce hard blocks.
    """
    tier = models.CharField(
        max_length=50,
        choices=[
            ('FREE', 'Free Trial'),
            ('STARTER', 'Starter'),
            ('PROFESSIONAL', 'Professional'),
            ('ENTERPRISE', 'Enterprise'),
        ]
    )
    
    feature_code = models.CharField(
        max_length=100,
        help_text="Feature code (e.g., 'MAX_RESOURCES', 'MAX_USERS')"
    )
    
    limit = models.IntegerField(
        default=0,
        help_text="Maximum allowed count for this feature"
    )
    
    class Meta:
        unique_together = ['tier', 'feature_code']
        ordering = ['tier', 'feature_code']
    
    def __str__(self):
        return f"{self.tier} - {self.feature_code}: {self.limit}"

