from django.db import models

from apps.core.models import TimeStampedModel


class UserEvent(TimeStampedModel):
    """Tracks every single user action/behavior in the app.

    The mobile app sends events here for full behavioral analytics.
    """

    # Event types covering all user interactions
    EVENT_TYPES = [
        # Navigation
        ("screen_view", "Screen View"),
        ("screen_exit", "Screen Exit"),
        # Engagement
        ("tap", "Tap / Click"),
        ("scroll", "Scroll"),
        ("swipe", "Swipe"),
        ("long_press", "Long Press"),
        ("pull_to_refresh", "Pull to Refresh"),
        # Search
        ("search", "Search"),
        ("search_result_click", "Search Result Click"),
        # Content
        ("store_view", "Store View"),
        ("product_view", "Product View"),
        ("event_view", "Event View"),
        ("banner_click", "Banner Click"),
        ("category_click", "Category Click"),
        # Actions
        ("favorite_add", "Add to Favorites"),
        ("favorite_remove", "Remove from Favorites"),
        ("share", "Share"),
        ("call", "Phone Call"),
        ("whatsapp_click", "WhatsApp Click"),
        ("instagram_click", "Instagram Click"),
        ("website_click", "Website Click"),
        ("coupon_claim", "Coupon Claim"),
        ("review_submit", "Review Submit"),
        # Cart / Purchase intent
        ("add_to_cart", "Add to Cart"),
        ("remove_from_cart", "Remove from Cart"),
        ("checkout_start", "Checkout Start"),
        ("purchase_complete", "Purchase Complete"),
        # Session
        ("app_open", "App Open"),
        ("app_close", "App Close"),
        ("app_background", "App Backgrounded"),
        ("app_foreground", "App Foregrounded"),
        # Auth
        ("login", "Login"),
        ("logout", "Logout"),
        ("signup", "Signup"),
        # Notifications
        ("notification_received", "Notification Received"),
        ("notification_opened", "Notification Opened"),
        ("notification_dismissed", "Notification Dismissed"),
        # Errors
        ("error", "Error"),
        ("crash", "Crash"),
        # Custom
        ("custom", "Custom Event"),
    ]

    user = models.ForeignKey(
        "users.User",
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="analytics_events",
    )
    # Anonymous device tracking for guest users
    device_id = models.CharField(max_length=255, blank=True, db_index=True)

    event_type = models.CharField(max_length=50, choices=EVENT_TYPES, db_index=True)
    event_name = models.CharField(
        max_length=100, blank=True,
        help_text="Custom event name for more granular tracking (e.g. 'home_banner_1_click')",
    )

    # Context — what was the user interacting with?
    screen_name = models.CharField(max_length=100, blank=True, db_index=True)
    target_type = models.CharField(
        max_length=50, blank=True,
        help_text="Type of object interacted with: store, product, event, banner, category, etc.",
    )
    target_id = models.CharField(
        max_length=50, blank=True,
        help_text="ID of the object interacted with.",
    )
    target_name = models.CharField(max_length=255, blank=True)

    # Extra data (flexible JSON for any additional context)
    metadata = models.JSONField(
        default=dict, blank=True,
        help_text="Any extra context: search query, scroll depth, duration, etc.",
    )

    # Session tracking
    session_id = models.CharField(max_length=100, blank=True, db_index=True)
    session_duration = models.PositiveIntegerField(
        null=True, blank=True,
        help_text="Duration in seconds (for session/screen events).",
    )

    # Device info
    platform = models.CharField(max_length=20, blank=True)  # ios, android
    app_version = models.CharField(max_length=20, blank=True)
    os_version = models.CharField(max_length=30, blank=True)
    device_model = models.CharField(max_length=100, blank=True)
    screen_resolution = models.CharField(max_length=20, blank=True)

    # Location (optional)
    latitude = models.DecimalField(max_digits=10, decimal_places=7, null=True, blank=True)
    longitude = models.DecimalField(max_digits=10, decimal_places=7, null=True, blank=True)
    city = models.CharField(max_length=100, blank=True)
    country = models.CharField(max_length=50, blank=True)

    # Network
    connection_type = models.CharField(max_length=20, blank=True)  # wifi, 4g, 5g
    ip_address = models.GenericIPAddressField(null=True, blank=True)

    # Timestamp from client (may differ from server created_at)
    client_timestamp = models.DateTimeField(null=True, blank=True)

    class Meta:
        db_table = "analytics_events"
        ordering = ["-created_at"]
        indexes = [
            models.Index(fields=["user", "event_type", "-created_at"]),
            models.Index(fields=["event_type", "-created_at"]),
            models.Index(fields=["device_id", "-created_at"]),
            models.Index(fields=["session_id", "-created_at"]),
            models.Index(fields=["screen_name", "-created_at"]),
            models.Index(fields=["target_type", "target_id"]),
        ]

    def __str__(self):
        user_str = self.user or self.device_id or "anonymous"
        return f"{user_str} | {self.event_type} | {self.screen_name}"


class UserSession(TimeStampedModel):
    """Tracks user sessions for engagement metrics."""

    user = models.ForeignKey(
        "users.User",
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="sessions",
    )
    device_id = models.CharField(max_length=255, blank=True, db_index=True)
    session_id = models.CharField(max_length=100, unique=True)

    started_at = models.DateTimeField()
    ended_at = models.DateTimeField(null=True, blank=True)
    duration_seconds = models.PositiveIntegerField(null=True, blank=True)

    # Device info snapshot
    platform = models.CharField(max_length=20, blank=True)
    app_version = models.CharField(max_length=20, blank=True)
    device_model = models.CharField(max_length=100, blank=True)

    # Session stats
    screens_viewed = models.PositiveIntegerField(default=0)
    events_count = models.PositiveIntegerField(default=0)

    class Meta:
        db_table = "analytics_sessions"
        ordering = ["-started_at"]

    def __str__(self):
        user_str = self.user or self.device_id or "anonymous"
        return f"{user_str} | {self.session_id}"
