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;
let systemSettings = { timezone: 'Asia/Ho_Chi_Minh', language: 'vi' };
let returnToDashboardAfterEdit = false;
let assetIdToDelete = null;
let sceneIdToDelete = null;
let dashboardReturnTab = 'media-library';
let editMiniMap = null;
let editMiniMapMarker = null;
let currentEditingScene = null; // Lưu object scene đang sửa để quản lý chia sẻ
let sharedUsersData = []; // [{id, username, email}]
let sharedEmailsData = []; // [email]

// Initialize when DOM is ready
document.addEventListener('DOMContentLoaded', () => {
    try {
        console.log("--- Bắt đầu khởi tạo Frontend ---");
        
        // 0. Kiểm tra tham số URL để truy cập trực tiếp
        const urlParams = new URLSearchParams(window.location.search);
        const urlSceneId = urlParams.get('sceneId');
        const urlToken = urlParams.get('token');

        // Ưu tiên nạp cấu hình hệ thống trước
        fetchSystemSettings();

        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
        
        // 3. Xử lý logic vào thẳng Scene hoặc khôi phục trang
        if (urlSceneId) {
            console.log(`[Direct Access] Opening scene ${urlSceneId} from URL`);
            openScene(urlSceneId, urlToken ? 'shared' : null, urlToken);
        } else {
            restoreActiveScene();
        }

        // Đảm bảo map đã sẵn sàng trước khi nạp data
        if (map) {
            // Chỉ nạp danh sách Scene để vẽ marker lên bản đồ
            loadScenes();
        }
    } catch (error) {
        console.error("Ứng dụng không thể khởi tạo:", error);
    }
});

/**
 * Lấy cấu hình hệ thống từ Backend
 */
async function fetchSystemSettings() {
    try {
        const res = await fetch(`${API_BASE_URL}/system/settings`);
        if (res.ok) {
            systemSettings = await res.json();
            applySystemSettings();
        }
    } catch (e) {
        console.warn("Không thể nạp cấu hình hệ thống, dùng mặc định.");
    }
}

/**
 * Áp dụng cấu hình Múi giờ và Ngôn ngữ vào UI
 */
function applySystemSettings() {
    console.log(`[System] Applying settings: Language=${systemSettings.language}, Timezone=${systemSettings.timezone}`);
    
    // 1. Cập nhật nhãn (Labels) dựa trên ngôn ngữ
    const translations = {
        vi: {
            brand: "Bản đồ Tour 3D Ảo",
            login: "Đăng nhập / Đăng ký",
            profile: "Quản lý hồ sơ",
            logout: "Đăng xuất",
            dashboardTitle: "Bảng điều khiển người dùng",
            tabProfile: "Hồ sơ",
            tabScenes: "Quản lí scene",
            tabMedia: "Quản lí ảnh và media",
            tabUsers: "Quản lí người dùng",
            tabSystem: "Cài đặt hệ thống"
        },
        en: {
            brand: "Virtual 3D Tour Map",
            login: "Login / Register",
            profile: "Manage Profile",
            logout: "Logout",
            dashboardTitle: "User Dashboard",
            tabProfile: "Profile",
            tabScenes: "My Scenes",
            tabMedia: "Media Library",
            tabUsers: "User Management",
            tabSystem: "System Settings"
        }
    };

    const lang = systemSettings.language || 'vi';
    const t = translations[lang];

    // Cập nhật các phần tử cố định
    const brandH1 = document.querySelector('.app-brand h1');
    if (brandH1) brandH1.innerText = t.brand;

    const dashboardH2 = document.querySelector('.dashboard-content h2');
    if (dashboardH2) dashboardH2.innerText = t.dashboardTitle;

    // Cập nhật các nút Tab
    const tabButtons = document.querySelectorAll('.dashboard-tabs .tab-btn');
    if (tabButtons.length >= 3) {
        tabButtons[0].innerText = t.tabProfile;
        tabButtons[1].innerText = t.tabScenes;
        tabButtons[2].innerText = t.tabMedia;
        if (tabButtons[3]) tabButtons[3].innerText = t.tabUsers;
        if (tabButtons[4]) tabButtons[4].innerText = t.tabSystem;
    }

    const profileBtn = document.querySelector('button[onclick="openDashboard()"]');
    if (profileBtn) profileBtn.innerText = t.profile;

    const logoutBtn = document.querySelector('button[onclick="handleLogout()"]');
    if (logoutBtn) logoutBtn.innerText = t.logout;
}

/**
 * Hàm định dạng dung lượng file cho Frontend
 */
function formatBytes(bytes, decimals = 2) {
    if (!bytes || bytes === 0) return '0 Bytes';
    const k = 1024;
    const dm = decimals < 0 ? 0 : decimals;
    const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}

/**
 * Tải và hiển thị thống kê các tệp tin lớn nhất
 */
async function loadMediaStats() {
    const token = localStorage.getItem('jwt');
    const statsContainer = document.getElementById('media-library-stats');
    if (!statsContainer) return;

    try {
        const res = await fetch(`${API_BASE_URL}/me/assets/top-large`, {
            headers: { 'Authorization': `Bearer ${token}` }
        });
        const topFiles = await res.json();
        
        if (topFiles && topFiles.length > 0) {
            let html = `
                <div class="top-files-section">
                    <h4><i class="fas fa-database"></i> Tệp tin chiếm dụng lớn nhất</h4>
                    <div class="top-files-list">
            `;
            topFiles.forEach(file => {
                const fileName = file.scene?.name || file.scene?.title || 'Ảnh chưa gắn Scene';
                html += `
                    <div class="top-file-item">
                        <span class="top-file-name">● ${fileName}</span>
                        <span class="top-file-size">${formatBytes(file.fileSize)}</span>
                    </div>
                `;
            });
            html += `</div></div>`;
            statsContainer.innerHTML = html;
        } else {
            statsContainer.innerHTML = '';
        }
    } catch (e) {
        console.warn("Không thể nạp thống kê media:", e);
    }
}

/**
 * Cập nhật nội dung tab Hồ sơ với thông tin người dùng
 */
async function updateProfileTabContent() {
    const token = localStorage.getItem('jwt');
    const username = localStorage.getItem('username');
    const role = localStorage.getItem('role');

    const avatar = document.getElementById('profile-avatar-initials');
    const userDisplay = document.getElementById('profile-username-display');
    const statusDisplay = document.getElementById('profile-status-display');
    const userInput = document.getElementById('profile-username');

    if (avatar && username) avatar.innerText = username.charAt(0).toUpperCase();
    if (userDisplay) userDisplay.innerText = username;
    if (statusDisplay) statusDisplay.innerText = role || 'Thành viên';
    if (userInput) userInput.value = username;

    // Lấy dữ liệu dung lượng thực tế từ server
    try {
        const res = await fetch(`${API_BASE_URL}/me/profile`, {
            headers: { 'Authorization': `Bearer ${token}` }
        });
        const data = await res.json();
        
        if (data.storage) {
            const { used, quota } = data.storage;
            const progress = document.getElementById('storage-progress-bar');
            const text = document.getElementById('storage-text');
            
            if (progress && text) {
                const usedMB = (used / (1024 * 1024)).toFixed(1);
                const quotaMB = quota === -1 ? '∞' : (quota / (1024 * 1024)).toFixed(0);
                text.innerText = `${usedMB} MB / ${quotaMB} MB`;
                
                if (quota !== -1) {
                    const percent = Math.min((used / quota) * 100, 100);
                    progress.style.width = percent + '%';
                    // Đổi màu thanh tiến trình dựa trên mức độ sử dụng
                    if (percent > 90) progress.style.background = '#dc3545'; // Đỏ (sắp hết)
                    else if (percent > 75) progress.style.background = '#ffc107'; // Vàng (cảnh báo)
                    else progress.style.background = '#28a745'; // Xanh (an toàn)
                } else {
                    progress.style.width = '100%';
                    progress.style.background = '#007bff'; // Màu xanh dương cho không giới hạn
                }
            }
        }
    } catch (e) {
        console.warn("Không thể tải thông tin dung lượng:", e);
    }
}

/**
 * Hàm bổ trợ định dạng ngày tháng theo múi giờ hệ thống
 */
function formatSystemDate(dateString) {
    if (!dateString) return 'N/A';
    const date = new Date(dateString);
    
    try {
        return new Intl.DateTimeFormat(systemSettings.language === 'vi' ? 'vi-VN' : 'en-US', {
            timeZone: systemSettings.timezone,
            year: 'numeric',
            month: '2-digit',
            day: '2-digit',
            hour: '2-digit',
            minute: '2-digit'
        }).format(date);
    } catch (e) {
        // Fallback nếu timezone không hợp lệ
        return date.toLocaleDateString();
    }
}

/**
 * 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;
    
    // Khởi tạo bản đồ với zoomControl và tắt attribution mặc định của Leaflet
    map = L.map('map', { zoomControl: true, attributionControl: false }).setView([startLat, startLng], startZoom);

    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        maxZoom: 19,
        // Attribution sẽ được thêm thủ công bên dưới để chỉ hiển thị OpenStreetMap
        // 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();
    });

    // Thêm attribution chỉ với OpenStreetMap, không có Leaflet
    L.control.attribution({ prefix: false }).addAttribution('OpenStreetMap contributors').addTo(map);

    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;
        }
        
        // Cho phép bất kỳ người dùng nào đã đăng nhập tạo Scene mới trên bản đồ
        const token = localStorage.getItem('jwt');
        if (!token) 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');

    const avatarInitials = document.getElementById('avatar-initials');

    if (token && username) {
        if (authGuest) authGuest.style.display = 'none'; // Hide login form
        authLoggedIn.style.display = 'block'; // Show welcome message and buttons
        avatarInitials.innerText = username.charAt(0).toUpperCase();
        
        // Hiển thị các nút dành cho admin (Chủ sở hữu/Admin tối cao)
        const adminButtons = document.querySelectorAll('.dashboard-tabs .admin-only');
        if (role === 'admin' || role === 'Chủ sở hữu') {
            adminButtons.forEach(btn => btn.style.display = 'block');
        } else {
            adminButtons.forEach(btn => btn.style.display = 'none');
        }
    } else {
        authGuest.style.display = 'block'; // Show login form
        authLoggedIn.style.display = 'none'; // Hide welcome message
        avatarInitials.innerText = '?';
        document.getElementById('user-dropdown').classList.remove('show'); // Đóng dropdown nếu không đăng nhập
    }
}

/**
 * Handles user login
 */
async function handleLogin() {
    const errorMsg = document.getElementById('login-error-msg');
    if (errorMsg) errorMsg.style.display = 'none';

    const username = document.getElementById('username-input').value.trim();
    const password = document.getElementById('password-input').value.trim();

    if (!username || !password) {
        if (errorMsg) {
            errorMsg.innerText = 'Vui lòng nhập đầy đủ thông tin';
            errorMsg.style.display = 'block';
        }
        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 || 'Đăng nhập thất bại');

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

        checkAuthStatus();
        toggleDropdown(); // Đóng dropdown sau khi đăng nhập
        loadScenes(); // Reload scenes to show member/private scenes
        
        // Làm sạch form
        document.getElementById('username-input').value = '';
        document.getElementById('password-input').value = '';
    } catch (error) {
        if (errorMsg) {
            errorMsg.innerText = error.message;
            errorMsg.style.display = 'block';
        }
    }
}

/**
 * Chuyển đổi giữa chế độ Đăng nhập và Đăng ký trong dropdown
 */
window.switchAuthMode = function(mode) {
    const loginSection = document.getElementById('login-section');
    const registerSection = document.getElementById('register-section');
    const loginBtn = document.getElementById('tab-login-btn');
    const registerBtn = document.getElementById('tab-register-btn');

    if (mode === 'login') {
        loginSection.style.display = 'block';
        registerSection.style.display = 'none';
        loginBtn.classList.add('active');
        registerBtn.classList.remove('active');
    } else {
        loginSection.style.display = 'none';
        registerSection.style.display = 'block';
        loginBtn.classList.remove('active');
        registerBtn.classList.add('active');
    }
};

/**
 * Handles user registration
 */
async function handleRegister() {
    const errorMsg = document.getElementById('reg-error-msg');
    if (errorMsg) errorMsg.style.display = 'none';

    const fullName = document.getElementById('reg-fullname').value.trim();
    const email = document.getElementById('reg-email').value.trim();
    const username = document.getElementById('reg-username').value.trim();
    const password = document.getElementById('reg-password').value;
    const confirm = document.getElementById('reg-confirm').value;
    const agree = document.getElementById('reg-agree').checked;

    // Kiểm tra các trường trống
    if (!fullName || !email || !username || !password || !confirm) {
        if (errorMsg) {
            errorMsg.innerText = 'Vui lòng điền đầy đủ thông tin';
            errorMsg.style.display = 'block';
        }
        return;
    }

    // Kiểm tra mật khẩu khớp nhau
    if (password !== confirm) {
        if (errorMsg) {
            errorMsg.innerText = 'Mật khẩu xác nhận không khớp';
            errorMsg.style.display = 'block';
        }
        return;
    }

    // Kiểm tra đồng ý quy định
    if (!agree) {
        if (errorMsg) {
            errorMsg.innerText = 'Bạn phải đồng ý với quy định của trang';
            errorMsg.style.display = 'block';
        }
        return;
    }

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

        const data = await response.json();
        if (!response.ok) throw new Error(data.message || 'Đăng ký thất bại');

        showNotification('Đăng ký thành công! Bạn có thể đăng nhập ngay bây giờ.', 'success');
        switchAuthMode('login'); // Tự động chuyển về tab đăng nhập sau khi thành công
    } catch (error) {
        if (errorMsg) {
            errorMsg.innerText = error.message;
            errorMsg.style.display = 'block';
        }
    }
}

/**
 * Hiển thị hộp thoại xác nhận đăng xuất
 */
function showLogoutConfirm() {
    const modal = document.getElementById('logout-confirm-modal');
    if (modal) {
        closeDashboard(); // Đảm bảo đóng dashboard nếu đang mở
        modal.style.display = 'flex';
    }
}

/**
 * Đóng hộp thoại xác nhận đăng xuất
 */
function closeLogoutConfirm() {
    const modal = document.getElementById('logout-confirm-modal');
    if (modal) {
        modal.style.display = 'none';
        openDashboard(); // Mở lại dashboard sau khi đóng confirm
    }   
    
}

/**
 * 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();
    if (document.getElementById('user-dropdown').classList.contains('show')) {
        toggleDropdown();
    }
    closeLogoutConfirm();
    closeDashboard();
    loadScenes(); // Reload scenes to filter out private ones
}

/**
 * Opens Modal for creating a Scene and sets lat/lng inputs
 */
function openCreateSceneModal(lat, lng) {
    returnToDashboardAfterEdit = false;
    const token = localStorage.getItem('jwt');
    if (!token) {
        showNotification('Please log in first to create a 3D scene.', 'error');
        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);

    const lang = systemSettings.language || 'vi';
    const modalTitle = document.getElementById('create-scene-modal-title');
    if (modalTitle) modalTitle.innerText = lang === 'vi' ? "Tạo 3D scene mới" : "Create New 3D Scene";
}

/**
 * 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';

    if (returnToDashboardAfterEdit) {
        const targetTab = dashboardReturnTab;
        returnToDashboardAfterEdit = false;
        openDashboard();
        openDashboardTab(targetTab);
    }
}

/**
 * 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', () => {
        showNotification(sceneId ? 'Scene đang được cập nhật ngầm!' : 'Scene đã được tạo! Ảnh đang được xử lý 8K...', 'success');
        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) {}
            showNotification('Lỗi: ' + errorMsg, 'error');
        }
    });

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

    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) => {
            // 1. Kiểm tra tọa độ an toàn - Ngăn chặn treo map do NaN
            const latNum = Number(scene.gps?.lat ?? scene.lat);
            const lngNum = Number(scene.gps?.lng ?? scene.lng);

            if (isNaN(latNum) || isNaN(lngNum)) {
                console.error(`Bỏ qua Scene "${scene.name || scene.title}" do tọa độ lỗi:`, scene);
                return;
            }

            // 2. Logic lọc Ảnh mẹ: Sửa lỗi typo coordKey (dùng latNum 2 lần)
            const coordKey = `${latNum.toFixed(6)},${lngNum.toFixed(6)}`;
            if (seenCoordinates.has(coordKey)) return;
            seenCoordinates.add(coordKey);

            // 3. Truy cập Asset an toàn
            const assetId = scene.assetId?._id || scene.assetId;
            if (!assetId) return; // Bỏ qua nếu không có ảnh liên kết

            const sceneName = scene.name || scene.title || "Untitled Scene";

            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 = formatSystemDate(scene.assetId?.createdAt);
            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 === 'admin' || userRole === 'Chủ sở hữu';
                const isOwner = currentUserId && ownerId && ownerId.toString() === currentUserId.toString();

                if (isAdmin || isOwner) {
                    handleEditDeleteScene(scene);
                } else if (scene.privacy === 'public') {
                    // Cho phép bất kỳ ai (kể cả khách) lấy link chia sẻ của scene công khai
                    showShareLink(scene);
                } else {
                    showNotification("Bạn không có quyền chỉnh sửa scene này.", 'warning');
                }
            });

            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 editPrivacyBtn = document.getElementById('btn-edit-privacy-action');
    const deleteBtn = document.getElementById('btn-delete-action');
    const shareBtn = document.getElementById('btn-share-action');

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

    // Hành động Lấy link chia sẻ trực tiếp
    shareBtn.onclick = () => {
        closeActionModal();
        showShareLink(scene);
    };

    // Hành động Chỉnh sửa privacy
    editPrivacyBtn.onclick = () => {
        returnToDashboardAfterEdit = false;
        closeActionModal();
        // Mở modal metadata, false vì ảnh trên map luôn là ảnh mẹ (không phải child)
        openEditMetadataModal(scene, false);
    };

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

    // Gán sự kiện cho nút Xóa
    deleteBtn.onclick = () => {
        returnToDashboardAfterEdit = false; // Đảm bảo không mở dashboard nếu xóa từ map
        closeActionModal();
        deleteScene(scene._id);
    };
}

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

/**
 * Mở modal xác nhận xóa scene
 */
window.deleteScene = function(sceneId) {
    sceneIdToDelete = sceneId;
    document.getElementById('delete-scene-confirm-modal').style.display = 'flex';
};

window.closeDeleteSceneModal = function() {
    document.getElementById('delete-scene-confirm-modal').style.display = 'none';
    sceneIdToDelete = null;

    if (returnToDashboardAfterEdit) {
        const targetTab = dashboardReturnTab;
        returnToDashboardAfterEdit = false;
        openDashboard();
        openDashboardTab(targetTab);
    }
};

window.confirmDeleteScene = async function() {
    if (!sceneIdToDelete) return;

    const token = localStorage.getItem('jwt');
    try {
        const response = await fetch(`${API_BASE_URL}/scenes/${sceneIdToDelete}`, {
            method: 'DELETE',
            headers: { 'Authorization': `Bearer ${token}` }
        });
        const data = await response.json();

        if (!response.ok) throw new Error(data.message || 'Failed to delete scene');
        
        closeDeleteSceneModal();
        showSuccessModal(data.message || 'Scene đã được xóa vĩnh viễn');
        
        loadScenes();
        if (document.getElementById('tab-my-scenes').classList.contains('active')) {
            loadMyScenes();
        }
    } catch (error) {
        showNotification("Lỗi khi xóa: " + error.message, 'error');
    }
};

/**
 * Fetches secure scene details and triggers the Panorama viewer
 */
async function openScene(sceneId, privacy, shareToken, force = false, initialPitch = 0, initialYaw = 0) {
    // 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();
        console.log("DEBUG: Hotspots raw data from API:", hotspots);

        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, initialPitch, initialYaw);

        // Sau khi mở thành công từ URL trực tiếp, xóa tham số để làm sạch thanh địa chỉ (URL chuyên nghiệp)
        const urlParams = new URLSearchParams(window.location.search);
        if (urlParams.has('sceneId')) {
            window.history.replaceState({}, document.title, "/");
        }

    } catch (error) {
        if (typeof closeViewer === 'function') closeViewer();

        localStorage.removeItem('activeSceneId');
        localStorage.removeItem('activeScenePrivacy');
        localStorage.removeItem('activeSceneToken');

        // Kiểm tra nếu đang truy cập qua link trực tiếp (URL có sceneId) mà gặp lỗi (do xóa token hoặc token không hợp lệ)
        const urlParams = new URLSearchParams(window.location.search);
        if (urlParams.has('sceneId')) {
            showNotification("Bạn không có quyền truy cập hoặc liên kết chia sẻ đã hết hạn. Quay về bản đồ công cộng.", 'error');
            // Xóa toàn bộ tham số URL và tải lại trang để làm mới trạng thái (về trang chủ dành cho khách)
            window.history.replaceState({}, document.title, "/");
            location.reload();
            return;
        }

        showNotification(error.message, 'error');
    }
}

/**
 * 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');
        const savedPitch = parseFloat(localStorage.getItem('activeScenePitch')) || 0;
        const savedYaw = parseFloat(localStorage.getItem('activeSceneYaw')) || 0;
        openScene(savedSceneId, savedPrivacy, savedToken, false, savedPitch, savedYaw);
    }
}

/**
 * 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) {
        showNotification('Vui lòng đăng nhập để thực hiện thao tác này.', 'warning');
        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) {
                showNotification('Vui lòng chọn ảnh panorama.', 'warning');
                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) {
                    showNotification('Vui lòng chọn vị trí GPS.', 'warning');
                    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) {
            showNotification('Vui lòng chọn cảnh để liên kết.', 'warning');
            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');

        showNotification('Lưu điểm điều hướng thành công!', 'success');
        // 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);
        showNotification(error.message, 'error');
    }
}

/**
 * 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
            showNotification(data.message, 'success');
            location.reload();
        } else {
            throw new Error(data.message);
        }
    } catch (e) {
        showNotification("Lỗi reset: " + e.message, 'error');
    }
};

/**
 * 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');
        }

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

/**
 * Toggles the visibility of the user dropdown menu.
 */
function toggleDropdown() {
    document.getElementById('user-dropdown').classList.toggle('show');
}

/**
 * Opens the user dashboard overlay.
 */
function openDashboard() {
    const username = localStorage.getItem('username');
    const role = localStorage.getItem('role');
    
    if (username) {
        document.getElementById('sidebar-avatar').innerText = username.charAt(0).toUpperCase();
        document.getElementById('sidebar-username').innerText = username;
        document.getElementById('sidebar-status').innerText = role || 'Thành viên';
    }

    document.getElementById('dashboard-overlay').style.display = 'flex';
    document.getElementById('user-dropdown').classList.remove('show'); // Close dropdown
    // Mở tab profile mặc định khi mở dashboard
    openDashboardTab('profile');
}

/**
 * Closes the user dashboard overlay.
 */
function closeDashboard() {
    document.getElementById('dashboard-overlay').style.display = 'none';
}

/**
 * Tải danh sách scene của chính người dùng đăng nhập
 */
async function loadMyScenes() {
    const token = localStorage.getItem('jwt');
    const listContainer = document.getElementById('my-scenes-list');
    // Chuyển sang grid để đồng bộ với media library
    listContainer.className = 'dashboard-grid'; 
    listContainer.innerHTML = '<p>Đang tải danh sách...</p>';

    try {
        const res = await fetch(`${API_BASE_URL}/me/scenes`, {
            headers: { 'Authorization': `Bearer ${token}` }
        });
        const scenes = await res.json();
        if (!res.ok) throw new Error(scenes.message);

        listContainer.innerHTML = '';
        if (scenes.length === 0) {
            listContainer.innerHTML = '<p>Bạn chưa tạo scene nào.</p>';
            return;
        }

        scenes.forEach(scene => {
            const assetId = scene.assetId?._id || scene.assetId;
            let thumbUrl = `${API_BASE_URL}/assets/view/${assetId}`;
            if (token) thumbUrl += `?token=${token}`;

            const card = document.createElement('div');
            card.className = 'scene-card';
            card.style.backgroundImage = `url('${thumbUrl}')`;

            // Logic hiển thị badge trạng thái
            let statusBadge = '';
            if (scene.status === 'processing') {
                statusBadge = '<span class="status-badge processing">⏳ Đang xử lý 8K...</span>';
            } else if (scene.status === 'failed') {
                statusBadge = '<span class="status-badge failed">❌ Lỗi xử lý</span>';
            }
            
            card.innerHTML = `
                <div class="scene-card-overlay">
                    <div class="scene-card-info">
                        <strong>${scene.name || scene.title}</strong>
                        <p class="scene-desc">${scene.description || 'Không có mô tả'}</p>
                        <div class="scene-card-meta">
                            <span>🔒 ${scene.privacy}</span>
                            <span>👤 ${scene.createdBy?.username || 'Bạn'}</span>
                            <span>📅 ${formatSystemDate(scene.createdAt)}</span>
                        </div>
                        ${statusBadge}
                    </div>
                    <div class="media-actions" style="border: none; padding: 0;">
                        <button class="edit-btn-small" id="edit-scene-${scene._id}" ${scene.status === 'processing' ? 'disabled style="opacity:0.5; cursor:not-allowed;"' : ''}>Sửa</button>
                        <button class="delete-btn-small" id="delete-scene-${scene._id}">Xóa</button>
                    </div>
                </div>
            `;
            listContainer.appendChild(card);

            // Xử lý nút Sửa: Logic đóng dashboard -> mở modal -> quay lại dashboard
            document.getElementById(`edit-scene-${scene._id}`).onclick = () => {
                dashboardReturnTab = 'my-scenes';
                returnToDashboardAfterEdit = true;
                closeDashboard();
                // Mặc định truyền false cho isChild, logic backend sẽ xử lý cascade privacy sau
                openEditMetadataModal(scene, false);
            };

            // Xử lý nút Xóa (Sẽ được hoàn thiện ở Bước 4)
            document.getElementById(`delete-scene-${scene._id}`).onclick = () => {
                dashboardReturnTab = 'my-scenes';
                returnToDashboardAfterEdit = true;
                closeDashboard();
                deleteScene(scene._id);
            };
        });
    } catch (e) {
        listContainer.innerHTML = `<p style="color:#ff4d4d">Lỗi: ${e.message}</p>`;
    }
}

/**
 * Tải danh sách người dùng dành cho Admin tối cao
 */
async function loadAdminUsers(page = 1) {
    const token = localStorage.getItem('jwt');
    const container = document.getElementById('admin-users-list');
    const paginationContainer = document.getElementById('admin-users-pagination');
    if (!container) return;

    container.innerHTML = '<p>Đang tải danh sách người dùng...</p>';
    if (paginationContainer) paginationContainer.innerHTML = '';

    try {
        const res = await fetch(`${API_BASE_URL}/admin/users?page=${page}&limit=10`, {
            headers: { 'Authorization': `Bearer ${token}` }
        });
        const data = await res.json();
        if (!res.ok) throw new Error(data.message);

        const { users, totalPages, currentPage, totalUsers } = data;

        let html = `
            <table class="admin-table">
                <thead>
                    <tr>
                        <th>Họ tên</th>
                        <th>Username</th>
                        <th>Email</th>
                        <th>Quyền hạn</th>
                        <th>Reset Password</th>
                        <th>Thao tác</th>
                    </tr>
                </thead>
                <tbody>
        `;

        users.forEach(user => {
            const isRootAdmin = user.role === 'admin';
            
            html += `
                <tr>
                    <td><input type="text" id="adm-fn-${user._id}" value="${user.fullName || ''}"></td>
                    <td><strong>${user.username}</strong></td>
                    <td><input type="email" id="adm-em-${user._id}" value="${user.email || ''}"></td>
                    <td>
                        <select id="adm-role-${user._id}" ${isRootAdmin ? 'disabled' : ''}>
                            <option value="user" ${user.role === 'user' ? 'selected' : ''}>User</option>
                            <option value="editor" ${user.role === 'editor' ? 'selected' : ''}>Editor</option>
                            <option value="moderator" ${user.role === 'moderator' ? 'selected' : ''}>Moderator</option>
                            <option value="admin" ${user.role === 'admin' ? 'selected' : ''}>Admin</option>
                        </select>
                    </td>
                    <td><input type="password" id="adm-pw-${user._id}" placeholder="${isRootAdmin ? 'N/A' : 'Mật khẩu mới'}" ${isRootAdmin ? 'disabled' : ''}></td>
                    <td>
                        <button class="edit-btn-small" onclick="updateUserByAdmin('${user._id}')">Lưu</button>
                        ${isRootAdmin ? '' : `<button class="delete-btn-small" onclick="deleteUserByAdmin('${user._id}')">Xóa</button>`}
                    </td>
                </tr>
            `;
        });

        html += '</tbody></table>';
        container.innerHTML = html;

        // Render Pagination UI
        if (paginationContainer && totalPages > 1) {
            paginationContainer.innerHTML = `
                <button class="pagination-btn" ${currentPage === 1 ? 'disabled' : ''} onclick="loadAdminUsers(${currentPage - 1})">Trang trước</button>
                <span class="pagination-info">Trang ${currentPage} / ${totalPages} (${totalUsers} người dùng)</span>
                <button class="pagination-btn" ${currentPage === totalPages ? 'disabled' : ''} onclick="loadAdminUsers(${currentPage + 1})">Trang sau</button>
            `;
        }
    } catch (e) {
        container.innerHTML = `<p style="color:red">Lỗi: ${e.message}</p>`;
    }
}

window.updateUserByAdmin = async function(userId) {
    const token = localStorage.getItem('jwt');
    const payload = {
        fullName: document.getElementById(`adm-fn-${userId}`).value,
        email: document.getElementById(`adm-em-${userId}`).value,
        role: document.getElementById(`adm-role-${userId}`).value,
        password: document.getElementById(`adm-pw-${userId}`).value
    };

    try {
        const res = await fetch(`${API_BASE_URL}/admin/users/${userId}`, {
            method: 'PUT',
            headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` },
            body: JSON.stringify(payload)
        });
        const data = await res.json();
        if (!res.ok) throw new Error(data.message);
        showNotification(data.message, 'success');
        loadAdminUsers();
    } catch (e) { showNotification(e.message, 'error'); }
};

window.deleteUserByAdmin = async function(userId) {
    if (!confirm('Xóa vĩnh viễn người dùng này?')) return;
    const token = localStorage.getItem('jwt');
    try {
        const res = await fetch(`${API_BASE_URL}/admin/users/${userId}`, {
            method: 'DELETE',
            headers: { 'Authorization': `Bearer ${token}` }
        });
        const data = await res.json();
        if (!res.ok) throw new Error(data.message);
        showNotification(data.message, 'success');
        loadAdminUsers();
    } catch (e) { showNotification(e.message, 'error'); }
};

/**
 * Tải và hiển thị kho ảnh/media của người dùng
 */
async function loadMyAssets() {
    const token = localStorage.getItem('jwt');
    const gridContainer = document.getElementById('media-library-list');
    const currentUserId = localStorage.getItem('userId');
    const userRole = localStorage.getItem('role');
    
    gridContainer.innerHTML = '<p>Đang tải kho ảnh...</p>';

    try {
        const res = await fetch(`${API_BASE_URL}/me/assets`, {
            headers: { 'Authorization': `Bearer ${token}` }
        });
        const assets = await res.json();
        if (!res.ok) throw new Error(assets.message);

        gridContainer.innerHTML = '';
        if (assets.length === 0) {
            gridContainer.innerHTML = '<p>Kho ảnh trống.</p>';
            return;
        }

        assets.forEach(asset => {
            const scene = asset.linkedScene;
            const isTrash = !scene;
            const parentNames = asset.parentScenes?.map(p => p.name || p.title).join(', ');
            
            const card = document.createElement('div');
            card.className = `media-card ${isTrash ? 'trash-item' : ''}`;
            
            let statusBadge = '';
            if (scene?.status === 'processing') {
                statusBadge = '<span class="status-badge processing" style="position:static; margin-top:5px; display:inline-block;">⏳ Đang nén 8K...</span>';
            } else if (scene?.status === 'failed') {
                statusBadge = '<span class="status-badge failed" style="position:static; margin-top:5px; display:inline-block;">❌ Lỗi</span>';
            }

            // Build inner HTML without the onclick for edit/delete buttons
            let innerHtml = `
                <div class="media-thumb">
                    <img src="${API_BASE_URL}/assets/view/${asset._id}?token=${token}" alt="Thumbnail">
                    ${isTrash ? '<span class="badge-trash">Ảnh rác</span>' : ''}
                </div>
                <div class="media-info">
                    <strong>${scene ? (scene.name || scene.title) : 'Chưa gắn Scene'}</strong>
                    <p class="desc">${scene?.description || 'Không có mô tả'}</p>
                    ${parentNames ? `<p class="parent-link">🔗 Liên kết từ: ${parentNames}</p>` : ''}
                    ${statusBadge}
                    <span class="date">Tải lên: ${formatSystemDate(asset.createdAt)}</span>
                </div>
                <div class="media-actions">
                </div>
            `;
            card.innerHTML = innerHtml;

            // Add edit button and its event listener separately
            if (scene && asset.uploadedBy === currentUserId) {
                const editButton = document.createElement('button');
                editButton.className = 'edit-btn-small';
                editButton.innerText = 'Sửa Scene';
                if (scene.status === 'processing') editButton.disabled = true;
                dashboardReturnTab = 'media-library';
                const isChild = asset.parentScenes && asset.parentScenes.length > 0;
                editButton.addEventListener('click', () => openEditFromMedia(scene, isChild)); 
                card.querySelector('.media-actions').appendChild(editButton);
            }

            // Add delete button and its event listener
            if (asset.uploadedBy === currentUserId || (isTrash && (userRole === 'admin' || userRole === 'Chủ sở hữu'))) {
                const deleteButton = document.createElement('button');
                deleteButton.className = 'delete-btn-small';
                deleteButton.innerText = 'Xóa';
                deleteButton.addEventListener('click', () => deleteAsset(asset._id));
                card.querySelector('.media-actions').appendChild(deleteButton);
            }

            gridContainer.appendChild(card);
        });
    } catch (e) {
        gridContainer.innerHTML = `<p style="color:#ff4d4d">Lỗi nạp media: ${e.message}</p>`;
    }
}

/**
 * Xóa ảnh khỏi kho media
 */
window.deleteAsset = function(assetId) {
    assetIdToDelete = assetId;
    document.getElementById('delete-asset-confirm-modal').style.display = 'flex';
};

window.closeDeleteAssetModal = function() {
    document.getElementById('delete-asset-confirm-modal').style.display = 'none';
    assetIdToDelete = null;
};

window.confirmDeleteAsset = async function() {
    if (!assetIdToDelete) return;
    
    const token = localStorage.getItem('jwt');
    try {
        const res = await fetch(`${API_BASE_URL}/assets/${assetIdToDelete}`, {
            method: 'DELETE',
            headers: { 'Authorization': `Bearer ${token}` }
        });
        
        let data;
        const contentType = res.headers.get("content-type");
        if (contentType && contentType.includes("application/json")) {
            data = await res.json();
        }

        if (!res.ok) {
            throw new Error(data?.message || `Lỗi máy chủ (${res.status})`);
        }

        closeDeleteAssetModal();
        showNotification(data.message || "Đã xóa thành công", 'success');
        loadMyAssets(); // Nạp lại kho ảnh
        loadScenes();   // Nạp lại bản đồ nếu có scene bị xóa kèm theo
    } catch (e) {
        showNotification("Lỗi khi xóa: " + e.message, 'error');
    }
};

/**
 * Hiển thị Modal thông báo thành công
 */
window.showSuccessModal = function(message, icon = '✓') {
    const modal = document.getElementById('success-modal');
    const msgElem = document.getElementById('success-modal-message');
    const iconElem = document.getElementById('success-modal-icon');
    if (modal && msgElem && iconElem) {
        msgElem.innerText = message;
        iconElem.innerText = icon;
        modal.style.display = 'flex';
        // Tự động ẩn sau 3 giây
        setTimeout(() => closeSuccessModal(), 3000);
    }
};

/**
 * Đóng Modal thành công (hỗ trợ click ra ngoài)
 */
window.closeSuccessModal = function(e) {
    const modal = document.getElementById('success-modal');
    if (!modal) return;
    // Nếu nhấn từ code (không có e) hoặc click trúng overlay thì đóng
    if (e && e.target !== modal) return;
    modal.style.display = 'none';
};

/**
 * Hiển thị Modal thông báo lỗi hoặc cảnh báo
 */
window.showErrorModal = function(message, title = "Thông báo", icon = '⚠️') {
    const modal = document.getElementById('error-modal');
    const msgElem = document.getElementById('error-modal-message');
    const titleElem = document.getElementById('error-modal-title');
    const iconElem = document.getElementById('error-modal-icon');
    if (modal && msgElem && iconElem) {
        msgElem.innerText = message;
        iconElem.innerText = icon;
        if (titleElem) titleElem.innerText = title;
        modal.style.display = 'flex';
    }
};

/**
 * Đóng Modal lỗi (hỗ trợ click ra ngoài)
 */
window.closeErrorModal = function(e) {
    const modal = document.getElementById('error-modal');
    if (!modal) return;
    // Nếu nhấn từ code (không có e) hoặc click trúng overlay thì đóng
    if (e && e.target !== modal) return;
    modal.style.display = 'none';
};

/**
 * Hàm thông báo dùng chung thay thế alert()
 */
window.showNotification = function(message, type = 'success') {
    if (type === 'success') {
        showSuccessModal(message, '✓');
    } else if (type === 'warning') {
        showErrorModal(message, 'Cảnh báo', '⚠️');
    } else {
        showErrorModal(message, 'Lỗi', '❌');
    }
};

window.openEditFromMedia = function(scene, isChild = false) {
    if (!scene || !scene._id) {
        showNotification("Không thể chỉnh sửa: Ảnh này không được gắn với một Scene hợp lệ.", 'error');
        return;
    }
    dashboardReturnTab = 'media-library';
    returnToDashboardAfterEdit = true;
    closeDashboard();
    openEditMetadataModal(scene, isChild);
};

/**
 * Mở Modal sửa thông tin Metadata chuyên biệt
 */
window.openEditMetadataModal = function(scene, isChild = false) {
    currentEditingScene = scene; // Lưu lại để dùng cho chia sẻ
    // Load dữ liệu chia sẻ hiện tại
    sharedUsersData = scene.sharedWith || [];
    sharedEmailsData = scene.sharedEmails || [];

    document.getElementById('edit-modal-scene-id').value = scene._id;
    document.getElementById('edit-modal-title').value = scene.name || scene.title || '';
    document.getElementById('edit-modal-description').value = scene.description || '';
    
    const lat = scene.gps?.lat || scene.lat;
    const lng = scene.gps?.lng || scene.lng;
    document.getElementById('edit-modal-lat').value = lat;
    document.getElementById('edit-modal-lng').value = lng;

    // Xử lý logic Privacy cho Cảnh con
    const privacySelect = document.getElementById('edit-modal-privacy');
    const childInfo = document.getElementById('edit-child-privacy-info');
    
    if (isChild) {
        privacySelect.value = scene.privacy;
        privacySelect.disabled = true;
        childInfo.style.display = 'block';
    } else {
        privacySelect.value = scene.privacy;
        privacySelect.disabled = false;
        childInfo.style.display = 'none';
    }
    
    handleEditPrivacyChange(); // Cập nhật hiển thị nút bánh răng

    document.getElementById('edit-scene-metadata-modal').style.display = 'flex';
    
    // Khởi tạo Mini Map tại vị trí hiện tại của Scene
    setTimeout(() => initEditSceneMiniMap(lat, lng), 100);
};

function closeEditMetadataModal() {
    document.getElementById('edit-scene-metadata-modal').style.display = 'none';
    if (returnToDashboardAfterEdit) {
        const targetTab = dashboardReturnTab;
        returnToDashboardAfterEdit = false;
        openDashboard();
        openDashboardTab(targetTab);
    }
}

function initEditSceneMiniMap(lat, lng) {
    if (editMiniMap) {
        editMiniMap.setView([lat, lng], 16);
        if (editMiniMapMarker) editMiniMapMarker.setLatLng([lat, lng]);
        editMiniMap.invalidateSize();
        return;
    }

    editMiniMap = L.map('edit-mini-map').setView([lat, lng], 16);
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(editMiniMap);

    editMiniMapMarker = L.marker([lat, lng], { draggable: true }).addTo(editMiniMap);
    
    editMiniMap.on('click', (e) => {
        const { lat, lng } = e.latlng;
        editMiniMapMarker.setLatLng([lat, lng]);
        document.getElementById('edit-modal-lat').value = lat.toFixed(6);
        document.getElementById('edit-modal-lng').value = lng.toFixed(6);
    });
}

/**
 * Xử lý khi thay đổi Dropdown Privacy trong Modal sửa
 */
window.handleEditPrivacyChange = function() {
    const privacy = document.getElementById('edit-modal-privacy').value;
    const settingsBtn = document.getElementById('btn-edit-privacy-settings');
    const isChild = document.getElementById('edit-modal-privacy').disabled;

    if (!isChild && (privacy === 'member' || privacy === 'shared' || privacy === 'public')) {
        settingsBtn.style.display = 'block';
    } else {
        settingsBtn.style.display = 'none';
    }
};

/**
 * Mở modal cài đặt chi tiết dựa trên loại Privacy
 */
window.openPrivacySettingsModal = function() {
    const privacy = document.getElementById('edit-modal-privacy').value;
    if (privacy === 'member') {
        renderSharedList();
        document.getElementById('share-member-modal').style.display = 'flex';
    } else if (privacy === 'shared' || privacy === 'public') {
        showShareLink(currentEditingScene);
    }
};

/**
 * Hiển thị modal lấy link chia sẻ (dùng cho cả khách và chủ sở hữu)
 * @param {Object} scene - Đối tượng Scene cần lấy link
 */
window.showShareLink = function(scene) {
    if (!scene) return;
    
    // Lưu lại scene đang tương tác để các logic phụ trợ hoạt động đồng bộ
    currentEditingScene = scene;

    // Trỏ link vào endpoint /api/share/ để hỗ trợ Open Graph (ảnh thumbnail Facebook/Zalo)
    const baseUrl = window.location.origin + '/api/share/';
    const token = scene.shareToken || '';
    document.getElementById('shared-link-input').value = `${baseUrl}${scene._id}${token ? '?token=' + token : ''}`;
    document.getElementById('share-link-modal').style.display = 'flex';
};

/**
 * Tìm kiếm người dùng để chia sẻ
 */
window.searchUsersToShare = async function(query) {
    const dropdown = document.getElementById('search-results-dropdown');
    if (!query || query.length < 2) {
        dropdown.style.display = 'none';
        return;
    }

    const token = localStorage.getItem('jwt');
    try {
        const res = await fetch(`${API_BASE_URL}/users/search?q=${encodeURIComponent(query)}`, {
            headers: { 'Authorization': `Bearer ${token}` }
        });
        const users = await res.json();
        
        dropdown.innerHTML = '';
        if (users.length > 0) {
            users.forEach(user => {
                const item = document.createElement('div');
                item.className = 'search-item';
                item.innerText = `${user.username} (${user.email})`;
                item.onclick = () => addMemberToShare(user);
                dropdown.appendChild(item);
            });
            dropdown.style.display = 'block';
        } else {
            // Nếu không tìm thấy user, cho phép thêm email thủ công
            if (query.includes('@')) {
                dropdown.innerHTML = `<div class="search-item" onclick="addEmailToShare('${query}')">Thêm email: ${query}</div>`;
                dropdown.style.display = 'block';
            } else {
                dropdown.style.display = 'none';
            }
        }
    } catch (e) { console.error(e); }
};

function addMemberToShare(user) {
    if (!sharedUsersData.some(u => (u._id || u) === user._id)) {
        sharedUsersData.push(user);
        renderSharedList();
    }
    document.getElementById('share-user-search').value = '';
    document.getElementById('search-results-dropdown').style.display = 'none';
}

window.addEmailToShare = function(email) {
    if (!sharedEmailsData.includes(email)) {
        sharedEmailsData.push(email);
        renderSharedList();
    }
    document.getElementById('share-user-search').value = '';
    document.getElementById('search-results-dropdown').style.display = 'none';
};

function renderSharedList() {
    const list = document.getElementById('current-shared-list');
    list.innerHTML = '';
    
    sharedUsersData.forEach(user => {
        const name = user.username || 'User';
        list.innerHTML += `<div class="share-list-item">👤 ${name} <span class="remove-share-btn" onclick="removeShared('user', '${user._id || user}')">&times;</span></div>`;
    });
    
    sharedEmailsData.forEach(email => {
        list.innerHTML += `<div class="share-list-item">📧 ${email} <span class="remove-share-btn" onclick="removeShared('email', '${email}')">&times;</span></div>`;
    });
}

window.removeShared = function(type, id) {
    if (type === 'user') sharedUsersData = sharedUsersData.filter(u => (u._id || u) !== id);
    else sharedEmailsData = sharedEmailsData.filter(e => e !== id);
    renderSharedList();
};

window.closeShareMemberModal = () => document.getElementById('share-member-modal').style.display = 'none';
window.closeShareLinkModal = () => document.getElementById('share-link-modal').style.display = 'none';

/**
 * Copy link chia sẻ và đóng modal
 */
window.copySharedLink = function() {
    const linkInput = document.getElementById('shared-link-input');
    linkInput.select();
    navigator.clipboard.writeText(linkInput.value).then(() => {
        showSuccessModal("Đã sao chép liên kết vào bộ nhớ!");
        closeShareLinkModal();
    });
};

async function submitEditScene(e) {
    e.preventDefault();
    const id = document.getElementById('edit-modal-scene-id').value;
    const token = localStorage.getItem('jwt');

    // Sử dụng FormData vì API Backend hiện tại đang dùng Multer
    const formData = new FormData();
    formData.append('title', document.getElementById('edit-modal-title').value);
    formData.append('description', document.getElementById('edit-modal-description').value);
    formData.append('lat', document.getElementById('edit-modal-lat').value);
    formData.append('lng', document.getElementById('edit-modal-lng').value);
    formData.append('privacy', document.getElementById('edit-modal-privacy').value);
    
    formData.append('shareExpireDays', document.getElementById('share-link-expire').value);
    // Đính kèm dữ liệu chia sẻ nâng cao
    formData.append('sharedWithUsers', JSON.stringify(sharedUsersData.map(u => u._id || u)));
    formData.append('sharedEmails', JSON.stringify(sharedEmailsData));

    try {
        const res = await fetch(`${API_BASE_URL}/scenes/${id}`, {
            method: 'PUT',
            headers: { 'Authorization': `Bearer ${token}` },
            body: formData
        });
        const data = await res.json();
        if (!res.ok) throw new Error(data.message);

        showNotification("Đã cập nhật thông tin cảnh thành công!", 'success');
        closeEditMetadataModal();
        loadScenes(); 
    } catch (err) {
        showNotification("Lỗi cập nhật: " + err.message, 'error');
    }
}

/**
 * Xử lý tải xuống bản sao lưu
 */
async function handleBackup() {
    const token = localStorage.getItem('jwt');
    try {
        showNotification("Đang chuẩn bị bản sao lưu...", "success");
        const response = await fetch(`${API_BASE_URL}/admin/backup`, {
            method: 'POST',
            headers: { 'Authorization': `Bearer ${token}` }
        });
        if (!response.ok) throw new Error("Lỗi khi tạo backup");
        const blob = await response.blob();
        const url = window.URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = `backup_3dtour_${new Date().toISOString().slice(0,10)}.zip`;
        document.body.appendChild(a);
        a.click();
        window.URL.revokeObjectURL(url);
        showNotification("Đã tải xuống bản sao lưu!", "success");
    } catch (e) { showNotification(e.message, "error"); }
}

/**
 * Xử lý khôi phục dữ liệu từ file zip
 */
async function handleRestore(input) {
    if (!input.files || !input.files[0]) return;
    if (!confirm("CẢNH BÁO: Khôi phục dữ liệu sẽ xóa sạch dữ liệu hiện tại và thay thế bằng dữ liệu từ bản sao lưu. Bạn có chắc chắn?")) {
        input.value = ''; return;
    }
    const token = localStorage.getItem('jwt');
    const formData = new FormData();
    formData.append('backupFile', input.files[0]);
    try {
        showNotification("Đang khôi phục... Vui lòng không đóng trình duyệt.", "success");
        const response = await fetch(`${API_BASE_URL}/admin/restore`, {
            method: 'POST',
            headers: { 'Authorization': `Bearer ${token}` },
            body: formData
        });
        const data = await response.json();
        if (!response.ok) throw new Error(data.message);
        showNotification("Khôi phục thành công! Hệ thống sẽ tải lại.", "success");
        setTimeout(() => location.reload(), 2000);
    } catch (e) {
        showNotification(e.message, "error");
        input.value = '';
    }
}

/**
 * Opens a specific tab within the dashboard.
 * @param {string} tabName - The ID of the tab pane to open (e.g., 'profile', 'my-scenes').
 */
function openDashboardTab(tabName) {
    // Ẩn tất cả các tab pane
    document.querySelectorAll('.dashboard-tab-pane').forEach(pane => {
        pane.classList.remove('active');
    });
    // Bỏ active khỏi tất cả các nút tab
    document.querySelectorAll('.dashboard-tabs .tab-btn').forEach(btn => {
        btn.classList.remove('active');
    });

    // Hiển thị tab pane được chọn
    const selectedPane = document.getElementById(`tab-${tabName}`);
    if (selectedPane) {
        selectedPane.classList.add('active');
        // Nếu là tab profile, cập nhật nội dung
        if (tabName === 'profile') {
            updateProfileTabContent();
        }
        if (tabName === 'my-scenes') {
            loadMyScenes();
        }
        if (tabName === 'media-library') {
            loadMediaStats();
            loadMyAssets();
        }
        if (tabName === 'user-management') {
            loadAdminUsers();
        }
    }

    // Đánh dấu nút tab được chọn là active
    const selectedTabButton = document.querySelector(`.dashboard-tabs .tab-btn[onclick="openDashboardTab('${tabName}')"]`);
    if (selectedTabButton) {
        selectedTabButton.classList.add('active');
    }

    // Cập nhật avatar initials khi mở dashboard
    const username = localStorage.getItem('username');
    if (username) {
        document.getElementById('avatar-initials').innerText = username.charAt(0).toUpperCase();
    }
}
