"""
Traffic Tracking & Analytics System
Real-time visitor tracking, page views, traffic sources, device analytics
"""
from django.db import models
from django.contrib.auth import get_user_model
from django.utils import timezone
from datetime import timedelta
import json

User = get_user_model()


class PageView(models.Model):
    """
    Track every page view
    """
    # User Info
    user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
    session_id = models.CharField(max_length=100, db_index=True)
    
    # Page Info
    url = models.CharField(max_length=500, db_index=True)
    page_title = models.CharField(max_length=300, blank=True)
    referrer = models.CharField(max_length=500, blank=True)
    
    # Request Info
    ip_address = models.GenericIPAddressField()
    user_agent = models.TextField()
    
    # Device Info
    device_type = models.CharField(max_length=20, blank=True)  # mobile, tablet, desktop
    browser = models.CharField(max_length=50, blank=True)
    os = models.CharField(max_length=50, blank=True)
    
    # Location (from IP)
    country = models.CharField(max_length=100, blank=True)
    city = models.CharField(max_length=100, blank=True)
    
    # Timing
    time_on_page = models.IntegerField(default=0, help_text='Seconds spent on page')
    created_at = models.DateTimeField(auto_now_add=True, db_index=True)
    
    class Meta:
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['-created_at', 'url']),
            models.Index(fields=['session_id', '-created_at']),
        ]
    
    def __str__(self):
        return f"{self.url} - {self.created_at}"


class Visitor(models.Model):
    """
    Unique visitors (by IP + User Agent)
    """
    ip_address = models.GenericIPAddressField(db_index=True)
    user_agent = models.TextField()
    fingerprint = models.CharField(max_length=64, unique=True, db_index=True)
    
    # User association
    user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
    
    # Device & Browser
    device_type = models.CharField(max_length=20, blank=True)
    browser = models.CharField(max_length=50, blank=True)
    os = models.CharField(max_length=50, blank=True)
    
    # Location
    country = models.CharField(max_length=100, blank=True)
    city = models.CharField(max_length=100, blank=True)
    
    # Visit counts
    visit_count = models.IntegerField(default=1)
    page_views = models.IntegerField(default=0)
    
    # First & Last visit
    first_visit = models.DateTimeField(auto_now_add=True)
    last_visit = models.DateTimeField(auto_now=True)
    
    class Meta:
        ordering = ['-last_visit']
    
    def __str__(self):
        return f"Visitor from {self.country or 'Unknown'} - {self.visit_count} visits"


class TrafficSource(models.Model):
    """
    Track where traffic comes from
    """
    SOURCE_CHOICES = [
        ('direct', 'Direct'),
        ('search', 'Search Engine'),
        ('social', 'Social Media'),
        ('email', 'Email'),
        ('referral', 'Referral'),
        ('paid', 'Paid Ads'),
    ]
    
    source_type = models.CharField(max_length=20, choices=SOURCE_CHOICES, db_index=True)
    source_name = models.CharField(max_length=200, blank=True)  # e.g., "Google", "Facebook"
    referrer_url = models.CharField(max_length=500, blank=True)
    
    # Campaign tracking (UTM parameters)
    utm_source = models.CharField(max_length=200, blank=True)
    utm_medium = models.CharField(max_length=200, blank=True)
    utm_campaign = models.CharField(max_length=200, blank=True)
    utm_term = models.CharField(max_length=200, blank=True)
    utm_content = models.CharField(max_length=200, blank=True)
    
    # Stats
    visit_count = models.IntegerField(default=0)
    page_views = models.IntegerField(default=0)
    conversions = models.IntegerField(default=0)
    
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    
    class Meta:
        ordering = ['-visit_count']
    
    def __str__(self):
        return f"{self.get_source_type_display()} - {self.source_name}"


class DailyStats(models.Model):
    """
    Aggregated daily statistics
    """
    date = models.DateField(unique=True, db_index=True)
    
    # Traffic
    unique_visitors = models.IntegerField(default=0)
    total_page_views = models.IntegerField(default=0)
    new_visitors = models.IntegerField(default=0)
    returning_visitors = models.IntegerField(default=0)
    
    # Engagement
    avg_time_on_site = models.IntegerField(default=0, help_text='Average seconds')
    avg_pages_per_visit = models.DecimalField(max_digits=5, decimal_places=2, default=0)
    bounce_rate = models.DecimalField(max_digits=5, decimal_places=2, default=0)
    
    # Conversions
    new_users = models.IntegerField(default=0)
    orders = models.IntegerField(default=0)
    revenue = models.DecimalField(max_digits=12, decimal_places=2, default=0)
    
    # Devices
    mobile_visitors = models.IntegerField(default=0)
    tablet_visitors = models.IntegerField(default=0)
    desktop_visitors = models.IntegerField(default=0)
    
    created_at = models.DateTimeField(auto_now_add=True)
    
    class Meta:
        ordering = ['-date']
        verbose_name_plural = 'Daily Statistics'
    
    def __str__(self):
        return f"Stats for {self.date}"
    
    @classmethod
    def get_or_create_today(cls):
        """Get or create today's stats"""
        today = timezone.now().date()
        stats, created = cls.objects.get_or_create(date=today)
        return stats


class PopularPage(models.Model):
    """
    Track most popular pages
    """
    url = models.CharField(max_length=500, unique=True, db_index=True)
    page_title = models.CharField(max_length=300, blank=True)
    
    # Stats
    view_count_today = models.IntegerField(default=0)
    view_count_week = models.IntegerField(default=0)
    view_count_month = models.IntegerField(default=0)
    view_count_total = models.IntegerField(default=0)
    
    # Engagement
    avg_time_on_page = models.IntegerField(default=0)
    bounce_rate = models.DecimalField(max_digits=5, decimal_places=2, default=0)
    
    last_viewed = models.DateTimeField(auto_now=True)
    
    class Meta:
        ordering = ['-view_count_total']
    
    def __str__(self):
        return f"{self.url} - {self.view_count_total} views"


class RealTimeVisitor(models.Model):
    """
    Currently active visitors (last 5 minutes)
    """
    session_id = models.CharField(max_length=100, unique=True, db_index=True)
    user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
    
    current_page = models.CharField(max_length=500)
    ip_address = models.GenericIPAddressField()
    
    device_type = models.CharField(max_length=20, blank=True)
    browser = models.CharField(max_length=50, blank=True)
    country = models.CharField(max_length=100, blank=True)
    
    last_activity = models.DateTimeField(auto_now=True, db_index=True)
    
    class Meta:
        ordering = ['-last_activity']
    
    def __str__(self):
        return f"Active visitor on {self.current_page}"
    
    @classmethod
    def get_active_count(cls):
        """Get count of visitors in last 5 minutes"""
        cutoff = timezone.now() - timedelta(minutes=5)
        return cls.objects.filter(last_activity__gte=cutoff).count()
    
    @classmethod
    def cleanup_old(cls):
        """Remove visitors inactive for more than 10 minutes"""
        cutoff = timezone.now() - timedelta(minutes=10)
        cls.objects.filter(last_activity__lt=cutoff).delete()


class TrafficAlert(models.Model):
    """
    Alerts for unusual traffic patterns
    """
    ALERT_TYPE_CHOICES = [
        ('spike', 'Traffic Spike'),
        ('drop', 'Traffic Drop'),
        ('suspicious', 'Suspicious Activity'),
        ('milestone', 'Milestone Reached'),
    ]
    
    alert_type = models.CharField(max_length=20, choices=ALERT_TYPE_CHOICES)
    message = models.TextField()
    
    metric_name = models.CharField(max_length=100)
    metric_value = models.IntegerField()
    threshold = models.IntegerField()
    
    is_resolved = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)
    
    class Meta:
        ordering = ['-created_at']
    
    def __str__(self):
        return f"{self.get_alert_type_display()} - {self.message}"
