from django.db import models
from django.conf import settings


import uuid

class Conversation(models.Model):
    """
    Container for a chat between users.
    Supports both 1-on-1 conversations and group chats (up to 10 users).
    """
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

    participants = models.ManyToManyField(
        settings.AUTH_USER_MODEL,
        related_name='conversations'
    )
    initiator = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET_NULL,
        null=True,
        related_name='initiated_conversations'
    )
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    is_accepted = models.BooleanField(default=False)

    # Group chat fields
    is_group = models.BooleanField(default=False)
    name = models.CharField(max_length=255, blank=True)  # Auto-generated from usernames if empty
    image = models.ImageField(upload_to='group_images/', blank=True, null=True)
    admin = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='created_groups'
    )
    admins = models.ManyToManyField(
        settings.AUTH_USER_MODEL,
        related_name='admin_of_groups',
        blank=True
    )

    # Invite link fields
    invite_enabled = models.BooleanField(default=False)
    invite_require_approval = models.BooleanField(default=False)
    invite_token = models.CharField(max_length=100, unique=True, null=True, blank=True)
    invite_short_token = models.CharField(max_length=50, unique=True, null=True, blank=True)
    invite_expires_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        ordering = ['-updated_at']

    def __str__(self):
        if self.is_group:
            return f"Group: {self.name or 'Unnamed Group'}"
        participant_names = ', '.join([str(p) for p in self.participants.all()[:2]])
        return f"Conversation: {participant_names}"

    def get_display_name(self):
        """Get display name for the conversation."""
        if self.is_group:
            if self.name:
                return self.name
            # Auto-generate from participant usernames
            return ', '.join([p.username for p in self.participants.all()[:5]])
        return None

    def get_image_url(self):
        """Get image URL for the conversation."""
        if self.is_group:
            if self.image:
                return self.image.url
            return '/user_group.svg'  # Default group image
        return None


class Message(models.Model):
    """
    A single message within a conversation.
    """
    conversation = models.ForeignKey(
        Conversation,
        on_delete=models.CASCADE,
        related_name='messages'
    )
    sender = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='sent_messages'
    )
    sender_name_snapshot = models.CharField(max_length=255, blank=True, null=True)
    sender_avatar_snapshot = models.TextField(blank=True, null=True)

    MESSAGE_TYPES = [
        ('text', 'Text'),
        ('post', 'Shared Post'),
        ('call_started', 'Call Started'),
        ('call_ended', 'Call Ended'),
        ('call_missed', 'Call Missed'),
        ('video_call_started', 'Video Call Started'),
        ('video_call_ended', 'Video Call Ended'),
        ('video_call_missed', 'Video Call Missed'),
        ('group_call_started', 'Group Call Started'),
        ('group_call_joined', 'Group Call Joined'),
        ('group_call_ended', 'Group Call Ended'),
        ('member_added', 'Member Added'),
        ('member_left', 'Member Left'),
        ('member_kicked', 'Member Kicked'),
        ('request_accepted', 'Request Accepted'),
    ]
    MESSAGE_TYPES = [
        ('text', 'Text Message'),
        ('image', 'Image Message'),
        ('video', 'Video Message'),
        ('audio', 'Audio Message'),
        ('file', 'File Message'),
        ('post', 'Shared Post'),
        ('category', 'Shared Category'),
        ('profile', 'Shared Profile'),
        ('call_started', 'Call Started'),
        ('call_ended', 'Call Ended'),
        ('call_missed', 'Call Missed'),
        ('video_call_started', 'Video Call Started'),
        ('video_call_ended', 'Video Call Ended'),
        ('video_call_missed', 'Video Call Missed'),
        ('group_call_started', 'Group Call Started'),
        ('group_call_joined', 'Group Call Joined'),
        ('group_call_ended', 'Group Call Ended'),
        ('member_added', 'Member Added'),
        ('member_left', 'Member Left'),
        ('member_kicked', 'Member Kicked'),
        ('request_accepted', 'Request Accepted'),
    ]
    message_type = models.CharField(max_length=30, choices=MESSAGE_TYPES, default='text')

    content = models.TextField(blank=True)
    attachment = models.FileField(upload_to='chat_attachments/', blank=True, null=True)
    is_read = models.BooleanField(default=False)
    is_edited = models.BooleanField(default=False)
    is_deleted = models.BooleanField(default=False)  # Soft delete for everyone
    deleted_by_users = models.ManyToManyField(
        settings.AUTH_USER_MODEL,
        blank=True,
        related_name='hidden_messages'
    )  # Hidden only for specific users
    reply_to = models.ForeignKey(
        'self',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='replies'
    )
    shared_post = models.ForeignKey(
        'posts.Post',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='shared_in_messages'
    )
    shared_category = models.ForeignKey(
        'categories.Category',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='shared_in_messages'
    )
    shared_profile = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='shared_in_messages'
    )
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['created_at']

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

    @property
    def attachment_type(self):
        """Detect the type of attachment (image, video, or other)."""
        if not self.attachment:
            return None

        # Try to guess from mimetype first
        import mimetypes
        mime_type, _ = mimetypes.guess_type(self.attachment.name)
        if mime_type:
            if mime_type.startswith('image/'):
                return 'image'
            elif mime_type.startswith('video/'):
                return 'video'
            elif mime_type.startswith('audio/'):
                return 'audio'

        # Fallback to extension check if mimetype guessing fails
        ext = self.attachment.name.lower().split('.')[-1]
        if ext in ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg']:
            return 'image'
        elif ext in ['mp4', 'mov', 'avi', 'mkv']:
            return 'video'
        elif ext == 'webm':
            # webm can be audio or video. For our voice recordings, we use .webm
            # We'll check if the filename suggests it's a voice message
            if 'voice_message' in self.attachment.name.lower():
                return 'audio'
            return 'video'
        elif ext in ['mp3', 'wav', 'ogg', 'm4a', 'aac', 'weba']:
            return 'audio'

        return 'other'


class ConversationVisibility(models.Model):
    """
    Controls visibility of a conversation for each user.
    Allows 'delete from my side' functionality without affecting the other user.
    """
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='conversation_visibilities'
    )
    conversation = models.ForeignKey(
        Conversation,
        on_delete=models.CASCADE,
        related_name='visibilities'
    )
    is_visible = models.BooleanField(default=True)
    is_muted = models.BooleanField(default=False)
    hidden_until = models.DateTimeField(null=True, blank=True)

    class Meta:
        unique_together = ['user', 'conversation']
        verbose_name_plural = 'Conversation visibilities'

    def __str__(self):
        return f"{self.user} - {self.conversation} (visible: {self.is_visible})"


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

    class Meta:
        unique_together = ['message', 'user', 'emoji']

    def __str__(self):
        return f"{self.user} reacted {self.emoji} to {self.message}"


class ChatAppearance(models.Model):
    """
    Stores per-user, per-conversation appearance preferences.
    Each user can customize how they see each conversation.
    """
    BG_TYPE_CHOICES = [
        ('default', 'Default'),
        ('color', 'Solid Color'),
        ('gradient', 'Gradient'),
        ('image', 'Image'),
        ('template', 'Template'),
    ]

    DISPLAY_MODE_CHOICES = [
        ('comfortable', 'Comfortable'),
        ('compact', 'Compact'),
    ]

    conversation = models.OneToOneField(
        Conversation,
        on_delete=models.CASCADE,
        related_name='appearance'
    )

    # Background settings
    bg_type = models.CharField(max_length=10, choices=BG_TYPE_CHOICES, default='default')
    bg_color = models.CharField(max_length=7, null=True, blank=True)  # Hex color like #FFFFFF
    bg_gradient_start = models.CharField(max_length=7, null=True, blank=True)
    bg_gradient_end = models.CharField(max_length=7, null=True, blank=True)
    bg_template = models.CharField(max_length=100, null=True, blank=True)
    bg_image = models.ImageField(upload_to='chat_backgrounds/', null=True, blank=True)
    bg_image_position = models.JSONField(default=dict, blank=True)  # {x, y, scale, rotation}

    # Message bubble colors
    message_bg_sent = models.CharField(max_length=7, null=True, blank=True)  # User's sent messages
    message_bg_received = models.CharField(max_length=7, null=True, blank=True)  # Received messages
    message_text_sent = models.CharField(max_length=7, null=True, blank=True)
    message_text_received = models.CharField(max_length=7, null=True, blank=True)

    # Display preferences
    display_mode = models.CharField(max_length=12, choices=DISPLAY_MODE_CHOICES, default='comfortable')

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

    def __str__(self):
        return f"Appearance for {self.conversation}"


class ConversationMember(models.Model):
    """
    Tracks membership in group conversations.
    Stores per-user settings like mute and hide for groups.
    """
    conversation = models.ForeignKey(
        Conversation,
        on_delete=models.CASCADE,
        related_name='members'
    )
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='group_memberships'
    )
    is_muted = models.BooleanField(default=False)
    is_hidden = models.BooleanField(default=False)
    joined_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        unique_together = ('conversation', 'user')
        ordering = ['joined_at']

    def __str__(self):
        return f"{self.user.username} in {self.conversation}"


class GroupJoinRequest(models.Model):
    """
    Tracks requests to add users to a group.
    Regular users propose additions, admin approves/rejects.
    """
    STATUS_CHOICES = [
        ('pending', 'Pending'),
        ('accepted', 'Accepted'),
        ('rejected', 'Rejected'),
    ]

    conversation = models.ForeignKey(
        Conversation,
        on_delete=models.CASCADE,
        related_name='join_requests'
    )
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='group_join_requests'
    )
    requested_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='proposed_group_requests'
    )
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        unique_together = ('conversation', 'user')
        ordering = ['-created_at']

    def __str__(self):
        return f"Request for {self.user.username} to join {self.conversation} ({self.status})"


class MessageRead(models.Model):
    """
    Tracks which users have read each message.
    Used to display read receipt avatars under messages in groups.
    """
    message = models.ForeignKey(
        'Message',
        on_delete=models.CASCADE,
        related_name='read_by'
    )
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='read_messages'
    )
    read_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        unique_together = ('message', 'user')
        ordering = ['read_at']

    def __str__(self):
        return f"{self.user.username} read message {self.message_id}"
