<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WhatsApp-style Chat</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <!-- Google Maps API -->
    <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB3DuJbc-sguk2Ry47XkKqkhIJHDJJNES4&callback=initMap" async defer></script>
    <style>
        .messages-container::-webkit-scrollbar {
            width: 6px;
        }
        .messages-container::-webkit-scrollbar-thumb {
            background-color: rgba(0, 0, 0, 0.2);
        }
    </style>
</head>
<body class="bg-gray-100 h-screen flex items-center justify-center">
    <div class="w-full max-w-3xl h-[700px] bg-white shadow-lg rounded-lg flex flex-col">

        <!-- Top Bar with User Information -->
        <div class="bg-[#075E54] text-white p-4 rounded-t-lg flex justify-between items-center">
            <div class="flex items-center space-x-3">
                <img src="{{ user.profile_picture_url }}" alt="Profile Picture" class="h-10 w-10 rounded-full">
                <h1 class="text-lg font-semibold">{{ conversation.user.username }}</h1>
            </div>
        </div>

        <!-- Chat Messages Container -->
        <div id="chatMessages" class="flex-1 overflow-y-auto p-4 space-y-4 messages-container">
            <!-- Messages will be inserted dynamically here -->
        </div>

        <!-- Bottom Bar with Input, Attach, Record, and Send -->
        <div class="bg-[#F0F0F0] p-4 rounded-b-lg relative">
            <div class="flex items-center space-x-2">

                <!-- Attach Button -->
                <button id="attachBtn" class="text-[#128C7E] hover:text-[#075E54] relative">
                    <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.172 7l-6.586 6.586a2 2 0 102.828 2.828l6.414-6.586a4 4 0 00-5.656-5.656l-6.415 6.585a6 6 0 108.486 8.486L20.5 13" />
                    </svg>
                </button>

                <!-- Emoji Picker Button -->
                <button id="emojiBtn" class="text-[#128C7E] hover:text-[#075E54]">
                    <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14.828 14.828a4 4 0 01-5.656 0M10 8h.01M14 8h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
                    </svg>
                </button>

                <!-- Input Box -->
                <input type="text" id="messageInput" class="flex-1 rounded-full py-2 px-4 focus:outline-none focus:ring-2 focus:ring-[#25D366]" placeholder="Type a message">

                <!-- Record Voice Button -->
                <button id="recordVoiceBtn" class="bg-[#25D366] text-white rounded-full p-2 hover:bg-[#128C7E]">
                    <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 14a4 4 0 004-4V5a4 4 0 00-8 0v5a4 4 0 004 4z" />
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 10v2a7 7 0 11-14 0v-2M12 19v3m-4 0h8" />
                    </svg>
                </button>

                <!-- Send Button -->
                <button id="sendBtn" class="bg-[#25D366] text-white rounded-full p-2 hover:bg-[#128C7E] focus:outline-none focus:ring-2 focus:ring-[#25D366]">
                    <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10l9 9m0 0l9-9m-9 9V3" />
                    </svg>
                </button>
            </div>

            <!-- Attach Options Popup -->
            <div id="attachOptions" class="absolute bottom-16 right-4 bg-white shadow-md rounded-lg p-2 hidden">
                <button id="sendFileBtn" class="flex items-center space-x-2 p-2 hover:bg-gray-100 w-full text-left">
                    <!-- Icon for Send File -->
                    <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-[#128C7E]" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16V8a2 2 0 012-2h6l2 2h6a2 2 0 012 2v8a2 2 0 01-2 2H6a2 2 0 01-2-2z" />
                    </svg>
                    <span class="text-gray-700">Send File</span>
                </button>
                <button id="shareLocationBtn" class="flex items-center space-x-2 p-2 hover:bg-gray-100 w-full text-left">
                    <!-- Icon for Share Location -->
                    <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-[#128C7E]" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 11c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM12 12c-2.761 0-5 2.239-5 5 0 .735.195 1.427.528 2.034a8.004 8.004 0 009.944 0A4.978 4.978 0 0017 17c0-2.761-2.239-5-5-5z" />
                    </svg>
                    <span class="text-gray-700">Share Location</span>
                </button>
            </div>
        </div>
    </div>

    <!-- Hidden file input -->
    <input type="file" id="fileInput" class="absolute opacity-0 w-0 h-0" accept="image/*,video/*,audio/*">

    <!-- Location Modal -->
    <div id="locationModal" class="fixed z-10 inset-0 overflow-y-auto hidden" aria-labelledby="modal-title" role="dialog" aria-modal="true">
        <div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
            <div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" aria-hidden="true"></div>
            <span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>
            <div class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full">
                <div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
                    <div id="map" style="height: 300px;"></div>
                </div>
                <div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
                    <button type="button" id="sendLocationBtn" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-[#25D366] text-base font-medium text-white hover:bg-[#128C7E] focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-[#25D366] sm:ml-3 sm:w-auto sm:text-sm">
                        Send Location
                    </button>
                    <button type="button" id="closeLocationBtn" class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-[#128C7E] sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">
                        Cancel
                    </button>
                </div>
            </div>
        </div>
    </div>
</body>
<script>
(function() {
    const conversationId = '{{ conversation.id }}';
    const currentUser = '{{ request.user.username }}';
    const wsScheme = window.location.protocol === "https:" ? "wss" : "ws";
    const chatSocket = new WebSocket(`${wsScheme}://${window.location.host}/ws/chat/${conversationId}/`);

    const closeLocationBtn = document.getElementById('closeLocationBtn');
    const attachOptions = document.getElementById('attachOptions');
    const sendFileBtn = document.getElementById('sendFileBtn');
    const shareLocationBtn = document.getElementById('shareLocationBtn');
    const messageInput = document.getElementById('messageInput');
    const chatMessages = document.getElementById('chatMessages');
    const sendBtn = document.getElementById('sendBtn');
    const attachBtn = document.getElementById('attachBtn');
    const fileInput = document.getElementById('fileInput');
    const locationModal = document.getElementById('locationModal');
    const sendLocationBtn = document.getElementById('sendLocationBtn');
    const emojiBtn = document.getElementById('emojiBtn');
    const recordVoiceBtn = document.getElementById('recordVoiceBtn');

    let recorder, voiceBlob, mediaRecorder;
    let map, marker;

    // Emoji Picker
    emojiBtn.addEventListener('click', () => {
        const picker = new EmojiButton();
        picker.pickerVisible ? picker.hidePicker() : picker.showPicker(messageInput);
        picker.on('emoji', emoji => {
            messageInput.value += emoji;
        });
    });

    // Voice Recording
    recordVoiceBtn.addEventListener('mousedown', async () => {
        recorder = await navigator.mediaDevices.getUserMedia({ audio: true });
        mediaRecorder = new MediaRecorder(recorder);
        mediaRecorder.start();
    });

    recordVoiceBtn.addEventListener('mouseup', () => {
        if (mediaRecorder && mediaRecorder.state !== 'inactive') {
            mediaRecorder.stop();
            mediaRecorder.ondataavailable = function(e) {
                voiceBlob = e.data;
                const formData = new FormData();
                formData.append('file', voiceBlob, 'voiceMessage.webm');
                sendVoice(formData);
            };
        }
    });

    function sendVoice(formData) {
        fetch('/upload/', {
            method: 'POST',
            body: formData,
            headers: {
                'X-CSRFToken': getCookie('csrftoken'),
            },
        })
        .then(response => response.json())
        .then(data => {
            if (data.status === 'success') {
                appendMessage({
                    sender: currentUser,
                    content: '',
                    fileUrl: data.file_url,
                    isFile: true,
                    fileType: 'audio/webm',
                });
            }
        });
    }

    // Append message to chat
    function appendMessage({ sender, content, fileUrl = null, isFile = false, fileType = '', timestamp = '' }) {
        const messageElement = document.createElement('div');
        messageElement.className = `message ${sender === currentUser ? 'sent' : 'received'}`;

        const messageBody = document.createElement('div');
        messageBody.className = `p-2 max-w-md rounded-lg ${sender === currentUser ? 'bg-[#DCF8C6]' : 'bg-[#E4E6EB]'}`;

        if (isFile && fileUrl) {
            if (fileType.startsWith('image/')) {
                messageBody.innerHTML = `<img src="${fileUrl}" alt="Image" class="rounded max-w-full">`;
            } else if (fileType.startsWith('audio/')) {
                messageBody.innerHTML = `<audio controls class="w-full"><source src="${fileUrl}" type="${fileType}"></audio>`;
            } else if (fileType.startsWith('video/')) {
                messageBody.innerHTML = `<video controls class="w-full"><source src="${fileUrl}" type="${fileType}"></video>`;
            } else {
                messageBody.innerHTML = `<a href="${fileUrl}" target="_blank" class="text-blue-500 hover:underline">Download File</a>`;
            }
        } else {
            messageBody.textContent = content;
        }

        const timeStampDiv = document.createElement('div');
        timeStampDiv.className = 'text-xs text-gray-500 mt-1';
        timeStampDiv.textContent = timestamp ? new Date(timestamp).toLocaleTimeString() : '';

        messageElement.appendChild(messageBody);
        messageElement.appendChild(timeStampDiv);
        chatMessages.appendChild(messageElement);
        chatMessages.scrollTop = chatMessages.scrollHeight;
    }

    // Load previous messages on page load
    {% for message in messages %}
        appendMessage({
            sender: '{{ message.sender.username }}',
            content: '{{ message.content|escapejs }}',
            fileUrl: '{{ message.file_url|default:"" }}',
            isFile: {{ message.is_file|yesno:"true,false" }},
            fileType: '{{ message.file_type|default:"" }}',
            timestamp: '{{ message.timestamp|date:"c" }}'
        });
    {% endfor %}

    // Send message to the server
    function sendMessage(content, messageType = 'text', isFile = false, fileUrl = '', fileType = '') {
        const data = {
            'action': 'message',
            'message': isFile ? fileUrl : content,
            'message_type': messageType,
            'is_file': isFile,
            'file_url': fileUrl,
            'file_type': fileType
        };
        chatSocket.send(JSON.stringify(data));
    }

    // Send message on button click or Enter key
    sendBtn.addEventListener('click', () => {
        const messageText = messageInput.value.trim();
        if (messageText) {
            sendMessage(messageText);
            messageInput.value = '';
        }
    });

    messageInput.addEventListener('keypress', (e) => {
        if (e.key === 'Enter' && !e.shiftKey) {
            const messageText = messageInput.value.trim();
            if (messageText) {
                sendMessage(messageText);
                messageInput.value = '';
                e.preventDefault();
            }
        }
    });

    // Attach file functionality
    attachBtn.addEventListener('click', () => attachOptions.classList.toggle('hidden'));

    document.addEventListener('click', (event) => {
        if (!attachBtn.contains(event.target) && !attachOptions.contains(event.target)) {
            attachOptions.classList.add('hidden');
        }
    });

    sendFileBtn.addEventListener('click', () => {
        attachOptions.classList.add('hidden');
        fileInput.click();
    });

    fileInput.addEventListener('change', function() {
        const file = this.files[0];
        if (file) {
            const formData = new FormData();
            formData.append('file', file);
            fetch('/upload/', {
                method: 'POST',
                body: formData,
                headers: {
                    'X-CSRFToken': getCookie('csrftoken'),
                },
            })
            .then(response => response.json())
            .then(data => {
                if (data.status === 'success') {
                    appendMessage({
                        sender: currentUser,
                        content: 'File',
                        fileUrl: data.file_url,
                        isFile: true,
                        fileType: file.type
                    });
                }
            });
        }
    });

    // Share location functionality
    shareLocationBtn.addEventListener('click', () => {
        attachOptions.classList.add('hidden');
        locationModal.classList.remove('hidden');
        initMap();
    });

    function initMap() {
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition((position) => {
                const pos = { lat: position.coords.latitude, lng: position.coords.longitude };

                map = new google.maps.Map(document.getElementById('map'), {
                    center: pos,
                    zoom: 15,
                });

                marker = new google.maps.Marker({
                    position: pos,
                    map: map,
                    draggable: true,
                });
            }, () => handleLocationError(true));
        } else {
            handleLocationError(false);
        }
    }

    function handleLocationError(hasGeolocation) {
        const defaultLocation = { lat: -34.397, lng: 150.644 };
        map = new google.maps.Map(document.getElementById('map'), {
            center: defaultLocation,
            zoom: 8,
        });
        marker = new google.maps.Marker({
            position: defaultLocation,
            map: map,
            draggable: true,
        });
    }

    sendLocationBtn.addEventListener('click', () => {
        if (marker) {
            const position = marker.getPosition();
            const messageText = `Shared a location: https://www.google.com/maps/search/?api=1&query=${position.lat()},${position.lng()}`;
            sendMessage(messageText, 'location');
            locationModal.classList.add('hidden');
        } else {
            alert('Please select a location on the map.');
        }
    });

    closeLocationBtn.addEventListener('click', () => locationModal.classList.add('hidden'));

    // WebSocket event listeners
    chatSocket.onopen = () => console.log('WebSocket connection established.');

    chatSocket.onmessage = (e) => {
        const data = JSON.parse(e.data);
        appendMessage({
            sender: data.sender,
            content: data.message,
            isFile: data.is_file,
            fileUrl: data.file_url,
            fileType: data.file_type,
            timestamp: data.timestamp
        });
    };

    chatSocket.onerror = (e) => console.error('WebSocket error:', e);

    chatSocket.onclose = () => console.warn('WebSocket connection closed.');

    // Utility function to get CSRF token
    function getCookie(name) {
        const cookies = document.cookie.split(';').reduce((acc, cookie) => {
            const [key, value] = cookie.split('=').map(c => c.trim());
            acc[key] = value;
            return acc;
        }, {});
        return cookies[name];
    }

})();
</script>
</html>

this code dosn't works okey
only send message works fine

my messages should be right side and green color bobble 
and other side recived messages with blue bobble
for start record and play sound i need sometime with this ui(voice size is not important)

send image only show half of url
location show link of location😐
i can't cancell record voice or ...

all of this are my problem

give me answer in two message
next message for html with full structure and attentaion
after that i will give js 

now write show your best in html 
don't explaine it
only work on code quality