import uuid

from django.conf import settings
from django.db import models


class Conversation(models.Model):
    """A single chat session between a user and the AI assistant."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="conversations",
    )
    session_key = models.CharField(
        max_length=200,
        blank=True,
        default="",
        db_index=True,
        help_text="For anonymous users, ties conversation to browser session",
    )
    title = models.CharField(max_length=300, blank=True, default="")
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["-updated_at"]

    def __str__(self):
        label = self.title or str(self.id)[:8]
        return f"Conversation {label}"


class Message(models.Model):
    """A single message within a conversation."""

    ROLE_CHOICES = [
        ("user", "User"),
        ("assistant", "Assistant"),
        ("system", "System"),
    ]
    FEEDBACK_CHOICES = [
        ("up", "Thumbs Up"),
        ("down", "Thumbs Down"),
        ("", "No Feedback"),
    ]

    conversation = models.ForeignKey(
        Conversation, on_delete=models.CASCADE, related_name="messages"
    )
    role = models.CharField(max_length=10, choices=ROLE_CHOICES)
    content = models.TextField()
    product_data = models.JSONField(
        null=True,
        blank=True,
        help_text="Structured product results attached to this message",
    )
    metadata = models.JSONField(
        null=True,
        blank=True,
        help_text="Extracted slots, intent, or other engine metadata",
    )
    # ── Feedback fields ───────────────────────────────────────────
    feedback = models.CharField(
        max_length=10,
        choices=FEEDBACK_CHOICES,
        blank=True,
        default="",
        help_text="User thumbs up/down on this assistant response",
    )
    feedback_note = models.TextField(
        blank=True,
        default="",
        help_text="Optional text note attached to feedback",
    )
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ["created_at"]

    def __str__(self):
        preview = self.content[:60]
        return f"[{self.role}] {preview}"


class UserPreferenceProfile(models.Model):
    """
    Accumulated preference signals built over time from a user's conversations.
    One profile per authenticated user.
    """

    user = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="preference_profile",
    )
    preferred_brands = models.JSONField(default=list, blank=True)
    preferred_categories = models.JSONField(default=list, blank=True)
    preferred_stores = models.JSONField(default=list, blank=True)
    budget_min = models.DecimalField(
        max_digits=10, decimal_places=2, null=True, blank=True
    )
    budget_max = models.DecimalField(
        max_digits=10, decimal_places=2, null=True, blank=True
    )
    sizes = models.JSONField(
        default=dict,
        blank=True,
        help_text='e.g. {"shoes": "42", "shirt": "L"}',
    )
    gender = models.CharField(max_length=20, blank=True, default="")
    # Learned attribute weights from feedback (serialized dict)
    attribute_weights = models.JSONField(
        default=dict,
        blank=True,
        help_text='e.g. {"price": 0.8, "brand": 0.3, "color": 0.2}',
    )
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return f"Preferences for {self.user}"


class ProductInteraction(models.Model):
    """
    Tracks when a user clicks, dismisses, or engages with a product card.
    Used to improve future ranking, intent weighting, and personalization.
    """

    ACTION_CHOICES = [
        ("click", "Clicked / Viewed"),
        ("add_cart", "Added to Cart"),
        ("dismiss", "Dismissed / Not Interested"),
        ("purchase", "Purchased"),
        ("positive_feedback", "Associated with Positive Response Feedback"),
        ("negative_feedback", "Associated with Negative Response Feedback"),
    ]

    conversation = models.ForeignKey(
        Conversation,
        on_delete=models.CASCADE,
        related_name="product_interactions",
        null=True,
        blank=True,
    )
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="product_interactions",
    )
    session_key = models.CharField(
        max_length=200, blank=True, default="", db_index=True
    )

    # Product snapshot at time of interaction
    product_name = models.CharField(max_length=300)
    store_name = models.CharField(max_length=200, blank=True, default="")
    store_slug = models.CharField(max_length=200, blank=True, default="")
    category = models.CharField(max_length=100, blank=True, default="")
    brand = models.CharField(max_length=100, blank=True, default="")
    price = models.FloatField(null=True, blank=True)
    currency = models.CharField(max_length=10, blank=True, default="")

    # The query context that surfaced this product
    query_context = models.JSONField(
        null=True,
        blank=True,
        help_text="The query params that produced this product result",
    )

    action = models.CharField(
        max_length=30, choices=ACTION_CHOICES, default="click"
    )
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ["-created_at"]
        indexes = [
            models.Index(fields=["session_key", "-created_at"]),
            models.Index(fields=["user", "-created_at"]),
        ]

    def __str__(self):
        return f"{self.action} on {self.product_name}"