from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
import uuid
from django.utils import timezone
from .validators import validate_video_file_extension, validate_video_file_size

class Profile(models.Model):
    USER_TYPES = [
        ('regular', 'Regular User'),
        ('premium', 'Premium User'),
        ('admin', 'Administrator'),
    ]
    
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    user_type = models.CharField(max_length=20, choices=USER_TYPES, default='regular')
    bio = models.TextField(blank=True)
    phone_number = models.CharField(max_length=15, blank=True)
    profile_image = models.ImageField(upload_to='profile_images/', null=True, blank=True)
    email_verified = models.BooleanField(default=False)
    two_factor_enabled = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    
    # Notification preferences
    email_notifications = models.BooleanField(default=True)
    push_notifications = models.BooleanField(default=True)
    
    # Professional fields
    company = models.CharField(max_length=100, blank=True)
    job_title = models.CharField(max_length=100, blank=True)
    location = models.CharField(max_length=100, blank=True)
    
    def __str__(self):
        return f"{self.user.username} ({self.get_user_type_display()})"
    
    @property
    def is_admin(self):
        return self.user_type == 'admin' or self.user.is_staff or self.user.is_superuser
    
    @property
    def is_premium(self):
        return self.user_type == 'premium'
    
    @property
    def is_regular(self):
        return self.user_type == 'regular'


@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        # Determine user type based on Django user permissions
        user_type = 'regular'
        if instance.is_superuser:
            user_type = 'admin'
        elif instance.is_staff:
            user_type = 'admin'
            
        Profile.objects.create(user=instance, user_type=user_type)

@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
    try:
        profile = instance.profile
        # Update user type if Django permissions changed
        if instance.is_superuser or instance.is_staff:
            if profile.user_type != 'admin':
                profile.user_type = 'admin'
                profile.save()
    except Profile.DoesNotExist:
        # Determine user type based on Django user permissions
        user_type = 'regular'
        if instance.is_superuser:
            user_type = 'admin'
        elif instance.is_staff:
            user_type = 'admin'
        Profile.objects.create(user=instance, user_type=user_type)


class PasswordReset(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    token = models.UUIDField(default=uuid.uuid4, unique=True)
    created_at = models.DateTimeField(auto_now_add=True)
    expires_at = models.DateTimeField()
    used = models.BooleanField(default=False)
    
    def __str__(self):
        return f"Password reset for {self.user.email}"
    
    def is_expired(self):
        return timezone.now() > self.expires_at
    
    def is_valid(self):
        return not self.used and not self.is_expired()


class SubscriptionPlan(models.Model):
    """Model to define subscription plans"""
    PLAN_TYPES = [
        ('practitioner', 'Practitioner'),
        ('patient', 'Patient'),
    ]
    
    name = models.CharField(max_length=100)
    plan_type = models.CharField(max_length=20, choices=PLAN_TYPES)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    duration_days = models.IntegerField(default=365)  # Default 1 year
    description = models.TextField(blank=True)
    stripe_price_id = models.CharField(max_length=100, blank=True)
    is_active = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    
    def __str__(self):
        return f"{self.name} - ${self.price}/year"


class Subscription(models.Model):
    """Model to track user subscriptions"""
    STATUS_CHOICES = [
        ('active', 'Active'),
        ('cancelled', 'Cancelled'),
        ('expired', 'Expired'),
        ('pending', 'Pending'),
    ]
    
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='subscriptions')
    plan = models.ForeignKey(SubscriptionPlan, on_delete=models.PROTECT)
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending')
    stripe_subscription_id = models.CharField(max_length=100, blank=True)
    stripe_customer_id = models.CharField(max_length=100, blank=True)
    start_date = models.DateTimeField(null=True, blank=True)
    end_date = models.DateTimeField(null=True, blank=True)
    auto_renew = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    
    class Meta:
        ordering = ['-created_at']
    
    def __str__(self):
        return f"{self.user.username} - {self.plan.name} ({self.status})"
    
    @property
    def is_active(self):
        if self.status != 'active':
            return False
        if self.end_date and timezone.now() > self.end_date:
            return False
        return True
    
    @property
    def days_remaining(self):
        if self.end_date and self.is_active:
            delta = self.end_date - timezone.now()
            return max(0, delta.days)
        return 0


class Payment(models.Model):
    """Model to track payment transactions"""
    PAYMENT_STATUS = [
        ('pending', 'Pending'),
        ('completed', 'Completed'),
        ('failed', 'Failed'),
        ('refunded', 'Refunded'),
    ]
    
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='payments')
    subscription = models.ForeignKey(Subscription, on_delete=models.SET_NULL, null=True, blank=True)
    amount = models.DecimalField(max_digits=10, decimal_places=2)
    currency = models.CharField(max_length=3, default='USD')
    status = models.CharField(max_length=20, choices=PAYMENT_STATUS, default='pending')
    stripe_payment_intent_id = models.CharField(max_length=100, blank=True)
    stripe_charge_id = models.CharField(max_length=100, blank=True)
    payment_method = models.CharField(max_length=50, default='stripe')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    
    class Meta:
        ordering = ['-created_at']
    
    def __str__(self):
        return f"{self.user.username} - ${self.amount} ({self.status})"


class DashboardCard(models.Model):
    """Model for dashboard cards/items that can be managed by admins"""
    title = models.CharField(max_length=200, help_text="Card title")
    description = models.TextField(blank=True, help_text="Optional description")
    image = models.ImageField(upload_to='dashboard_cards/', blank=True, null=True, help_text="Card image (required)")
    video = models.FileField(
        upload_to='dashboard_videos/', 
        blank=True, 
        null=True, 
        help_text="Card video (MP4, WebM, Ogg formats, max 1GB, optional)",
        validators=[validate_video_file_extension, validate_video_file_size]
    )
    link = models.URLField(blank=True, help_text="External link when card is clicked")
    order = models.IntegerField(default=0, help_text="Display order (lower numbers first)")
    is_active = models.BooleanField(default=True, help_text="Show/hide this card")
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    
    class Meta:
        ordering = ['order', '-created_at']
        verbose_name = 'Dashboard Card'
        verbose_name_plural = 'Dashboard Cards'
    
    def __str__(self):
        return self.title
    
    def get_image_url(self):
        """Return image URL"""
        if self.image:
            return self.image.url
        return '/static/images/bigdeal.png'
        
    def get_video_url(self):
        """Return video URL"""
        if self.video:
            return self.video.url
        return ''
        
    def has_video(self):
        """Check if card has a video"""
        return bool(self.video)