from django.db import models
from django.conf import settings
from django.utils import timezone
from payments.models import Payment


class PromotionSlot(models.Model):
    """Admin-defined promotion slots that vendors can purchase"""
    SLOT_TYPES = (
        ('trending', 'Trending'),
        ('flash_deal', 'Flash Deal'),
        ('featured', 'Featured'),
        ('homepage', 'Homepage Banner'),
    )

    slot_type = models.CharField(max_length=20, choices=SLOT_TYPES)
    name = models.CharField(max_length=100)
    description = models.TextField(blank=True, null=True)
    price = models.DecimalField(max_digits=10, decimal_places=2, help_text="Price vendor pays")
    duration_hours = models.IntegerField(help_text="Duration in hours")
    max_products = models.IntegerField(default=10, help_text="Max concurrent products in this slot")
    is_active = models.BooleanField(default=True)
    created_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET_NULL,
        null=True,
        related_name='created_promotion_slots'
    )
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        db_table = 'promotion_slots'
        ordering = ['slot_type', 'price']

    def __str__(self):
        return f"{self.name} ({self.get_slot_type_display()}) - KES {self.price}"

    @property
    def current_count(self):
        """Count of active promotions in this slot"""
        return self.product_promotions.filter(
            is_active=True,
            ends_at__gt=timezone.now()
        ).count()

    @property
    def is_available(self):
        """Check if slot has availability"""
        return self.current_count < self.max_products


class ProductPromotion(models.Model):
    """Vendor-purchased promotions for their products"""
    product = models.ForeignKey(
        'products.Product',
        on_delete=models.CASCADE,
        related_name='promotions'
    )
    slot = models.ForeignKey(
        PromotionSlot,
        on_delete=models.CASCADE,
        related_name='product_promotions'
    )
    vendor = models.ForeignKey(
        'accounts.VendorProfile',
        on_delete=models.CASCADE,
        related_name='promotions'
    )
    payment = models.ForeignKey(
        Payment,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='promotions'
    )
    starts_at = models.DateTimeField()
    ends_at = models.DateTimeField()
    is_active = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        db_table = 'product_promotions'
        ordering = ['-created_at']

    def __str__(self):
        return f"{self.product.name} - {self.slot.name}"

    @property
    def is_expired(self):
        return timezone.now() > self.ends_at

    @property
    def is_currently_active(self):
        now = timezone.now()
        return self.is_active and self.starts_at <= now <= self.ends_at

    def save(self, *args, **kwargs):
        # Auto-set starts_at if not set
        if not self.starts_at:
            self.starts_at = timezone.now()

        # Auto-set ends_at based on slot duration
        if not self.ends_at and self.slot:
            from datetime import timedelta
            self.ends_at = self.starts_at + timedelta(hours=self.slot.duration_hours)

        super().save(*args, **kwargs)


class SponsoredAd(models.Model):
    """Vendor-purchased sponsored ads that appear on public pages"""
    ITEM_TYPE_CHOICES = (
        ('product', 'Product'),
        ('service', 'Service'),
        ('event', 'Event'),
        ('menu', 'Menu'),
        ('video', 'Video'),
    )

    item_type = models.CharField(max_length=20, choices=ITEM_TYPE_CHOICES, default='product')
    product = models.ForeignKey(
        'products.Product',
        on_delete=models.CASCADE,
        related_name='sponsored_ads',
        null=True,
        blank=True,
    )
    service = models.ForeignKey(
        'services.Service',
        on_delete=models.CASCADE,
        related_name='sponsored_ads',
        null=True,
        blank=True,
    )
    event = models.ForeignKey(
        'events.Event',
        on_delete=models.CASCADE,
        related_name='sponsored_ads',
        null=True,
        blank=True,
    )
    menu = models.ForeignKey(
        'menus.Menu',
        on_delete=models.CASCADE,
        related_name='sponsored_ads',
        null=True,
        blank=True,
    )
    video = models.ForeignKey(
        'videos.VideoListing',
        on_delete=models.CASCADE,
        related_name='sponsored_ads',
        null=True,
        blank=True,
    )
    vendor = models.ForeignKey(
        'accounts.VendorProfile',
        on_delete=models.CASCADE,
        related_name='sponsored_ads'
    )
    payment = models.ForeignKey(
        Payment,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='sponsored_ads'
    )
    days = models.PositiveIntegerField()
    total_cost = models.DecimalField(max_digits=10, decimal_places=2)
    impressions = models.PositiveIntegerField(default=0)
    clicks = models.PositiveIntegerField(default=0)
    starts_at = models.DateTimeField()
    ends_at = models.DateTimeField()
    is_active = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        db_table = 'sponsored_ads'
        ordering = ['-created_at']

    def __str__(self):
        return f"Ad: {self.item_name} ({self.days} days)"

    @property
    def item(self):
        """Return the related item based on item_type"""
        if self.item_type == 'product':
            return self.product
        elif self.item_type == 'service':
            return self.service
        elif self.item_type == 'event':
            return self.event
        elif self.item_type == 'menu':
            return self.menu
        elif self.item_type == 'video':
            return self.video
        return None

    @property
    def item_name(self):
        """Return the name of the related item"""
        item = self.item
        if item is None:
            return 'Unknown'
        if self.item_type in ('event', 'video'):
            return item.title
        return item.name

    @property
    def is_currently_active(self):
        now = timezone.now()
        return self.is_active and self.starts_at <= now <= self.ends_at

    @property
    def is_expired(self):
        return timezone.now() > self.ends_at

    @property
    def ctr(self):
        if self.impressions == 0:
            return 0
        return round((self.clicks / self.impressions) * 100, 2)
