from django.db import models
from django.conf import settings
from django.core.exceptions import ValidationError
from django.utils import timezone

class Chat(models.Model):
    owner = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET_NULL,
        null=True,
        related_name='owned_chats'
    )
    
    members = models.ManyToManyField(
        settings.AUTH_USER_MODEL,
        related_name='chats',
        blank=True
    )

    moderators = models.ManyToManyField(
        settings.AUTH_USER_MODEL,
        related_name='moderated_chats',
        blank=True
    )

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

    def save(self, *args, **kwargs):
        is_new = self._state.adding
        super().save(*args, **kwargs)
        
        # LOGIC: Ensure owner is always a member and moderator
        if is_new and self.owner:
            self.members.add(self.owner)
            self.moderators.add(self.owner)

    def __str__(self):
        return f"Chat {self.id}"


class Message(models.Model):
    chat = models.ForeignKey(Chat, related_name='messages', on_delete=models.CASCADE)
    
    sender = models.ForeignKey(
        settings.AUTH_USER_MODEL, 
        on_delete=models.CASCADE,
        related_name='sent_messages'
    )

    #odpověď na jinou zprávu
    reply_to = models.ForeignKey(
        'self',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='replies'
    )
    
    content = models.TextField(blank=True) 

    # --- TRACKING EDIT STATUS ---
    # We add these so the frontend doesn't need to check MessageHistory table
    is_edited = models.BooleanField(default=False)
    edited_at = models.DateTimeField(null=True, blank=True)

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

    def clean(self):
        # VALIDATION: Ensure sender is actually in the chat
        # Note: We check self.id to avoid running this on creation if logic depends on M2M
        # But generally, a sender must be a member.
        if self.chat and self.sender:
            if not self.chat.members.filter(id=self.sender.id).exists():
                raise ValidationError("Sender is not a member of this chat.")

    def save(self, *args, **kwargs):
        # Optional: Run validation before saving
        # self.full_clean() 
        super().save(*args, **kwargs)

    # --- HELPER METHODS FOR WEBSOCKETS / VIEWS ---

    def edit_content(self, new_text):
        """
        Handles the complex logic of editing:
        1. Checks if text actually changed.
        2. Saves old text to History.
        3. Updates current text and timestamps.
        """
        if self.content == new_text:
            return False  # No change happened

        # 1. Save History
        MessageHistory.objects.create(
            message=self,
            old_content=self.content
        )

        # 2. Update Self
        self.content = new_text
        self.is_edited = True
        self.edited_at = timezone.now()
        self.save()
        return True

    def toggle_reaction(self, user, emoji):
        """
        Handles Add/Remove/Switch logic.
        Returns a tuple: (action, reaction_object)
        action can be: 'added', 'removed', 'switched'
        """
        try:
            reaction = MessageReaction.objects.get(message=self, user=user)
            
            if reaction.emoji == emoji:
                # Same emoji -> Remove it (Toggle)
                reaction.delete()
                return 'removed', None
            else:
                # Different emoji -> Switch it
                reaction.emoji = emoji
                reaction.save()
                return 'switched', reaction
                
        except MessageReaction.DoesNotExist:
            # New reaction -> Create it
            reaction = MessageReaction.objects.create(
                message=self,
                user=user,
                emoji=emoji
            )
            return 'added', reaction

    def __str__(self):
        return f"Message {self.id} from {self.sender}"


class MessageHistory(models.Model):
    message = models.ForeignKey(
        Message, 
        on_delete=models.CASCADE, 
        related_name='edit_history'
    )
    old_content = models.TextField()
    archived_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-archived_at']


class MessageReaction(models.Model):
    message = models.ForeignKey(
        Message, 
        on_delete=models.CASCADE, 
        related_name='reactions'
    )
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    emoji = models.CharField(max_length=10) 
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        unique_together = ('message', 'user')
    
    def __str__(self):
        return f"{self.user} reacted {self.emoji}"


class MessageFile(models.Model):
    message = models.ForeignKey(
        Message, 
        on_delete=models.CASCADE, 
        related_name='media_files' 
    )
    file = models.FileField(upload_to='chat_uploads/%Y/%m/%d/')

    media_type = models.CharField(max_length=20, choices=[
        ('IMAGE', 'Image'), 
        ('VIDEO', 'Video'), 
        ('FILE', 'File')
    ], default='FILE')

    uploaded_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f"Media {self.id} for Message {self.message.id}"