from uuid import uuid4
from django.contrib.auth import get_user_model
from django.db import models


User = get_user_model()


class Conversation(models.Model):
    user = models.ForeignKey(User, related_name="chats", on_delete=models.CASCADE)
    operator = models.ForeignKey(User, related_name="assigned_chats", on_delete=models.CASCADE, null=True, blank=True)
    is_active = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)
    last_touch = models.DateTimeField(auto_now=True)
    key = models.UUIDField(default=uuid4, unique=True)
    unread_count = models.IntegerField(default=0)

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


class Message(models.Model):
    TEXT = 'text'
    IMAGE = 'image'
    VIDEO = 'video'
    VOICE = 'voice'
    LOCATION = 'location'
    FILE = 'file'

    MESSAGE_TYPES = [
        (TEXT, 'Text'),
        (IMAGE, 'Image'),
        (VIDEO, 'Video'),
        (VOICE, 'Voice'),
        (LOCATION, 'Location'),
        (FILE, 'File')
    ]
    conversation = models.ForeignKey(Conversation, related_name='messages', on_delete=models.CASCADE)
    sender = models.ForeignKey(User, on_delete=models.CASCADE)
    content = models.TextField(blank=True, null=True)
    reply_to = models.ForeignKey('self', null=True, blank=True, on_delete=models.SET_NULL)
    timestamp = models.DateTimeField(auto_now_add=True)
    edited = models.BooleanField(default=False)
    message_type = models.CharField(max_length=10, choices=MESSAGE_TYPES, default=TEXT)
    is_read = models.BooleanField(default=False)

    def __str__(self):
        return f"Message {self.id} in Conversation {self.conversation.id}"


class Attachment(models.Model):
    file = models.FileField(upload_to='attachments/')
    created_at = models.DateTimeField(auto_now_add=True)

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


this is my model

from channels.generic.websocket import AsyncWebsocketConsumer
from channels.db import database_sync_to_async
import json
from .models import Conversation, Message

class ChatConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.user = self.scope['user']
        self.conversation_id = self.scope['url_route']['kwargs']['conversation_id']
        self.conversation_group_name = f'chat_{self.conversation_id}'

        # Join the conversation group
        await self.channel_layer.group_add(self.conversation_group_name, self.channel_name)
        await self.accept()

        # Send the initial chat state with the last 15 messages
        await self.send_initial_chat_state()

    async def disconnect(self, close_code):
        await self.channel_layer.group_discard(self.conversation_group_name, self.channel_name)

    async def receive(self, text_data):
        data = json.loads(text_data)
        action = data.get('action')

        if action == 'send_message':
            await self.handle_send_message(data)
        elif action == 'load_more_messages':
            await self.load_more_messages(data)
        elif action == 'switch_conversation':
            await self.switch_conversation(data)

    async def send_initial_chat_state(self):
        messages = await self.get_last_messages(self.conversation_id, limit=15)

        await self.send(text_data=json.dumps({
            'action': 'initial_state',
            'messages': [self.format_message(message) for message in messages],
        }))

    async def load_more_messages(self, data):
        offset = data.get('offset', 0)
        messages = await self.get_messages(self.conversation_id, offset)

        await self.send(text_data=json.dumps({
            'action': 'load_more_messages',
            'messages': [self.format_message(message) for message in messages],
        }))

    async def switch_conversation(self, data):
        new_conversation_id = data.get('conversation_id')

        # Leave the current conversation group
        await self.channel_layer.group_discard(self.conversation_group_name, self.channel_name)

        # Update the conversation ID
        self.conversation_id = new_conversation_id
        self.conversation_group_name = f'chat_{self.conversation_id}'

        # Join the new conversation group
        await self.channel_layer.group_add(self.conversation_group_name, self.channel_name)

        # Send the initial state for the new conversation
        await self.send_initial_chat_state()

    async def handle_send_message(self, data):
        message_text = data.get('message')
        message_type = data.get('message_type', 'text')

        message = await self.create_message(self.user, message_text, message_type)

        await self.channel_layer.group_send(self.conversation_group_name, {
            'type': 'chat_message',
            'message': self.format_message(message)
        })

    @database_sync_to_async
    def get_last_messages(self, conversation_id, limit=15):
        return Message.objects.filter(conversation_id=conversation_id).order_by('-timestamp')[:limit]

    @database_sync_to_async
    def get_messages(self, conversation_id, offset):
        return Message.objects.filter(conversation_id=conversation_id).order_by('-timestamp')[offset:offset + 15]

    @database_sync_to_async
    def create_message(self, sender, content, message_type='text'):
        return Message.objects.create(
            conversation=self.conversation,
            sender=sender,
            content=content,
            message_type=message_type
        )

    def format_message(self, message):
        return {
            'id': message.id,
            'sender': message.sender.username,
            'content': message.content,
            'timestamp': message.timestamp.strftime('%Y-%m-%d %H:%M:%S'),
            'message_type': message.message_type,
        }

    async def chat_message(self, event):
        await self.send(text_data=json.dumps(event))


give me new version of consumer
manage multi conversation with one connection
pick and end a conversation
notification for new message in a conversation
also at start show count of unread messages for each conversation

i have to see them and after that have ability to ask from socket to pick that conversation and after that i'll send message or terminate that conversation

in initial, you have to send operator conversations and unpicked conversations (without operator)
before pick and end conversation, you should validate owner for end and is it unpicked
you have to broadcast a conversation is picked by some one and others can't pick it 
in this socket we can't create new conversation

in receive we user will send 
TEXT = 'text'
IMAGE = 'image'
VIDEO = 'video'
VOICE = 'voice'
LOCATION = 'location'
FILE = 'file'
for each message and only text is text
in other cases, user send type of message + URL

give me a small consumer
don't write to much and extra code
don't explaine it
only give me consumer code