const API_BASE_URL = '/api'; // Sử dụng đường dẫn tương đối để tránh lỗi CORS/Hostname

let map;
let tempMarker = null;
let markerClusterGroup;
let currentSceneId = null;
let previousSceneId = null;
let miniMap = null;
let miniMapMarker = null;

// Initialize when DOM is ready
document.addEventListener('DOMContentLoaded', () => {
    try {
        console.log("--- Bắt đầu khởi tạo Frontend ---");
        if (document.getElementById('map')) {
            console.log("1. Đang khởi tạo bản đồ Leaflet...");
            initMap();
        }
        
        // Chạy tuần tự để tránh xung đột luồng xử lý
        checkAuthStatus(); // 2. Kiểm tra đăng nhập
        
        // Đảm bảo map đã sẵn sàng trước khi nạp data
        if (map) {
            loadScenes().then(() => {
                console.log("4. Đang chuẩn bị khôi phục Scene cũ (nếu có)...");
                // Chỉ khôi phục khi bản đồ đã nạp xong các marker
                setTimeout(restoreActiveScene, 500);
            });
        }
    } catch (error) {
        console.error("Ứng dụng không thể khởi tạo:", error);
    }
});

/**
 * Initializes the full-screen Leaflet Map
 */
function initMap() {
    // Đọc vị trí và zoom đã lưu từ localStorage
    const savedLat = localStorage.getItem('map-lat');
    const savedLng = localStorage.getItem('map-lng');
    const savedZoom = localStorage.getItem('map-zoom');

    // Đảm bảo tọa độ khởi tạo luôn hợp lệ
    let startLat = parseFloat(savedLat);
    let startLng = parseFloat(savedLng);
    let startZoom = parseInt(savedZoom);

    if (isNaN(startLat)) startLat = 21.0285;
    if (isNaN(startLng)) startLng = 105.8542;
    if (isNaN(startZoom)) startZoom = 13;

    map = L.map('map', { zoomControl: true }).setView([startLat, startLng], startZoom);

    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        maxZoom: 19,
        attribution: '© OpenStreetMap contributors'
    }).addTo(map);

    // Khởi tạo Marker Cluster Group CHỈ dành cho Scene (Ảnh mẹ)
    markerClusterGroup = L.markerClusterGroup({
        zoomToBoundsOnClick: false, 
        spiderfyOnMaxZoom: true,    
        maxClusterRadius: 50,       
        spiderfyDistanceMultiplier: 3.5, // Tăng thêm khoảng cách để callout ảnh mẹ tách rõ ràng khi tỏa ra
        showCoverageOnHover: false,
        iconCreateFunction: function(cluster) {
            const childMarkers = cluster.getAllChildMarkers();
            try {
                if (childMarkers.length > 0 && childMarkers[0].options.icon) {
                    const childIcon = childMarkers[0].options.icon;
                    // Trả về một DivIcon MỚI dựa trên cấu hình của con, tránh dùng chung instance gây crash render
                    return L.divIcon({
                        html: childIcon.options.html,
                        className: childIcon.options.className,
                        iconSize: childIcon.options.iconSize,
                        iconAnchor: childIcon.options.iconAnchor
                    });
                }
            } catch (e) {}
            return L.divIcon({ className: 'cluster-fallback', html: '<div style="background:#007bff;width:10px;height:10px;border-radius:50%;"></div>' });
        }
    });

    // Khi click chuột trái vào một cụm callout, thực hiện tách chúng ra
    markerClusterGroup.on('clusterclick', (a) => {
        a.layer.spiderfy();
    });

    map.addLayer(markerClusterGroup);

    // Lưu vị trí bản đồ mỗi khi người dùng di chuyển hoặc zoom xong
    map.on('moveend', () => {
        const center = map.getCenter();
        localStorage.setItem('map-lat', center.lat);
        localStorage.setItem('map-lng', center.lng);
        localStorage.setItem('map-zoom', map.getZoom());
    });

    // Event listener for right-click on map to open modal
    map.on('contextmenu', (e) => {
        // Nếu viewer 3D đang hiển thị, không thực hiện tạo scene trên bản đồ
        const viewerContainer = document.getElementById('viewer-container');
        // Kiểm tra z-index và display để chắc chắn viewer đang ẩn
        if (viewerContainer && viewerContainer.style.display !== 'none') {
            return;
        }
        
        // Chỉ Admin (Chủ sở hữu) mới có quyền tạo Scene mới trực tiếp trên map qua contextmenu
        const userRole = localStorage.getItem('role');
        const isAdmin = userRole === 'Chủ sở hữu' || userRole === 'admin';
        if (!isAdmin) return;

        const { lat, lng } = e.latlng;
        openCreateSceneModal(lat, lng);
    });
}

/**
 * Checks if user is logged in (via localStorage JWT) and updates UI
 */
function checkAuthStatus() {
    const token = localStorage.getItem('jwt');
    const username = localStorage.getItem('username');
    const role = localStorage.getItem('role');

    const authGuest = document.getElementById('auth-guest');
    const authLoggedIn = document.getElementById('auth-logged-in');

    if (token && username) {
        authGuest.style.display = 'none';
        authLoggedIn.style.display = 'block';
        document.getElementById('logged-username').innerText = username;
        document.getElementById('logged-role').innerText = role || 'Thành viên';
    } else {
        authGuest.style.display = 'block';
        authLoggedIn.style.display = 'none';
    }
}

/**
 * Handles user login
 */
async function handleLogin() {
    const username = document.getElementById('username-input').value.trim();
    const password = document.getElementById('password-input').value.trim();

    if (!username || !password) {
        alert('Please fill in both fields');
        return;
    }

    try {
        const response = await fetch(`${API_BASE_URL}/auth/login`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ username, password })
        });

        const data = await response.json();
        if (!response.ok) throw new Error(data.message || 'Login failed');

        localStorage.setItem('jwt', data.token);
        localStorage.setItem('username', data.user.username);
        localStorage.setItem('role', data.user.role);
        localStorage.setItem('userId', data.user.id);

        checkAuthStatus();
        loadScenes(); // Reload scenes to show member/private scenes
        alert('Logged in successfully!');
    } catch (error) {
        alert(error.message);
    }
}

/**
 * Handles user registration
 */
async function handleRegister() {
    const username = document.getElementById('username-input').value.trim();
    const password = document.getElementById('password-input').value.trim();

    if (!username || !password) {
        alert('Please fill in both fields');
        return;
    }

    try {
        const response = await fetch(`${API_BASE_URL}/auth/register`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ username, password, role: 'Thành viên' })
        });

        const data = await response.json();
        if (!response.ok) throw new Error(data.message || 'Registration failed');

        alert('Registration successful! You can now log in.');
    } catch (error) {
        alert(error.message);
    }
}

/**
 * Handles user logout
 */
function handleLogout() {
    localStorage.removeItem('jwt');
    localStorage.removeItem('username');
    localStorage.removeItem('role');
    localStorage.removeItem('activeSceneId');
    localStorage.removeItem('activeScenePrivacy');
    localStorage.removeItem('activeSceneToken');
    localStorage.removeItem('userId');
    
    // Đảm bảo đóng viewer nếu đang mở
    if (typeof closeViewer === 'function') {
        closeViewer();
    }
    
    checkAuthStatus();
    loadScenes(); // Reload scenes to filter out private ones
    alert('Logged out successfully');
}

/**
 * Opens Modal for creating a Scene and sets lat/lng inputs
 */
function openCreateSceneModal(lat, lng) {
    const token = localStorage.getItem('jwt');
    if (!token) {
        alert('Please log in first to create a 3D scene.');
        return;
    }

    // Place a temporary marker on the map
    if (tempMarker) map.removeLayer(tempMarker);
    tempMarker = L.marker([lat, lng]).addTo(map);

    document.getElementById('create-scene-modal').style.display = 'flex';
    document.getElementById('modal-scene-id').value = '';
    document.getElementById('modal-lat').value = lat.toFixed(6);
    document.getElementById('modal-lng').value = lng.toFixed(6);
}

/**
 * Closes the Create Scene Modal and removes temporary marker
 */
function closeModal() {
    document.getElementById('create-scene-modal').style.display = 'none';
    if (tempMarker) {
        map.removeLayer(tempMarker);
        tempMarker = null;
    }
    document.getElementById('create-scene-form').reset();
    document.getElementById('shared-with-group').style.display = 'none';
}

/**
 * Toggles visibility of the shared users input based on privacy selection
 */
function toggleSharedUsers() {
    const privacy = document.getElementById('modal-privacy').value;
    const group = document.getElementById('shared-with-group');
    if (privacy === 'shared') {
        group.style.display = 'block';
    } else {
        group.style.display = 'none';
    }
}

/**
 * Form submission for Scene creation (multipart/form-data)
 */
async function submitScene(e) {
    e.preventDefault();
    const form = document.getElementById('create-scene-form');
    const formData = new FormData(form);
    const sceneId = document.getElementById('modal-scene-id').value;
    const token = localStorage.getItem('jwt');

    const url = sceneId ? `${API_BASE_URL}/scenes/${sceneId}` : `${API_BASE_URL}/scenes`;
    const method = sceneId ? 'PUT' : 'POST';

    uploadWithProgress(url, method, formData, token, 'create', () => {
        alert(sceneId ? 'Scene đang được cập nhật ngầm!' : 'Scene đã được tạo! Ảnh đang được xử lý 8K...');
        closeModal();
        loadScenes();
    });
}

/**
 * Helper function to handle uploads with progress bars
 */
function uploadWithProgress(url, method, formData, token, prefix, callback) {
    const xhr = new XMLHttpRequest();
    const container = document.getElementById(`${prefix}-progress-container`);
    const bar = document.getElementById(`${prefix}-progress-bar`);
    const percentText = document.getElementById(`${prefix}-progress-percent`);
    const statusText = document.getElementById(`${prefix}-progress-status`);

    if (container) container.style.display = 'block';
    if (statusText) statusText.innerText = "Đang tải ảnh lên...";

    xhr.upload.addEventListener('progress', (e) => {
        if (e.lengthComputable) {
            const percent = Math.round((e.loaded / e.total) * 100);
            if (bar) bar.style.width = percent + '%';
            if (percentText) percentText.innerText = percent + '%';
            if (percent === 100 && statusText) statusText.innerText = "Tải lên xong! Đang khởi tạo trên server...";
        }
    });

    xhr.addEventListener('load', () => {
        if (container) container.style.display = 'none';
        if (xhr.status >= 200 && xhr.status < 300) {
            callback(JSON.parse(xhr.responseText));
        } else {
            let errorMsg = 'Không thể tải lên';
            try {
                const err = JSON.parse(xhr.responseText);
                errorMsg = err.message || errorMsg;
            } catch (e) {}
            alert('Lỗi: ' + errorMsg);
        }
    });

    xhr.addEventListener('error', () => {
        if (container) container.style.display = 'none';
        alert('Lỗi kết nối mạng.');
    });

    xhr.open(method, url);
    if (token) xhr.setRequestHeader('Authorization', `Bearer ${token}`);
    xhr.send(formData);
}

/**
 * Loads and displays visible Scenes on the map
 */
async function loadScenes() {
    try {
        const token = localStorage.getItem('jwt');
        const headers = {};
        if (token) {
            headers['Authorization'] = `Bearer ${token}`;
        }

        // Thêm timestamp để tránh lỗi 304 hang do cache trình duyệt
        const timestamp = new Date().getTime();
        console.log(`3.1 Đang gửi yêu cầu lấy danh sách Scene (ts: ${timestamp})...`);
        const response = await fetch(`${API_BASE_URL}/scenes?_=${timestamp}`, {
            method: 'GET',
            headers
        });

        console.log(`[API Response] /scenes status: ${response.status}`);
        if (!response.ok) throw new Error('Failed to load scenes');
        const scenes = await response.json();
        
        console.log(`[Data] Nhận được ${scenes.length} scenes từ server`);
        if (!Array.isArray(scenes)) return;

        // Xóa sạch các layers cũ trước khi nạp mới
        markerClusterGroup.clearLayers();
        const markersToAdd = [];
        const activeSceneId = localStorage.getItem('activeSceneId');
        const seenCoordinates = new Set(); // Dùng để lọc "Ảnh mẹ" (1 marker per location)

        // Chỉ lặp qua danh sách Scene mẹ, lọc bỏ các hotspots trùng tọa độ
        scenes.forEach((scene) => {
            // Ép kiểu tọa độ về Number để tránh lỗi render bản đồ
            const latNum = Number(scene.gps?.lat || scene.lat);
            const lngNum = Number(scene.gps?.lng || scene.lng);

            if (isNaN(latNum) || isNaN(lngNum)) return;

            // Logic lọc Ảnh mẹ: Mỗi tọa độ GPS chỉ tạo duy nhất 1 Marker đại diện
            const coordKey = `${latNum.toFixed(6)},${lngNum.toFixed(6)}`;
            if (seenCoordinates.has(coordKey)) return; // Bỏ qua nếu tọa độ này đã có Marker
            seenCoordinates.add(coordKey);

            // Kiểm tra an toàn dữ liệu từ MongoDB trước khi truy cập
            const assetId = scene.assetId?._id || scene.assetId;
            const sceneName = scene.name || scene.title;

            let thumbUrl = `${API_BASE_URL}/assets/view/${assetId}`;
            if (token) thumbUrl += `?token=${token}`;
            else if (scene.privacy === 'shared' && scene.shareToken) thumbUrl += `?token=${scene.shareToken}`;

            const calloutIcon = L.divIcon({
                className: 'custom-scene-marker',
                html: `
                    <div class="scene-callout">
                        <div class="scene-img-wrapper">
                            <img src="${thumbUrl}" alt="${sceneName}">
                        </div>
                    </div>`,
                iconSize: [64, 64],
                iconAnchor: [32, 76] // Căn giữa ngang, đáy mũi tên tại tọa độ lat/lng
            });

            const marker = L.marker([latNum, lngNum], { 
                icon: calloutIcon,
                title: sceneName
            });
            
            // Tạo nội dung thông tin khi Hover (Tooltip)
            const createdDate = scene.assetId?.createdAt ? new Date(scene.assetId.createdAt).toLocaleDateString('vi-VN') : 'N/A';
            const tooltipContent = `
                <div class="scene-hover-info">
                    <strong>${sceneName}</strong><br>
                    ${scene.description ? `<small>${scene.description}</small><br>` : ''}
                    <span>Người tạo: ${scene.createdBy ? scene.createdBy.username : 'Ẩn danh'}</span><br>
                    <span>Ngày tạo: ${createdDate}</span>
                </div>
            `;

            // Gán Tooltip cho sự kiện Hover
            marker.bindTooltip(tooltipContent, {
                direction: 'top',
                offset: [0, -70],
                className: 'custom-scene-tooltip'
            });

            // Sự kiện Click chuột trái: Vào thẳng trình xem 360
            marker.on('click', () => {
                openScene(scene._id, scene.privacy, scene.shareToken || '');
            });

            marker.on('contextmenu', (e) => {
                if (e.originalEvent) {
                    L.DomEvent.stop(e.originalEvent);
                }

                const currentUserId = localStorage.getItem('userId');
                const userRole = localStorage.getItem('role');
                // Hỗ trợ cả schema cũ (owner) và mới (createdBy)
                const ownerId = scene.createdBy?._id || scene.createdBy || scene.owner?._id || scene.owner;

                // Phân quyền: Admin hoặc Chủ sở hữu Scene
                const isAdmin = userRole === 'Chủ sở hữu' || userRole === 'admin';
                if (isAdmin || (currentUserId && ownerId && ownerId.toString() === currentUserId.toString())) {
                    handleEditDeleteScene(scene);
                } else {
                    alert("Bạn không có quyền chỉnh sửa scene này.");
                }
            });

            markersToAdd.push(marker);
        });

        // Thêm danh sách marker đã lọc vào group
        markerClusterGroup.addLayers(markersToAdd);

    } catch (error) {
        console.error('Error loading scenes:', error);
    }
}

/**
 * Handles Edit/Delete options for a scene
 */
async function handleEditDeleteScene(scene) {
    const modal = document.getElementById('action-choice-modal');
    const title = document.getElementById('action-modal-title');
    const editBtn = document.getElementById('btn-edit-action');
    const deleteBtn = document.getElementById('btn-delete-action');

    title.innerText = `Scene: ${scene.title}`;
    modal.style.display = 'flex';

    // Gán sự kiện cho nút Sửa
    editBtn.onclick = () => {
        closeActionModal();
        openEditSceneModal(scene);
    };

    // Gán sự kiện cho nút Xóa
    deleteBtn.onclick = async () => {
        if (confirm(`Cảnh báo: Thao tác này sẽ xóa vĩnh viễn scene "${scene.title}" và tệp tin ảnh 360 liên quan. Bạn có chắc chắn?`)) {
            closeActionModal();
            await deleteScene(scene._id);
        }
    };
}

/**
 * Closes the Action Choice Modal
 */
function closeActionModal() {
    document.getElementById('action-choice-modal').style.display = 'none';
}

/**
 * Opens the modal in Edit mode
 */
function openEditSceneModal(scene) {
    document.getElementById('modal-scene-id').value = scene._id;
    // Cập nhật để hỗ trợ cả cấu trúc cũ và mới (gps.lat/name)
    document.getElementById('modal-lat').value = scene.gps?.lat || scene.lat;
    document.getElementById('modal-lng').value = scene.gps?.lng || scene.lng;
    const sceneName = scene.name || scene.title;
    document.getElementById('modal-title').value = sceneName;
    document.getElementById('modal-privacy').value = scene.privacy;
    document.getElementById('modal-panorama').required = false; // Photo update is optional
    
    toggleSharedUsers();
    document.getElementById('create-scene-modal').style.display = 'flex';
}

/**
 * Deletes a scene via API
 */
async function deleteScene(sceneId) {
    const token = localStorage.getItem('jwt');
    try {
        const response = await fetch(`${API_BASE_URL}/scenes/${sceneId}`, {
            method: 'DELETE',
            headers: { 'Authorization': `Bearer ${token}` }
        });
        if (!response.ok) throw new Error('Failed to delete scene');
        alert('Scene deleted successfully');
        loadScenes();
    } catch (error) {
        alert(error.message);
    }
}

/**
 * Fetches secure scene details and triggers the Panorama viewer
 */
async function openScene(sceneId, privacy, shareToken, force = false) {
    // Nếu đang xem chính scene này và không yêu cầu làm mới (force), không cần nạp lại
    if (!force && currentSceneId === sceneId && document.getElementById('viewer-container').style.display === 'block') {
        return;
    }

    try {
        const token = localStorage.getItem('jwt');
        const headers = {};
        if (token) {
            headers['Authorization'] = `Bearer ${token}`;
        }

        console.log(`[Viewer] Đang mở scene: ${sceneId}`);
        let url = `${API_BASE_URL}/scenes/${sceneId}`;
        if (privacy === 'shared' && shareToken) {
            url += `?token=${shareToken}`;
        }

        // Lưu trạng thái Scene hiện tại để khôi phục sau khi reload trang
        localStorage.setItem('activeSceneId', sceneId);
        localStorage.setItem('activeScenePrivacy', privacy || '');
        localStorage.setItem('activeSceneToken', shareToken || '');

        // Nạp đồng thời Scene và danh sách Hotspots từ Collection riêng
        const [sceneRes, hotspotsRes] = await Promise.all([
            fetch(url, { method: 'GET', headers }),
            fetch(`${API_BASE_URL}/hotspots/${sceneId}`, { method: 'GET', headers })
        ]);

        const scene = await sceneRes.json();
        const hotspots = await hotspotsRes.json();

        if (!sceneRes.ok) throw new Error(scene.message || 'Failed to fetch scene details');

        // Lấy ID người tạo (createdBy) để phân quyền chuột phải trong viewer
        const sceneOwnerId = scene.createdBy?._id || scene.createdBy || scene.owner?._id || scene.owner;

        // Tự động focus bản đồ vào vị trí của Scene
        if (map) {
            map.flyTo([scene.gps?.lat || scene.lat, scene.gps?.lng || scene.lng], 16);
        }

        // Cập nhật tọa độ vào các input ẩn để hỗ trợ GPS inheritance cho hotspot khi tải ảnh mới
        document.getElementById('modal-lat').value = scene.gps?.lat || scene.lat;
        document.getElementById('modal-lng').value = scene.gps?.lng || scene.lng;

        // Cập nhật lịch sử di chuyển để hỗ trợ tạo hotspot ngược tự động
        if (currentSceneId && currentSceneId !== sceneId) {
            previousSceneId = currentSceneId;
        }
        currentSceneId = sceneId;

        // Kiểm tra an toàn assetId (hỗ trợ cả dạng Object và String ID)
        const assetId = scene.assetId?._id || scene.assetId;
        if (!assetId) throw new Error("Dữ liệu hình ảnh của cảnh này bị lỗi hoặc chưa xử lý xong.");

        let secureImageUrl = `${API_BASE_URL}/assets/view/${assetId}`;
        
        // Ưu tiên JWT token nếu đang đăng nhập, nếu không thì dùng shareToken
        if (token) {
            secureImageUrl += `?token=${token}`;
        } else if (privacy === 'shared' && scene.shareToken) {
            secureImageUrl += `?token=${scene.shareToken}`;
        }

        // Initialize 3D Viewer with secure, referer-protected image stream
        initPanoramaViewer(secureImageUrl, hotspots || [], sceneOwnerId);

    } catch (error) {
        localStorage.removeItem('activeSceneId');
        localStorage.removeItem('activeScenePrivacy');
        localStorage.removeItem('activeSceneToken');
        alert(error.message);
    }
}

/**
 * Khôi phục Scene đang xem từ localStorage sau khi reload trang
 */
function restoreActiveScene() {
    const savedSceneId = localStorage.getItem('activeSceneId');
    if (savedSceneId) {
        const savedPrivacy = localStorage.getItem('activeScenePrivacy');
        const savedToken = localStorage.getItem('activeSceneToken');
        openScene(savedSceneId, savedPrivacy, savedToken);
    }
}

/**
 * Xử lý việc tạo hotspot sau khi click chuột phải trong trình xem 360
 * @param {number} pitch - Tọa độ dọc (-90 đến 90)
 * @param {number} yaw - Tọa độ ngang (-180 đến 180)
 * @param {Object} existingHotspot - Thông tin hotspot cũ nếu có
 */
window.handleHotspotCreation = async function(pitch, yaw, existingHotspot = null) {
    const token = localStorage.getItem('jwt');
    if (!token) {
        alert('Vui lòng đăng nhập để thực hiện thao tác này.');
        return;
    }

    const modal = document.getElementById('hotspot-modal');
    const form = document.getElementById('hotspot-form');
    
    // Hiển thị Modal TRƯỚC để các logic UI (như Mini Map) tính toán được kích thước
    modal.style.display = 'flex';

    // Reset form và gán tọa độ
    form.reset();
    document.getElementById('hs-pitch').value = pitch;
    document.getElementById('hs-yaw').value = yaw;
    document.getElementById('hs-id').value = existingHotspot ? existingHotspot._id : '';
    document.getElementById('hotspot-modal-title').innerText = existingHotspot ? 'Cập nhật điểm điều hướng' : 'Thêm điểm điều hướng mới';

    // Reset UI states
    document.querySelector('input[name="hsLinkType"][value="existing"]').checked = true;
    window.toggleHSLinkType('existing');
    document.querySelector('input[name="hsGPSMode"][value="map"]').checked = true;
    window.toggleHSGPSMode('map');

    // Lấy danh sách Scene có sẵn để đổ vào dropdown
    try {
        const res = await fetch(`${API_BASE_URL}/scenes`, { headers: { 'Authorization': `Bearer ${token}` } });
        const scenes = await res.json();
        const select = document.getElementById('hs-target-id');
        select.innerHTML = '<option value="">-- Chọn một cảnh để liên kết --</option>';
        scenes.forEach(s => {
            if (s._id !== currentSceneId) { // Không liên kết tới chính nó
                select.innerHTML += `<option value="${s._id}">${s.name || s.title}</option>`;
            }
        });

        // QUAN TRỌNG: Chỉ điền dữ liệu hotspot cũ SAU KHI dropdown đã được nạp đầy đủ options
        if (existingHotspot) {
            document.getElementById('hs-title').value = existingHotspot.title || '';
            document.getElementById('hs-desc').value = existingHotspot.description || '';
            if (existingHotspot.target_scene_id) {
                select.value = existingHotspot.target_scene_id;
            }
        }
    } catch (e) { console.error("Lỗi nạp danh sách scene:", e); }

    // Xử lý sự kiện submit form
    form.onsubmit = async (e) => {
        e.preventDefault();
        const formData = new FormData(form);
        const linkType = formData.get('hsLinkType');

        if (linkType === 'upload') {
            const file = document.getElementById('hs-panorama-file').files[0];
            if (!file) {
                alert('Vui lòng chọn ảnh panorama.');
                return;
            }

            const gpsMode = formData.get('hsGPSMode');
            let lat = 0, lng = 0;

            if (gpsMode === 'inherit') {
                // Ép kiểu về Number khi lấy từ input
                lat = Number(document.getElementById('modal-lat').value);
                lng = Number(document.getElementById('modal-lng').value);
            } else {
                lat = Number(document.getElementById('hs-lat').value);
                lng = Number(document.getElementById('hs-lng').value);
                if (!lat || !lng) {
                    alert('Vui lòng chọn vị trí GPS.');
                    return;
                }
            }

            const sceneData = new FormData();
            sceneData.append('panorama', file);
            sceneData.append('title', formData.get('title'));
            sceneData.append('lat', lat); // FormData sẽ convert sang string, Backend cần ép kiểu lại
            sceneData.append('lng', lng);
            sceneData.append('privacy', 'public');

            uploadWithProgress(`${API_BASE_URL}/scenes`, 'POST', sceneData, token, 'hs', async (sceneRes) => {
                await saveHotspotToDB(pitch, yaw, formData.get('title'), formData.get('description'), sceneRes.scene._id, existingHotspot?._id);
                closeHotspotModal();
            });
            return;
        }

        const finalTargetId = formData.get('targetSceneId');
        if (!finalTargetId) {
            alert('Vui lòng chọn cảnh để liên kết.');
            return;
        }
        await saveHotspotToDB(pitch, yaw, formData.get('title'), formData.get('description'), finalTargetId, existingHotspot?._id);
        modal.style.display = 'none';
    };
};

/**
 * Đóng Modal biên tập Hotspot
 */
function closeHotspotModal() {
    document.getElementById('hotspot-modal').style.display = 'none';
}

/**
 * Khởi tạo hoặc cập nhật Mini Map trong Hotspot Modal
 */
function initHSMiniMap() {
    const pLat = parseFloat(document.getElementById('modal-lat').value) || 21.0285;
    const pLng = parseFloat(document.getElementById('modal-lng').value) || 105.8542;

    if (miniMap) {
        miniMap.setView([pLat, pLng], 15);
        updateHSMiniMapMarker(pLat, pLng);
        // Fix lỗi vỡ tiles của Leaflet trong Modal
        setTimeout(() => miniMap.invalidateSize(), 200);
        return;
    }
    
    miniMap = L.map('hs-mini-map').setView([pLat, pLng], 15);
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(miniMap);
    
    miniMap.on('click', (e) => {
        const { lat, lng } = e.latlng;
        updateHSMiniMapMarker(lat, lng);
    });
    
    updateHSMiniMapMarker(pLat, pLng);
    setTimeout(() => miniMap.invalidateSize(), 200);
}

function updateHSMiniMapMarker(lat, lng) {
    if (miniMapMarker) miniMap.removeLayer(miniMapMarker);
    miniMapMarker = L.marker([lat, lng]).addTo(miniMap);
    document.getElementById('hs-lat').value = lat.toFixed(6);
    document.getElementById('hs-lng').value = lng.toFixed(6);
}

window.toggleHSLinkType = function(type) {
    document.getElementById('hs-section-existing').style.display = type === 'existing' ? 'block' : 'none';
    document.getElementById('hs-section-upload').style.display = type === 'upload' ? 'block' : 'none';
    
    if (type === 'upload') {
        const gpsMode = document.querySelector('input[name="hsGPSMode"]:checked')?.value || 'map';
        window.toggleHSGPSMode(gpsMode);
    }
};

window.toggleHSGPSMode = function(mode) {
    document.getElementById('hs-map-selector').style.display = mode === 'map' ? 'block' : 'none';
    document.getElementById('hs-manual-gps').style.display = mode === 'manual' ? 'block' : 'none';
    
    if (mode === 'map') initHSMiniMap();
};

/**
 * Chuyển đổi tab cũ (giữ lại để tương thích nếu cần)
 */
function switchHSTab(tabName) {
    if (tabName === 'select') {
        window.toggleHSLinkType('existing');
    } else {
        window.toggleHSLinkType('upload');
    }
}

/**
 * Ẩn/hiện input nhập GPS thủ công
 */
function toggleManualGPS() {
    const mode = document.getElementById('hs-gps-mode').value;
    const manualDiv = document.getElementById('hs-manual-gps');
    manualDiv.style.display = mode === 'manual' ? 'block' : 'none';
}

/**
 * Gửi dữ liệu lưu Hotspot lên Backend
 */
async function saveHotspotToDB(pitch, yaw, title, description, targetSceneId, hotspotId) {
    const token = localStorage.getItem('jwt');
    // Gọi đúng API create hoặc update tùy vào trạng thái
    const url = hotspotId ? `${API_BASE_URL}/hotspots/update/${hotspotId}` : `${API_BASE_URL}/hotspots/create`;
    const method = hotspotId ? 'PUT' : 'POST';

    try {
        const body = {
            title,
            description,
            target_scene_id: targetSceneId,
            coordinates: {
                pitch: Number(pitch),
                yaw: Number(yaw)
            }
        };

        // Nếu tạo mới, cần gửi kèm ID của scene hiện tại làm parent
        if (!hotspotId) {
            body.parent_scene_id = currentSceneId;
        }

        const response = await fetch(url, {
            method: method,
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${token}`
            },
            body: JSON.stringify(body)
        });

        const data = await response.json();
        if (!response.ok) throw new Error(data.message || 'Lỗi khi lưu hotspot');

        alert('Lưu điểm điều hướng thành công!');
        // Buộc nạp lại để cập nhật danh sách hotspot mới
        openScene(currentSceneId, localStorage.getItem('activeScenePrivacy'), localStorage.getItem('activeSceneToken'), true);
        
    } catch (error) {
        console.error(error);
        alert(error.message);
    }
}

/**
 * Công cụ dọn dẹp toàn bộ dữ liệu (Chỉ dùng cho nhà phát triển)
 * Gọi lệnh: systemReset() từ trình duyệt
 */
window.systemReset = async function() {
    if (!confirm("CẢNH BÁO: Thao tác này sẽ xóa sạch TOÀN BỘ scene và ảnh trên server. Bạn có chắc chắn?")) return;
    
    const token = localStorage.getItem('jwt');
    try {
        const response = await fetch(`${API_BASE_URL}/maintenance/reset-all`, {
            method: 'POST',
            headers: { 'Authorization': `Bearer ${token}` }
        });
        const data = await response.json();
        
        if (response.ok) {
            localStorage.clear(); // Xóa sạch token, vị trí map, active scene
            alert(data.message);
            location.reload();
        } else {
            throw new Error(data.message);
        }
    } catch (e) {
        alert("Lỗi reset: " + e.message);
    }
};

/**
 * Mở Menu tùy chọn cho Hotspot (Sửa/Xóa)
 */
window.openHotspotMenu = function(hotspot) {
    const modal = document.getElementById('hotspot-action-modal');
    const editBtn = document.getElementById('btn-hs-edit');
    const deleteBtn = document.getElementById('btn-hs-delete');

    modal.style.display = 'flex';

    // Hành động Sửa: Mở form biên tập với dữ liệu cũ
    editBtn.onclick = () => {
        closeHotspotActionModal();
        window.handleHotspotCreation(hotspot.pitch, hotspot.yaw, hotspot);
    };

    // Hành động Xóa: Xác nhận và gọi API xóa
    deleteBtn.onclick = async () => {
        if (confirm('Bạn có chắc chắn muốn xóa điểm điều hướng này?')) {
            closeHotspotActionModal();
            await deleteHotspot(hotspot._id);
        }
    };
};

/**
 * Đóng Modal tùy chọn Hotspot
 */
function closeHotspotActionModal() {
    document.getElementById('hotspot-action-modal').style.display = 'none';
}

/**
 * Xóa Hotspot thông qua API
 */
async function deleteHotspot(hotspotId) {
    const token = localStorage.getItem('jwt');
    try {
        // Gọi đúng API delete hotspot độc lập
        const response = await fetch(`${API_BASE_URL}/hotspots/delete/${hotspotId}`, {
            method: 'DELETE',
            headers: { 'Authorization': `Bearer ${token}` }
        });
        
        if (!response.ok) {
            const err = await response.json();
            throw new Error(err.message || 'Lỗi xóa hotspot');
        }

        alert('Đã xóa điểm điều hướng.');
        // Refresh lại scene hiện tại để cập nhật viewer
        openScene(currentSceneId, null, null, true);
    } catch (e) {
        alert(e.message);
    }
}
