from django.db import models
from django.core.exceptions import ValidationError
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin
from django.utils import timezone
from .phone import normalize_phone

class UserManager(BaseUserManager):
    def create_user(self, phone, password=None, **extra_fields):
        if not phone:
            raise ValueError('The Phone Number must be set')
        user = self.model(phone=normalize_phone(phone), **extra_fields)
        if password:
            user.set_password(password)
        else:
            user.set_unusable_password()
        user.save(using=self._db)
        return user

    def create_superuser(self, phone, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        return self.create_user(phone, password, **extra_fields)

class User(AbstractBaseUser, PermissionsMixin):
    phone = models.CharField(max_length=15, unique=True, verbose_name="Phone Number")
    name = models.CharField(max_length=100, blank=True, verbose_name="Full Name")
    email = models.EmailField(blank=True, verbose_name="Email Address")
    avatar_url = models.CharField(max_length=500, blank=True, verbose_name="Avatar URL")
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    date_joined = models.DateTimeField(default=timezone.now)

    objects = UserManager()

    USERNAME_FIELD = 'phone'
    REQUIRED_FIELDS = []

    class Meta:
        verbose_name = "User"
        verbose_name_plural = "Users"

    def __str__(self):
        return f"{self.name} ({self.phone})" if self.name else self.phone

    def clean(self):
        super().clean()
        self.phone = normalize_phone(self.phone)


class Student(User):
    class Meta:
        proxy = True
        verbose_name = 'دانشجو'
        verbose_name_plural = 'دانشجویان'


class Category(models.Model):
    name = models.CharField(max_length=100)
    slug = models.SlugField(unique=True, blank=True)
    icon = models.CharField(max_length=50, default="bi-briefcase", help_text="Icon class name e.g. bi-graph-up-arrow")
    description = models.TextField(blank=True)

    class Meta:
        verbose_name = "Category"
        verbose_name_plural = "Categories"

    def __str__(self):
        return self.name


class Instructor(models.Model):
    name = models.CharField(max_length=100)
    title = models.CharField(max_length=200, help_text="e.g. Executive Business Coach & Forbes 30u30")
    bio = models.TextField()
    avatar_url = models.CharField(max_length=500, blank=True)
    rating = models.DecimalField(max_digits=3, decimal_places=1, default=4.9)
    students_count = models.IntegerField(default=12500)

    class Meta:
        verbose_name = "Instructor"
        verbose_name_plural = "Instructors"

    def __str__(self):
        return self.name


class Course(models.Model):
    LEVEL_CHOICES = [
        ('Executive', 'Executive Masterclass'),
        ('Mastery', 'Advanced Mastery'),
        ('Foundational', 'Foundational Leader'),
    ]

    name = models.CharField(max_length=150, verbose_name="Course Title")
    slug = models.SlugField(unique=True, blank=True)
    course_id = models.CharField(max_length=100, unique=True, verbose_name="کد یکتای دوره")
    category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, blank=True, related_name='courses')
    instructor = models.ForeignKey(Instructor, on_delete=models.SET_NULL, null=True, blank=True, related_name='courses')
    
    tagline = models.CharField(max_length=255, blank=True, help_text="Catchy 1-line benefit for executives")
    description = models.TextField(blank=True, verbose_name="Full Description")
    
    price = models.IntegerField(default=0, verbose_name="Price (USD/Toman)")
    discount_price = models.IntegerField(default=0, verbose_name="Discounted Price (0 if no discount)")
    is_free = models.BooleanField(default=False)
    is_featured = models.BooleanField(default=True)
    is_hidden = models.BooleanField(default=False)
    badge_text = models.CharField(max_length=50, blank=True, help_text="e.g. BESTSELLER, EXECUTIVE MASTERCLASS")

    cover_image = models.ImageField(upload_to='course_covers/', blank=True, null=True)
    cover_url = models.CharField(max_length=500, blank=True, help_text="External cover image link")
    demo_video_url = models.TextField(blank=True, null=True, help_text="Embed iframe or direct video URL")

    level = models.CharField(max_length=30, choices=LEVEL_CHOICES, default='Executive')
    duration = models.CharField(max_length=50, default="12.5 Hours", verbose_name="Total Video Duration")
    rating = models.DecimalField(max_digits=3, decimal_places=1, default=4.9)
    enrolled_count = models.IntegerField(default=3400, verbose_name="Enrolled Students")

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = "Course"
        verbose_name_plural = "Courses"
        constraints = [
            models.CheckConstraint(condition=models.Q(price__gte=0), name='course_price_non_negative'),
            models.CheckConstraint(condition=models.Q(discount_price__gte=0), name='course_discount_non_negative'),
        ]

    def __str__(self):
        return self.name

    def clean(self):
        super().clean()
        if self.discount_price and self.discount_price >= self.price:
            raise ValidationError({'discount_price': 'قیمت با تخفیف باید کمتر از قیمت اصلی دوره باشد.'})
        if self.is_free and (self.price or self.discount_price):
            raise ValidationError('برای دوره رایگان، قیمت اصلی و قیمت تخفیف باید صفر باشد.')

    @property
    def lesson_count(self):
        return self.videos.filter(is_active=True).count()

    @property
    def get_cover(self):
        if self.cover_image:
            return self.cover_image.url
        if self.cover_url:
            return self.cover_url
        return "https://images.unsplash.com/photo-1551836022-d5d88e9218df?auto=format&fit=crop&w=1200&q=80"

    @property
    def effective_price(self):
        if self.is_free:
            return 0
        if self.discount_price and self.discount_price < self.price:
            return self.discount_price
        return self.price

    @property
    def discount_percent(self):
        if self.price > 0 and self.discount_price > 0 and self.discount_price < self.price:
            return int(((self.price - self.discount_price) / self.price) * 100)
        return 0

    @property
    def discount_amount(self):
        return self.price - self.effective_price if self.discount_percent else 0


class Headline(models.Model):
    course = models.ForeignKey(Course, on_delete=models.CASCADE, related_name='headlines')
    title = models.CharField(max_length=150, verbose_name="Chapter Title")
    description = models.TextField(blank=True)
    order = models.IntegerField(default=0)

    class Meta:
        ordering = ['order']
        verbose_name = 'سرفصل'
        verbose_name_plural = 'سرفصل‌ها'

    def __str__(self):
        return f"{self.course.name} - {self.title}"


class Video(models.Model):
    course = models.ForeignKey(Course, on_delete=models.CASCADE, related_name='videos')
    headline = models.ForeignKey(Headline, on_delete=models.CASCADE, related_name='videos', verbose_name='سرفصل')
    title = models.CharField(max_length=150, verbose_name='نام ویدیو')
    duration = models.CharField(max_length=20, default="15 min")
    is_active = models.BooleanField(default=True)
    is_preview_free = models.BooleanField(default=False, verbose_name="Free Preview Lesson")
    player_url = models.URLField(max_length=1000, verbose_name='لینک ویدیو', help_text='لینک مستقیم یا Embed ویدیو را وارد کنید.')
    order = models.PositiveIntegerField(default=1, verbose_name='شماره ویدیو')

    class Meta:
        ordering = ['headline__order', 'order', 'id']
        verbose_name = 'ویدیو'
        verbose_name_plural = 'ویدیوها'
        constraints = [models.UniqueConstraint(fields=('headline', 'order'), name='unique_video_number_per_headline')]

    def clean(self):
        super().clean()
        if self.headline_id and self.course_id and self.headline.course_id != self.course_id:
            raise ValidationError({'headline': 'سرفصل انتخاب‌شده باید متعلق به همین دوره باشد.'})

    def __str__(self):
        return f"{self.course.name} | {self.title}"


class CourseFile(models.Model):
    course = models.ForeignKey(Course, on_delete=models.CASCADE, related_name='files')
    title = models.CharField(max_length=150, verbose_name="Attachment Name")
    file_url = models.CharField(max_length=500, blank=True, help_text="Direct download link")
    file = models.FileField(upload_to='course_files/', blank=True, null=True)
    file_size = models.CharField(max_length=50, default="2.4 MB")

    def __str__(self):
        return f"{self.course.name} - {self.title}"


class Order(models.Model):
    STATUS_CHOICES = [
        ('Completed', 'Completed'),
        ('Pending', 'Pending'),
        ('Failed', 'Failed'),
    ]
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='orders')
    course = models.ForeignKey(Course, on_delete=models.CASCADE, related_name='orders')
    amount = models.IntegerField(default=0)
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='Pending')
    transaction_id = models.CharField(max_length=100, unique=True, blank=True)
    gateway_authority = models.CharField(max_length=64, blank=True, db_index=True, verbose_name='شناسه درگاه')
    gateway_reference = models.CharField(max_length=64, blank=True, verbose_name='شماره پیگیری')
    payment_error = models.TextField(blank=True, verbose_name='خطا یا توضیحات پرداخت')
    gateway_response = models.JSONField(default=dict, blank=True, verbose_name='پاسخ درگاه')
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-created_at']
        verbose_name = 'سفارش'
        verbose_name_plural = 'سفارش‌ها'

    def __str__(self):
        return f"Order #{self.id} - {self.user.phone} - {self.course.name}"


class Enrollment(models.Model):
    SOURCE_CHOICES = [
        ('Payment', 'خرید'),
        ('Admin', 'فعال‌سازی مدیر'),
        ('Free', 'دوره رایگان'),
        ('Legacy', 'انتقال از سامانه قبلی'),
    ]
    course = models.ForeignKey(Course, on_delete=models.CASCADE, related_name='enrollments')
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='enrollments')
    source = models.CharField(max_length=20, choices=SOURCE_CHOICES, default='Admin')
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        verbose_name = 'ثبت‌نام دوره'
        verbose_name_plural = 'ثبت‌نام‌های دوره'
        constraints = [models.UniqueConstraint(fields=('course', 'user'), name='unique_course_enrollment_per_user')]

    def __str__(self):
        return f"{self.user.phone} - {self.course.name}"


# نگهداری صرفاً برای حفظ داده‌های قدیمی؛ اسپات‌پلیر در مسیر اجرایی سایت غیرفعال است.
class SpotplayerLicense(models.Model):
    course = models.ForeignKey(Course, on_delete=models.CASCADE, related_name='licenses')
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='licenses')
    license_key = models.TextField(verbose_name='کلید لایسنس اسپات‌پلیر', blank=True)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        verbose_name = "SpotPlayer License"
        verbose_name_plural = "SpotPlayer Licenses"
        constraints = [models.UniqueConstraint(fields=('course', 'user'), name='unique_course_license_per_user')]

    def __str__(self):
        return f"{self.user.phone} - {self.course.name}"

class Review(models.Model):
    course = models.ForeignKey(Course, on_delete=models.CASCADE, related_name='reviews')
    user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
    student_name = models.CharField(max_length=100)
    student_title = models.CharField(max_length=150, default="CEO & Founder")
    avatar_url = models.CharField(max_length=500, blank=True)
    rating = models.IntegerField(default=5)
    comment = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-created_at']

    def __str__(self):
        return f"Review by {self.student_name} on {self.course.name}"
