// assets/js/app.js

document.addEventListener('DOMContentLoaded', () => {
    // --- i18n ---
    window.i18n = {
        currentLang: localStorage.getItem('appLang') || 'en',
        translations: {},

        async loadLanguage(lang) {
            try {
                // Přidáno cache-busting, aby prohlížeč nenačítal staré soubory
                const res = await fetch(`assets/locales/${lang}.json?v=` + new Date().getTime());
                this.translations = await res.json();
                this.currentLang = lang;
                localStorage.setItem('appLang', lang);

                const langSwitch = document.getElementById('lang-switch');
                if (langSwitch) langSwitch.value = lang;

                this.translatePage();
            } catch (e) {
                console.error("Failed to load language", e);
            }
        },

        t(key) {
            // Priority 1: Exact string match (perfect for translating API messages directly)
            if (this.translations && this.translations[key] !== undefined) {
                return this.translations[key];
            }

            // Priority 2: Dot-notation object path mapping
            const keys = key.split('.');
            let value = this.translations;
            for (const k of keys) {
                if (value && value[k] !== undefined) {
                    value = value[k];
                } else {
                    return key; // Falback to key
                }
            }
            return value;
        },

        translatePage() {
            document.querySelectorAll('[data-i18n]').forEach(el => {
                const key = el.getAttribute('data-i18n');
                el.innerText = this.t(key);
            });
            document.querySelectorAll('[data-i18n-title]').forEach(el => {
                const key = el.getAttribute('data-i18n-title');
                el.setAttribute('title', this.t(key));
            });
            document.querySelectorAll('[data-i18n-placeholder]').forEach(el => {
                const key = el.getAttribute('data-i18n-placeholder');
                el.setAttribute('placeholder', this.t(key));
            });
        }
    };

    // --- State ---
    const appState = {
        user: null,
        boards: [],
        currentBoard: null,
        columns: [],
        tasks: []
    };

    // --- DOM Elements ---
    const ui = {
        viewAuth: document.getElementById('view-auth'),
        viewBoard: document.getElementById('view-board'),
        sidebar: document.getElementById('sidebar'),
        boardList: document.getElementById('board-list'),
        navUsername: document.getElementById('nav-username'),
        navAvatar: document.getElementById('nav-avatar'),
        btnNavAdmin: document.getElementById('btn-nav-admin'),
        adminNavSection: document.getElementById('admin-nav-section'),
        viewAdmin: document.getElementById('view-admin'),
        toastContainer: document.getElementById('toast-container'),
        boardCanvas: document.getElementById('board-canvas'),
        currentBoardTitle: document.getElementById('current-board-title'),
        currentBoardRole: document.getElementById('current-board-role'),
        wrapperAddColumn: document.getElementById('wrapper-add-column'),

        // Buttons
        btnLogout: document.getElementById('btn-logout'),
        toggleSidebar: document.getElementById('toggle-sidebar'), // Desktop
        btnMobileSidebar: document.getElementById('btn-mobile-sidebar'), // Mobile
        btnNewBoard: document.getElementById('btn-new-board'),
        btnAddColumn: document.getElementById('btn-add-column'),
        btnTeam: document.getElementById('btn-team'),
        btnSettings: document.getElementById('btn-settings'),
        btnBoardChat: document.getElementById('btn-board-chat'),
        btnBoardChatBadge: document.getElementById('board-chat-badge'),
        boardChatSidebar: document.getElementById('board-chat-sidebar'),
        btnCloseBoardChat: document.getElementById('btn-close-board-chat'),
        boardChatHistory: document.getElementById('board-chat-history'),
        formBoardChat: document.getElementById('form-board-chat'),
        boardChatContentInput: document.querySelector('#form-board-chat input[name="content"]'),

        // Modals
        modalOverlay: document.getElementById('modal-overlay'),
        modalNewBoard: document.getElementById('modal-new-board'),
        modalTask: document.getElementById('modal-task'),
        modalTeam: document.getElementById('modal-team'),
        modalSettings: document.getElementById('modal-settings'),
        modalProfile: document.getElementById('modal-profile'),
        btnProfile: document.getElementById('nav-avatar'),
        btnDeleteTask: document.getElementById('btn-delete-task'),
        btnDeleteBoard: document.getElementById('btn-delete-board'),
        btnInbox: document.getElementById('btn-nav-inbox'),
        inboxBadge: document.getElementById('inbox-badge'),
        closeBtns: document.querySelectorAll('.close-modal, .close-modal-btn'),

        // Forms
        formLogin: document.getElementById('form-login'),
        formRegister: document.getElementById('form-register'),
        formCreateBoard: document.getElementById('form-create-board'),
        formTask: document.getElementById('form-task'),
        formTaskComment: document.getElementById('form-task-comment'),
        formAddMember: document.getElementById('form-add-member'),
        formSettings: document.getElementById('form-settings'),
        formProfile: document.getElementById('form-profile'),
        btnUpdatePassword: document.getElementById('btn-update-password'),
        btnProfileOk: document.getElementById('btn-profile-ok'),
        taskCommentsSection: document.getElementById('task-comments-section'),
        taskCommentsList: document.getElementById('task-comments-list'),
        modalInbox: document.getElementById('modal-inbox'),
        inboxContactsList: document.getElementById('inbox-contacts-list'),
        inboxChatHeader: document.getElementById('inbox-chat-header'),
        inboxChatHistory: document.getElementById('inbox-chat-history'),
        formInboxSend: document.getElementById('form-inbox-send'),
        inboxReceiverId: document.getElementById('inbox-receiver-id'),
        inboxContentInput: document.querySelector('#form-inbox-send input[name="content"]'),
        inboxBtnSend: document.getElementById('inbox-btn-send'),
        authTabs: document.querySelectorAll('.auth-tab'),
        modalAdminUser: document.getElementById('modal-admin-user'),
        formAdminUsername: document.getElementById('form-admin-username'),
        formAdminPassword: document.getElementById('form-admin-password'),

        // Password Reset
        forgotPwdContainer: document.getElementById('forgot-pwd-container'),
        linkForgotPwd: document.getElementById('link-forgot-pwd'),
        modalForgotPwd: document.getElementById('modal-forgot-password'),
        formForgotPwd: document.getElementById('form-forgot-password'),
        modalResetPwd: document.getElementById('modal-reset-password'),
        formResetPwd: document.getElementById('form-reset-password'),
        resetPwdTokenInput: document.getElementById('reset-pwd-token-input'),

        // Mobile bottom nav
        btnMobileNavProfile: document.getElementById('btn-mobile-nav-profile'),
        mobileNavAvatar: document.getElementById('mobile-nav-avatar'),
        btnMobileNavInbox: document.getElementById('btn-mobile-nav-inbox'),
        btnMobileNavAdmin: document.getElementById('btn-mobile-nav-admin'),
        adminPendingBadge: document.getElementById('admin-pending-badge'),
        mobileAdminPendingBadge: document.getElementById('mobile-admin-pending-badge'),
        btnMobileNavLogout: document.getElementById('btn-mobile-nav-logout'),
        mobileInboxBadge: document.getElementById('mobile-inbox-badge'),
        formAdminTransfer: document.getElementById('form-admin-transfer'),
        btnAdminToggleActive: document.getElementById('btn-admin-toggle-active'),
        btnAdminDeleteUser: document.getElementById('btn-admin-delete-user'),
        adminUsersList: document.getElementById('admin-users-list'),
        btnAdminBack: document.getElementById('btn-admin-back'),
        modalAdminDeleteConfirm: document.getElementById('modal-admin-delete-confirm'),
        formAdminDeleteConfirm: document.getElementById('form-admin-delete-confirm'),
        adminDeleteTransferOwner: document.getElementById('admin-delete-transfer-owner'),
        adminDeleteConfirmUsernameDisplay: document.getElementById('admin-delete-confirm-username-display'),
        adminDeleteConfirmInput: document.getElementById('admin-delete-confirm-input')
    };

    const langSwitch = document.getElementById('lang-switch');
    if (langSwitch) {
        langSwitch.addEventListener('change', async (e) => {
            await window.i18n.loadLanguage(e.target.value);
        });
    }

    const themeSwitch = document.getElementById('theme-switch');
    if (themeSwitch) {
        // Init theme on load
        const savedTheme = localStorage.getItem('kanban_theme') || 'dark';
        document.documentElement.setAttribute('data-theme', savedTheme);
        themeSwitch.value = savedTheme;

        themeSwitch.addEventListener('change', (e) => {
            const newTheme = e.target.value;
            document.documentElement.setAttribute('data-theme', newTheme);
            localStorage.setItem('kanban_theme', newTheme);
        });
    }

    let draggedTask = null;
    let draggedColumn = null;
    let draggedBoardInfo = null;
    let selectedAdminUser = null; // Store user ID being edited in admin

    // --- Utilities ---
    function showToast(message, type = 'success') {
        const toast = document.createElement('div');
        toast.className = `toast toast-${type}`;
        toast.innerHTML = `<i class="fa-solid fa-${type === 'success' ? 'check-circle' : 'exclamation-triangle'}"></i> ${message}`;
        ui.toastContainer.appendChild(toast);
        setTimeout(() => toast.remove(), 3000);
    }

    function switchView(viewId) {
        document.querySelectorAll('.view').forEach(v => v.classList.add('hidden'));
        document.querySelectorAll('.view').forEach(v => v.classList.remove('active'));

        const targetView = document.getElementById(viewId);
        if (targetView) {
            targetView.classList.remove('hidden');
            targetView.classList.add('active');
        }

        // Handle specific view side-effects
        if (viewId === 'view-auth') {
            ui.sidebar.classList.add('hidden');
            document.querySelector('.user-profile').classList.add('hidden');
        } else {
            ui.sidebar.classList.remove('hidden');
            document.querySelector('.user-profile').classList.remove('hidden');
        }

        if (viewId === 'view-admin') {
            if (ui.btnNavAdmin) ui.btnNavAdmin.classList.add('active');
            loadAdminUsers();
        } else {
            if (ui.btnNavAdmin) ui.btnNavAdmin.classList.remove('active');
        }
    }

    function openModal(modalEl) {
        ui.modalOverlay.classList.remove('hidden');
        document.querySelectorAll('.modal').forEach(m => m.classList.add('hidden'));
        modalEl.classList.remove('hidden');
    }

    function closeModal() {
        ui.modalOverlay.classList.add('hidden');
        document.querySelectorAll('.modal').forEach(m => m.classList.add('hidden'));
    }

    // Global Keydown Handler for Escape
    document.addEventListener('keydown', (e) => {
        if (e.key === 'Escape') {
            // Close Modals
            if (!ui.modalOverlay.classList.contains('hidden')) {
                closeModal();
            }
            // Close Board Chat
            if (ui.boardChatSidebar && !ui.boardChatSidebar.classList.contains('hidden')) {
                ui.btnCloseBoardChat.click(); // Triggers the proper teardown including interval clearing
            }
        }
    });

    function getInitials(name) {
        return name ? name.substring(0, 1).toUpperCase() : 'U';
    }

    // --- Authentication ---
    async function initApp() {
        // Check for Password Reset token in URL first
        const urlParams = new URLSearchParams(window.location.search);
        const resetToken = urlParams.get('reset_token');
        if (resetToken) {
            document.getElementById('mobile-bottom-nav').classList.add('hidden');
            switchView('view-auth');
            if (ui.resetPwdTokenInput) {
                ui.resetPwdTokenInput.value = resetToken;
                openModal(ui.modalResetPwd);
            }
            // Clear token from URL to prevent refiring on reload
            window.history.replaceState({}, document.title, window.location.pathname);
            return; // Skip normal auth flow until reset is done
        }

        try {
            const res = await api.checkSession();
            if (res.user) {
                appState.user = res.user;
                ui.navUsername.textContent = res.user.username;
                ui.navAvatar.textContent = getInitials(res.user.username);
                if (ui.mobileNavAvatar) {
                    ui.mobileNavAvatar.textContent = getInitials(res.user.username);
                }

                if (appState.user.role === 'admin') {
                    ui.adminNavSection.classList.remove('hidden');
                    if (ui.btnMobileNavAdmin) ui.btnMobileNavAdmin.classList.remove('hidden');
                } else {
                    ui.adminNavSection.classList.add('hidden');
                    if (ui.btnMobileNavAdmin) ui.btnMobileNavAdmin.classList.add('hidden');
                }

                document.getElementById('mobile-bottom-nav').classList.remove('hidden');
                switchView('view-board');
                loadBoards();
                updateUnreadMessagesCount();
                updateAdminPendingBadge();
            } else {
                document.getElementById('mobile-bottom-nav').classList.add('hidden');
                switchView('view-auth');
            }
        } catch (e) {
            document.getElementById('mobile-bottom-nav').classList.add('hidden');
            switchView('view-auth');
        }
    }

    // Auth Tabs
    ui.authTabs.forEach(tab => {
        tab.addEventListener('click', (e) => {
            ui.authTabs.forEach(t => t.classList.remove('active'));
            document.querySelectorAll('.auth-form').forEach(f => f.classList.remove('active'));
            e.target.classList.add('active');
            document.getElementById(e.target.dataset.target).classList.add('active');
        });
    });

    // Android App Bridge
    if (window.KanbanAndroid) {
        const resetServerBtn = document.createElement('button');
        resetServerBtn.type = 'button';
        resetServerBtn.className = 'btn btn-secondary';
        resetServerBtn.style.marginTop = '1rem';
        resetServerBtn.style.width = '100%';
        resetServerBtn.innerHTML = '<i class="fa-solid fa-server"></i> Změnit připojený server';
        resetServerBtn.addEventListener('click', () => { window.KanbanAndroid.clearServer(); });
        ui.formLogin.appendChild(resetServerBtn);
    }

    if (window.ENABLE_PASSWORD_RESET && ui.forgotPwdContainer) {
        ui.forgotPwdContainer.style.display = 'block';
    }

    if (ui.linkForgotPwd) {
        ui.linkForgotPwd.addEventListener('click', (e) => {
            e.preventDefault();
            if (ui.formForgotPwd) ui.formForgotPwd.reset();
            openModal(ui.modalForgotPwd);
        });
    }

    if (ui.formForgotPwd) {
        ui.formForgotPwd.addEventListener('submit', async (e) => {
            e.preventDefault();
            const data = Object.fromEntries(new FormData(e.target));
            const btn = ui.formForgotPwd.querySelector('button[type="submit"]');
            const originalText = btn.innerHTML;
            btn.innerHTML = '<i class="fa-solid fa-spinner fa-spin"></i>';
            btn.disabled = true;

            try {
                const res = await api.forgotPassword(data.username);
                showToast(res.message);
                closeModal();
            } catch (err) {
                showToast(err.message, 'error');
            } finally {
                btn.innerHTML = originalText;
                btn.disabled = false;
            }
        });
    }

    if (ui.formResetPwd) {
        ui.formResetPwd.addEventListener('submit', async (e) => {
            e.preventDefault();
            const data = Object.fromEntries(new FormData(e.target));
            if (data.password !== data.confirm_password) {
                showToast(window.i18n ? window.i18n.t('alerts.pwd_mismatch') : 'Passwords do not match.', 'error');
                return;
            }

            const btn = ui.formResetPwd.querySelector('button[type="submit"]');
            const originalText = btn.innerHTML;
            btn.innerHTML = '<i class="fa-solid fa-spinner fa-spin"></i>';
            btn.disabled = true;

            try {
                const res = await api.resetPassword(data.token, data.password);
                showToast(res.message);
                closeModal();
                initApp();
            } catch (err) {
                showToast(err.message, 'error');
            } finally {
                btn.innerHTML = originalText;
                btn.disabled = false;
            }
        });
    }

    ui.formLogin.addEventListener('submit', async (e) => {
        e.preventDefault();
        try {
            const { username, password } = Object.fromEntries(new FormData(e.target));
            await api.login(username, password);
            showToast(window.i18n ? window.i18n.t('alerts.login_success') : 'Logged in successfully!');
            initApp();
        } catch (err) {
            showToast(err.message, 'error');
        }
    });

    ui.formRegister.addEventListener('submit', async (e) => {
        e.preventDefault();
        try {
            const { username, email, password } = Object.fromEntries(new FormData(e.target));
            const res = await api.register(username, email, password);
            if (res && res.pending_approval) {
                showToast(window.i18n ? window.i18n.t('alerts.register_pending') : (res.message || 'Account created! Waiting for administrator approval.'));
                ui.formRegister.reset();
                ui.authTabs[0].click(); // Switch to login tab
            } else {
                showToast(window.i18n ? window.i18n.t('alerts.register_success') : 'Account created successfully!');
                initApp();
            }
        } catch (err) {
            showToast(err.message, 'error');
        }
    });

    async function performLogout() {
        try {
            await api.logout();
            window.location.reload();
        } catch (e) {
            showToast(window.i18n ? window.i18n.t('alerts.logout_failed') : 'Failed to logout', 'error');
        }
    }

    ui.btnLogout.addEventListener('click', performLogout);
    if (ui.btnMobileNavLogout) ui.btnMobileNavLogout.addEventListener('click', performLogout);

    ui.formProfile.addEventListener('submit', async (e) => {
        e.preventDefault();
        // The password change logic is now handled by btnUpdatePassword.
        // This submit listener will primarily handle closing the modal if no password fields are touched.
        const oldPassword = e.target.old_password.value;
        const newPassword = e.target.new_password.value;
        const confirmPassword = e.target.confirm_password.value;

        if (!oldPassword && !newPassword && !confirmPassword) {
            // If no password fields are filled, just close the modal.
            // Other profile settings (like language) are saved on-the-fly or via other buttons.
            closeModal();
        }
    });

    if (ui.btnUpdatePassword) {
        ui.btnUpdatePassword.addEventListener('click', async () => {
            const oldPassword = ui.formProfile.old_password.value;
            const newPassword = ui.formProfile.new_password.value;
            const confirmPassword = ui.formProfile.confirm_password.value;

            if (!oldPassword || !newPassword || !confirmPassword) {
                showToast(window.i18n ? window.i18n.t('alerts.fill_fields') : 'Please fill in all password fields.', 'error');
                return;
            }

            if (newPassword !== confirmPassword) {
                showToast(window.i18n ? window.i18n.t('alerts.pw_mismatch') : 'Passwords do not match.', 'error');
                return;
            }
            try {
                await api.changePassword(oldPassword, newPassword);
                showToast(window.i18n && window.i18n.t ? window.i18n.t('alerts.password_updated') : 'Password updated successfully!');
                ui.formProfile.old_password.value = '';
                ui.formProfile.new_password.value = '';
                ui.formProfile.confirm_password.value = '';
                closeModal();
            } catch (err) {
                showToast(err.message, 'error');
            }
        });
    }

    if (ui.btnProfileOk) {
        ui.btnProfileOk.addEventListener('click', () => {
            closeModal();
        });
    }

    // --- Boards ---
    async function loadBoards() {
        try {
            const data = await api.getBoards();
            appState.boards = data.boards;
            renderBoardList();
        } catch (e) {
            showToast(window.i18n ? window.i18n.t('alerts.load_boards_fail') : 'Failed to load boards.', 'error');
        }
    }

    function renderBoardList() {
        ui.boardList.innerHTML = '';
        if (appState.boards.length === 0) {
            ui.boardList.innerHTML = '<li class="text-muted"><small>No boards found.</small></li>';
        }

        appState.boards.forEach((b, index) => {
            const li = document.createElement('li');
            li.dataset.id = b.id;

            // Generate Inner HTML depending on active state
            const isActive = appState.currentBoard && appState.currentBoard.id === b.id;
            if (isActive) li.classList.add('active');

            li.innerHTML = `
                <div style="display: flex; align-items: center; justify-content: space-between; width: 100%;">
                    <div><i class="fa-solid fa-chalkboard"></i> ${b.title}</div>
                    <div class="board-arrows" style="display: flex; gap: 4px; opacity: 0; pointer-events: none; transition: opacity 0.2s;">
                        <button class="icon-btn small arrow-btn btn-move-board" data-dir="up" data-i18n-title="alerts.btn_move_up" title="${window.i18n ? window.i18n.t('alerts.btn_move_up') : 'Move Up'}"><i class="fa-solid fa-arrow-up"></i></button>
                        <button class="icon-btn small arrow-btn btn-move-board" data-dir="down" data-i18n-title="alerts.btn_move_down" title="${window.i18n ? window.i18n.t('alerts.btn_move_down') : 'Move Down'}"><i class="fa-solid fa-arrow-down"></i></button>
                    </div>
                </div>
            `;

            // Select on click
            li.addEventListener('click', (e) => {
                // Don't select if clicking an arrow button
                if (e.target.closest('.btn-move-board')) return;
                selectBoard(b);
            });

            // Show arrows on hover via JS (or simple css class via JS)
            li.addEventListener('mouseenter', () => {
                const arrows = li.querySelector('.board-arrows');
                if (arrows) {
                    arrows.style.opacity = '1';
                    arrows.style.pointerEvents = 'auto';
                }
            });
            li.addEventListener('mouseleave', () => {
                const arrows = li.querySelector('.board-arrows');
                if (arrows) {
                    arrows.style.opacity = '0';
                    arrows.style.pointerEvents = 'none';
                }
            });

            // Handle manual arrows
            li.querySelectorAll('.btn-move-board').forEach(btn => {
                btn.addEventListener('click', (e) => {
                    e.stopPropagation();
                    moveBoardManual(b, e.currentTarget.dataset.dir, index);
                });
            });

            // Drag and Drop
            li.draggable = true;
            li.addEventListener('dragstart', (e) => {
                e.dataTransfer.effectAllowed = 'move';
                draggedBoardInfo = { id: b.id, index: index, element: li };
                setTimeout(() => li.style.opacity = '0.5', 0);
            });
            li.addEventListener('dragend', () => {
                li.style.opacity = '1';
                draggedBoardInfo = null;
            });
            li.addEventListener('dragover', (e) => {
                e.preventDefault();
                e.dataTransfer.dropEffect = 'move';
            });
            li.addEventListener('drop', (e) => {
                e.preventDefault();
                if (!draggedBoardInfo || draggedBoardInfo.id === b.id) return;
                handleBoardReorderDrop(index);
            });

            ui.boardList.appendChild(li);
        });

        // Auto select first board if none selected
        if (!appState.currentBoard && appState.boards.length > 0) {
            selectBoard(appState.boards[0]);
        } else if (appState.boards.length === 0) {
            ui.currentBoardTitle.innerHTML = `<span data-i18n="create_new_board">${window.i18n ? window.i18n.t('create_new_board') : 'Create a new Board'}</span> <button onclick="document.getElementById('btn-new-board').click()" class="btn btn-primary btn-sm" style="margin-left: 10px;" title="${window.i18n ? window.i18n.t('btn_create_board') : 'Create Board'}"><i class="fa-solid fa-plus"></i></button>`;
        }
    }

    async function moveBoardManual(board, dir, currentIndex) {
        if (dir === 'up' && currentIndex === 0) return;
        if (dir === 'down' && currentIndex === appState.boards.length - 1) return;

        const newIndex = dir === 'up' ? currentIndex - 1 : currentIndex + 1;

        // Swap locally
        const temp = appState.boards[currentIndex];
        appState.boards[currentIndex] = appState.boards[newIndex];
        appState.boards[newIndex] = temp;

        // Re-render immediately
        renderBoardList();

        // Save to DB
        try {
            await api.moveBoard(board.id, newIndex);
        } catch (e) {
            showToast(window.i18n ? window.i18n.t('alerts.save_position_fail') : 'Failed to save board position.', 'error');
            loadBoards(); // Revert on error
        }
    }

    async function handleBoardReorderDrop(targetIndex) {
        if (!draggedBoardInfo) return;

        const boardId = draggedBoardInfo.id;
        const sourceIndex = draggedBoardInfo.index;

        if (sourceIndex === targetIndex) return;

        // Reorder locally
        const [movedBoard] = appState.boards.splice(sourceIndex, 1);
        appState.boards.splice(targetIndex, 0, movedBoard);

        renderBoardList();

        try {
            await api.moveBoard(boardId, targetIndex);
        } catch (e) {
            showToast(window.i18n ? window.i18n.t('alerts.save_position_fail') : 'Failed to save board position.', 'error');
            loadBoards(); // Revert on error
        }
    }

    async function selectBoard(board) {
        switchView('view-board');
        appState.currentBoard = board;
        // ui.currentBoardTitle.textContent = board.title;
        ui.currentBoardTitle.innerHTML = `${board.title} ${(board.role === 'owner' || board.role === 'editor') ? `<button id="btn-edit-board" class="icon-btn small" title="${window.i18n ? window.i18n.t('alerts.btn_rename_board') : 'Rename Board'}" style="margin-left:8px;font-size:1rem;"><i class="fa-solid fa-pen"></i></button>` : ''}`;

        const btnEditBoard = document.getElementById('btn-edit-board');
        if (btnEditBoard) {
            btnEditBoard.addEventListener('click', async () => {
                const newTitle = prompt(window.i18n ? window.i18n.t('alerts.prompt_rename_board') : 'Rename board:', board.title);
                if (newTitle && newTitle.trim() !== '' && newTitle !== board.title) {
                    try {
                        await api.updateBoard(board.id, newTitle, board.description);
                        board.title = newTitle;
                        selectBoard(board); // Re-render title and list
                        showToast(window.i18n ? window.i18n.t('alerts.board_renamed_toast') : 'Board renamed');
                    } catch (err) { showToast(err.message, 'error'); }
                }
            });
        }

        ui.currentBoardRole.textContent = board.role.toUpperCase();
        ui.currentBoardRole.classList.remove('hidden');
        ui.btnBoardChat.classList.remove('hidden');

        if (board.role === 'owner') {
            ui.btnTeam.classList.remove('hidden');
            ui.btnSettings.classList.remove('hidden');
        } else {
            ui.btnTeam.classList.add('hidden');
            ui.btnSettings.classList.add('hidden');
        }

        renderBoardList(); // update active class
        await loadBoardData(board.id);

        // Refresh unread count immediately upon opening a new board
        updateBoardChatUnreadCount();
    }

    ui.btnNewBoard.addEventListener('click', () => openModal(ui.modalNewBoard));

    ui.formCreateBoard.addEventListener('submit', async (e) => {
        e.preventDefault();
        try {
            const data = Object.fromEntries(new FormData(e.target));

            // Translate default column titles before sending to backend
            const defaultColumns = [
                window.i18n ? window.i18n.t('col_todo') : 'To Do',
                window.i18n ? window.i18n.t('col_in_progress') : 'In Progress',
                window.i18n ? window.i18n.t('col_done') : 'Done'
            ];

            const res = await api.createBoard(data.title, data.description, defaultColumns);
            showToast(window.i18n ? window.i18n.t('alerts.board_created') : 'Board created!');
            closeModal();
            ui.formCreateBoard.reset();
            appState.boards.unshift(res.board);
            selectBoard(res.board);
        } catch (err) {
            showToast(err.message, 'error');
        }
    });

    // --- Columns & Tasks ---
    async function loadBoardData(boardId) {
        ui.boardCanvas.querySelectorAll('.column').forEach(c => c.remove());
        ui.wrapperAddColumn.classList.add('hidden');

        try {
            const [colsData, tasksData] = await Promise.all([
                api.getColumns(boardId),
                api.getTasks(boardId)
            ]);

            appState.columns = colsData.columns;
            appState.tasks = tasksData.tasks;

            appState.columns.forEach(col => renderColumn(col));

            // Re-append wrapper to end
            ui.boardCanvas.appendChild(ui.wrapperAddColumn);
            if (appState.currentBoard.role !== 'viewer') {
                ui.wrapperAddColumn.classList.remove('hidden');
            }
        } catch (e) {
            showToast(window.i18n ? window.i18n.t('alerts.load_data_fail') : 'Failed to load board data', 'error');
        }
    }

    function renderColumn(col) {
        const colEl = document.createElement('div');
        colEl.className = 'column';
        colEl.dataset.id = col.id;

        colEl.innerHTML = `
            <div class="column-header">
                <span class="column-title">${col.title}</span>
                <div class="column-actions">
                    ${appState.currentBoard.role !== 'viewer' ? `
                    <button class="icon-btn small text-muted btn-edit-col" data-i18n-title="alerts.btn_rename_col" title="${window.i18n ? window.i18n.t('alerts.btn_rename_col') : 'Rename Column'}"><i class="fa-solid fa-pen"></i></button>
                    ${(appState.currentBoard.role === 'owner' || appState.currentBoard.role === 'editor') ? `
                    <button class="icon-btn small text-muted btn-move-col-left" data-i18n-title="alerts.btn_move_left" title="${window.i18n ? window.i18n.t('alerts.btn_move_left') : 'Move Left'}"><i class="fa-solid fa-arrow-left"></i></button>
                    <button class="icon-btn small text-muted btn-move-col-right" data-i18n-title="alerts.btn_move_right" title="${window.i18n ? window.i18n.t('alerts.btn_move_right') : 'Move Right'}"><i class="fa-solid fa-arrow-right"></i></button>
                    <button class="icon-btn small text-muted btn-delete-col" data-i18n-title="alerts.btn_delete_col" title="${window.i18n ? window.i18n.t('alerts.btn_delete_col') : 'Delete Column'}"><i class="fa-solid fa-trash"></i></button>
                    ` : ''}
                    ` : ''}
                </div>
            </div>
            <div class="column-body" data-col-id="${col.id}">
                <!-- Tasks will be injected here -->
            </div>
            ${appState.currentBoard.role !== 'viewer' ?
                `<button class="add-task-btn"><i class="fa-solid fa-plus"></i> <span data-i18n="btn_add_card">${window.i18n ? window.i18n.t('btn_add_card') || 'Add a card...' : 'Add a card...'}</span></button>` : ''}
        `;

        if (appState.currentBoard.role !== 'viewer') {
            colEl.querySelector('.add-task-btn').addEventListener('click', () => {
                ui.formTask.reset();
                document.getElementById('task-id-input').value = '';
                document.getElementById('task-column-id-input').value = col.id;
                document.getElementById('task-title-input').value = '';
                document.getElementById('task-desc-input').value = '';
                document.getElementById('task-assign-id-input').value = '';
                document.getElementById('task-assign-search-input').value = '';
                document.getElementById('task-due-date').value = '';
                document.getElementById('modal-task-title').textContent = window.i18n ? window.i18n.t('btn_create_task') : 'Add Task';
                ui.btnDeleteTask.classList.add('hidden');
                ui.taskCommentsSection.classList.add('hidden');
                openModal(ui.modalTask);
            });

            colEl.querySelector('.btn-delete-col').addEventListener('click', async () => {
                if (confirm(window.i18n ? window.i18n.t('alerts.confirm_delete_col') : 'Are you sure you want to delete this column and all its tasks?')) {
                    try {
                        await api.deleteColumn(col.id);
                        showToast(window.i18n ? window.i18n.t('alerts.col_deleted') : 'Column deleted');
                        loadBoardData(appState.currentBoard.id);
                    } catch (e) { showToast(e.message, 'error'); }
                }
            });

            colEl.querySelector('.btn-edit-col').addEventListener('click', async () => {
                const newTitle = prompt(window.i18n ? window.i18n.t('alerts.prompt_enter_column') : 'Rename column:', col.title);
                if (newTitle && newTitle.trim() !== '' && newTitle !== col.title) {
                    try {
                        await api.updateColumn(col.id, newTitle);
                        col.title = newTitle;
                        colEl.querySelector('.column-title').textContent = newTitle;
                        showToast(window.i18n ? window.i18n.t('alerts.col_renamed') || 'Column renamed' : 'Column renamed');
                    } catch (err) { showToast(err.message, 'error'); }
                }
            });

            colEl.querySelector('.btn-move-col-left').addEventListener('click', () => moveColumn(col.id, -1));
            colEl.querySelector('.btn-move-col-right').addEventListener('click', () => moveColumn(col.id, 1));

            // Setup Column Drag & Drop
            colEl.draggable = true;
            colEl.addEventListener('dragstart', (e) => {
                if (!e.target.classList.contains('column')) return; // ignore task drag
                draggedColumn = colEl;
                setTimeout(() => colEl.classList.add('is-dragging-column'), 0);
            });
            colEl.addEventListener('dragend', (e) => {
                if (!e.target.classList.contains('column')) return;
                colEl.classList.remove('is-dragging-column');
                draggedColumn = null;
            });

            // Setup Task Dropzone
            const colBody = colEl.querySelector('.column-body');
            colBody.addEventListener('dragover', handleDragOver);
            colBody.addEventListener('drop', handleDrop);
        }

        ui.wrapperAddColumn.parentNode.insertBefore(colEl, ui.wrapperAddColumn);

        // Render tasks for this column
        const colTasks = appState.tasks.filter(t => t.column_id === col.id).sort((a, b) => a.position - b.position);
        colTasks.forEach(task => renderTask(task, colEl.querySelector('.column-body')));
    }

    function renderTask(task, container) {
        const tEl = document.createElement('div');
        tEl.className = 'task-card';
        tEl.dataset.id = task.id;
        tEl.draggable = appState.currentBoard.role !== 'viewer';

        let assignedHtml = task.assigned_username ?
            `<span class="task-assignee" title="${task.assigned_username}"><i class="fa-solid fa-user"></i> ${getInitials(task.assigned_username)}</span>` : '';

        let dueDateHtml = '';
        if (task.due_date) {
            const isPast = new Date(task.due_date) < new Date(new Date().setHours(0, 0, 0, 0));
            const colorClass = isPast ? 'text-danger' : 'text-muted';
            dueDateHtml = `<span class="badge ${colorClass}" style="margin-right: 6px;" data-i18n-title="due_date" title="${window.i18n ? window.i18n.t('due_date') : 'Due Date'}"><i class="fa-regular fa-calendar"></i> ${task.due_date}</span>`;
        }

        tEl.innerHTML = `
            <div class="task-title flex-between">
                <span>${task.title}</span>
                ${(appState.currentBoard.role === 'owner' || appState.currentBoard.role === 'editor') ? `
                <div class="task-arrows">
                    <button class="icon-btn arrow-btn btn-move-task" data-dir="left" data-i18n-title="alerts.btn_move_left" title="${window.i18n ? window.i18n.t('alerts.btn_move_left') : 'Move Left'}"><i class="fa-solid fa-arrow-left"></i></button>
                    <button class="icon-btn arrow-btn btn-move-task" data-dir="up" data-i18n-title="alerts.btn_move_up" title="${window.i18n ? window.i18n.t('alerts.btn_move_up') : 'Move Up'}"><i class="fa-solid fa-arrow-up"></i></button>
                    <button class="icon-btn arrow-btn btn-move-task" data-dir="down" data-i18n-title="alerts.btn_move_down" title="${window.i18n ? window.i18n.t('alerts.btn_move_down') : 'Move Down'}"><i class="fa-solid fa-arrow-down"></i></button>
                    <button class="icon-btn arrow-btn btn-move-task" data-dir="right" data-i18n-title="alerts.btn_move_right" title="${window.i18n ? window.i18n.t('alerts.btn_move_right') : 'Move Right'}"><i class="fa-solid fa-arrow-right"></i></button>
                    <button class="icon-btn arrow-btn text-danger btn-delete-task-quick" data-i18n-title="alerts.btn_delete_task" title="${window.i18n ? window.i18n.t('alerts.btn_delete_task') : 'Delete Task'}" style="margin-left:4px;"><i class="fa-solid fa-trash"></i></button>
                </div>
                ` : ''}
            </div>
            <div class="task-footer">
                <div style="display:flex; justify-content:space-between; align-items:center; margin-top:8px;">
                    <span>${task.description ? `<i class="fa-solid fa-align-left" data-i18n-title="alerts.txt_has_desc" title="${window.i18n ? window.i18n.t('alerts.txt_has_desc') : 'Has description'}" style="color:var(--text-muted);"></i>` : ''}</span>
                    <div style="display:flex; gap:6px; align-items:center;">
                        ${parseInt(task.unread_comment_count || 0, 10) > 0
                ? `<span class="badge bg-danger" data-i18n-title="alerts.txt_new_comments" title="${window.i18n ? window.i18n.t('alerts.txt_new_comments') : 'New comments'}" style="border-radius:12px; padding:2px 6px; font-size:0.75rem;"><i class="fa-solid fa-comment"></i> ${task.unread_comment_count}</span>`
                : (parseInt(task.comment_count || 0, 10) > 0
                    ? `<i class="fa-solid fa-comment" data-i18n-title="task_comments" title="${window.i18n ? window.i18n.t('task_comments') : 'Comments'}" style="color:var(--text-muted);"></i> <span style="font-size:0.8rem;color:var(--text-muted);">${task.comment_count}</span>`
                    : '')
            }
                    </div>
                </div>
                <div style="display:flex; align-items:center;">
                    ${dueDateHtml}
                    ${assignedHtml}
                </div>
            </div>
        `;

        if (appState.currentBoard.role !== 'viewer') {
            tEl.addEventListener('click', async () => {
                document.getElementById('modal-task-title').textContent = window.i18n ? window.i18n.t('title_edit_task') : 'Edit Task';
                document.getElementById('task-id-input').value = task.id;
                document.getElementById('task-column-id-input').value = task.column_id;
                document.getElementById('task-title-input').value = task.title;
                document.getElementById('task-desc-input').value = task.description || '';
                document.getElementById('task-assign-id-input').value = task.assigned_to || '';
                document.getElementById('task-assign-search-input').value = task.assigned_username || '';
                document.getElementById('task-due-date').value = task.due_date || '';
                ui.btnDeleteTask.classList.remove('hidden');

                // Comments Section
                ui.taskCommentsSection.classList.remove('hidden');
                ui.taskCommentsList.innerHTML = '<div style="padding:1rem;" class="text-muted">Loading comments...</div>';
                try {
                    const comRes = await api.getTaskComments(task.id);
                    renderTaskComments(comRes.comments);
                } catch (e) { ui.taskCommentsList.innerHTML = ''; }

                openModal(ui.modalTask);
            });

            tEl.addEventListener('dragstart', (e) => {
                draggedTask = tEl;
                setTimeout(() => tEl.classList.add('is-dragging'), 0);
            });
            tEl.addEventListener('dragend', () => {
                draggedTask.classList.remove('is-dragging');
                draggedTask = null;
            });

            // Handle manual arrows
            tEl.querySelectorAll('.btn-move-task').forEach(btn => {
                btn.addEventListener('click', (e) => {
                    e.stopPropagation(); // prevent modal opening
                    moveTaskManual(task, e.currentTarget.dataset.dir);
                });
            });

            // Handle quick delete
            const btnQuickDelete = tEl.querySelector('.btn-delete-task-quick');
            if (btnQuickDelete) {
                btnQuickDelete.addEventListener('click', async (e) => {
                    e.stopPropagation(); // prevent modal opening
                    if (confirm(window.i18n ? window.i18n.t('alerts.confirm_delete_task').replace('{0}', task.title) : `Are you sure you want to delete task "${task.title}"?`)) {
                        try {
                            await api.deleteTask(task.id);
                            showToast(window.i18n ? window.i18n.t('alerts.task_deleted') : 'Task deleted');
                            loadBoardData(appState.currentBoard.id);
                        } catch (err) { showToast(err.message, 'error'); }
                    }
                });
            }
        }

        container.appendChild(tEl);
    }

    // --- Drag and Drop & Manual Move Logic ---
    async function moveColumn(colId, direction) {
        // direction: -1 (left), 1 (right)
        const colIndex = appState.columns.findIndex(c => c.id === colId);
        if (colIndex < 0) return;

        const newIndex = colIndex + direction;
        if (newIndex < 0 || newIndex >= appState.columns.length) return; // Cant move further

        // Swap positions locally
        const temp = appState.columns[colIndex].position;
        appState.columns[colIndex].position = appState.columns[newIndex].position;
        appState.columns[newIndex].position = temp;

        // Re-sort and render locally for immediate feedback
        appState.columns.sort((a, b) => a.position - b.position);

        // Send update to server for both columns
        try {
            await api.updateColumnPos([
                { id: appState.columns[colIndex].id, position: appState.columns[colIndex].position },
                { id: appState.columns[newIndex].id, position: appState.columns[newIndex].position }
            ]);
            loadBoardData(appState.currentBoard.id);
        } catch (e) { showToast(window.i18n ? window.i18n.t('alerts.sync_failed') : 'Sync failed.', 'error'); }
    }

    async function moveTaskManual(task, direction) {
        let newColumnId = task.column_id;
        let newPos = task.position;
        let requiresSwap = false;
        let swapTask = null;

        const currentColumnTasks = appState.tasks.filter(t => t.column_id === task.column_id).sort((a, b) => a.position - b.position);
        const taskIdxInCol = currentColumnTasks.findIndex(t => t.id === task.id);
        const colIdx = appState.columns.findIndex(c => c.id === task.column_id);

        if (direction === 'up') {
            if (taskIdxInCol > 0) {
                swapTask = currentColumnTasks[taskIdxInCol - 1];
                requiresSwap = true;
            } else return; // already at top
        } else if (direction === 'down') {
            if (taskIdxInCol < currentColumnTasks.length - 1) {
                swapTask = currentColumnTasks[taskIdxInCol + 1];
                requiresSwap = true;
            } else return; // already at bottom
        } else if (direction === 'left') {
            if (colIdx > 0) {
                newColumnId = appState.columns[colIdx - 1].id;
                newPos = appState.tasks.filter(t => t.column_id === newColumnId).length; // put at bottom of new col
            } else return;
        } else if (direction === 'right') {
            if (colIdx < appState.columns.length - 1) {
                newColumnId = appState.columns[colIdx + 1].id;
                newPos = appState.tasks.filter(t => t.column_id === newColumnId).length;
            } else return;
        }

        try {
            if (requiresSwap && swapTask) {
                // If moving up/down in same column, swap exact positions
                await api.moveTask(task.id, newColumnId, swapTask.position);
                await api.moveTask(swapTask.id, newColumnId, task.position);
            } else {
                // Moving between columns
                await api.moveTask(task.id, newColumnId, newPos);
            }

            // Refresh
            const tasksData = await api.getTasks(appState.currentBoard.id);
            appState.tasks = tasksData.tasks;
            loadBoardData(appState.currentBoard.id);
        } catch (e) {
            showToast(window.i18n ? window.i18n.t('alerts.move_task_failed') : 'Failed to move task', 'error');
        }
    }

    function handleDragOver(e) {
        if (!draggedTask) return;
        e.preventDefault();
        const container = e.currentTarget;
        const afterElement = getDragAfterElement(container, e.clientY);
        if (afterElement == null) {
            container.appendChild(draggedTask);
        } else {
            container.insertBefore(draggedTask, afterElement);
        }
    }

    function getDragAfterElement(container, y) {
        const draggableElements = [...container.querySelectorAll('.task-card:not(.is-dragging)')];
        return draggableElements.reduce((closest, child) => {
            const box = child.getBoundingClientRect();
            const offset = y - box.top - box.height / 2;
            if (offset < 0 && offset > closest.offset) {
                return { offset: offset, element: child };
            } else {
                return closest;
            }
        }, { offset: Number.NEGATIVE_INFINITY }).element;
    }

    async function handleDrop(e) {
        e.preventDefault();
        if (!draggedTask) return;

        const container = e.currentTarget;
        const newColumnId = container.dataset.colId;
        const taskId = draggedTask.dataset.id;

        // Calculate new position index based on DOM order
        const tasksInDOM = [...container.querySelectorAll('.task-card')];
        const newPos = tasksInDOM.findIndex(el => el.dataset.id === taskId);

        try {
            await api.moveTask(taskId, newColumnId, newPos);
            // Re-fetch clean data silently
            const tasksData = await api.getTasks(appState.currentBoard.id);
            appState.tasks = tasksData.tasks;
        } catch (err) {
            showToast(window.i18n ? window.i18n.t('alerts.sync_failed') : 'Failed to sync move with server', 'error');
            loadBoardData(appState.currentBoard.id); // Revert UI
        }
    }

    // --- Column Drag and Drop Logic ---
    function handleBoardDragOver(e) {
        if (!draggedColumn) return;
        e.preventDefault();
        const afterElement = getDragAfterColumn(ui.boardCanvas, e.clientX);
        if (afterElement == null) {
            ui.boardCanvas.insertBefore(draggedColumn, ui.wrapperAddColumn);
        } else {
            ui.boardCanvas.insertBefore(draggedColumn, afterElement);
        }
    }

    function getDragAfterColumn(container, x) {
        const draggableElements = [...container.querySelectorAll('.column:not(.is-dragging-column)')];
        return draggableElements.reduce((closest, child) => {
            const box = child.getBoundingClientRect();
            const offset = x - box.left - box.width / 2;
            if (offset < 0 && offset > closest.offset) {
                return { offset: offset, element: child };
            } else {
                return closest;
            }
        }, { offset: Number.NEGATIVE_INFINITY }).element;
    }

    async function handleBoardDrop(e) {
        if (!draggedColumn) return;
        e.preventDefault();

        const colId = draggedColumn.dataset.id;
        const columnsInDOM = [...ui.boardCanvas.querySelectorAll('.column')];

        let positionsToUpdate = [];
        columnsInDOM.forEach((cEl, idx) => {
            const id = parseInt(cEl.dataset.id);
            const col = appState.columns.find(c => c.id == id);
            if (col && col.position !== idx) {
                positionsToUpdate.push({ id: id, position: idx });
                col.position = idx;
            }
        });

        if (positionsToUpdate.length > 0) {
            try {
                await api.updateColumnPos(positionsToUpdate);
                appState.columns.sort((a, b) => a.position - b.position);
            } catch (err) {
                showToast(window.i18n ? window.i18n.t('alerts.sync_col_move_failed') : 'Failed to sync column move', 'error');
                loadBoardData(appState.currentBoard.id);
            }
        }
    }

    ui.boardCanvas.addEventListener('dragover', handleBoardDragOver);
    ui.boardCanvas.addEventListener('drop', handleBoardDrop);

    function setupAutocomplete(searchInputId, hiddenInputId, resultsContainerId, onSelectCallback = null) {
        const searchInput = document.getElementById(searchInputId);
        const searchResults = document.getElementById(resultsContainerId);
        const hiddenInput = document.getElementById(hiddenInputId);
        let timeout;

        if (!searchInput || !searchResults || !hiddenInput) return;

        searchInput.addEventListener('input', (e) => {
            const query = e.target.value.trim();
            clearTimeout(timeout);
            hiddenInput.value = ''; // Reset ID when typing

            if (query.length < 2) {
                searchResults.classList.add('hidden');
                return;
            }

            timeout = setTimeout(async () => {
                try {
                    const res = await api.searchUsers(query);
                    searchResults.innerHTML = '';
                    if (res.users.length === 0) {
                        searchResults.innerHTML = '<div style="padding: 0.5rem 1rem;" class="text-muted">No users found</div>';
                    } else {
                        res.users.forEach(u => {
                            const div = document.createElement('div');
                            div.className = 'autocomplete-item';
                            div.innerHTML = `<strong>${u.username}</strong> <br><small class="text-muted">${u.email}</small>`;
                            div.addEventListener('click', () => {
                                searchInput.value = u.username;
                                hiddenInput.value = u.id;
                                searchResults.classList.add('hidden');
                                if (onSelectCallback) {
                                    onSelectCallback(u.id, u.username);
                                }
                            });
                            searchResults.appendChild(div);
                        });
                    }
                    searchResults.classList.remove('hidden');
                } catch (err) { }
            }, 300);
        });

        document.addEventListener('click', (e) => {
            if (!searchInput.contains(e.target) && !searchResults.contains(e.target)) {
                searchResults.classList.add('hidden');
            }
        });
    }

    setupAutocomplete('task-assign-search-input', 'task-assign-id-input', 'task-assign-results');
    setupAutocomplete('add-member-search', 'add-member-user-id', 'add-member-results');
    setupAutocomplete('inbox-search-users', 'inbox-search-user-id', 'inbox-search-results', (userId, username) => {
        activateInboxChat(userId, username);
        // Clear search box after selection to keep UI clean
        setTimeout(() => {
            document.getElementById('inbox-search-users').value = '';
        }, 300);
    });

    ui.formTask.addEventListener('submit', async (e) => {
        e.preventDefault();
        const data = Object.fromEntries(new FormData(e.target));
        try {
            if (data.task_id) {
                await api.updateTask(data.task_id, data.title, data.description, data.assigned_to, data.due_date);
                showToast(window.i18n ? window.i18n.t('alerts.task_updated') : 'Task updated');
            } else {
                await api.createTask(data.column_id, data.title, data.description, data.assigned_to, data.due_date);
                showToast(window.i18n ? window.i18n.t('alerts.task_created') : 'Task created');
            }
            closeModal();
            loadBoardData(appState.currentBoard.id);
        } catch (err) { showToast(err.message, 'error'); }
    });

    ui.formTaskComment.addEventListener('submit', async (e) => {
        e.preventDefault();
        const content = new FormData(e.target).get('content');
        const taskId = document.getElementById('task-id-input').value;
        if (!taskId || !content.trim()) return;

        try {
            const res = await api.addTaskComment(taskId, content.trim());
            e.target.reset();
            // Fetch list again or append directly
            const comRes = await api.getTaskComments(taskId);
            renderTaskComments(comRes.comments);
        } catch (err) { showToast(err.message, 'error'); }
    });

    function renderTaskComments(comments) {
        ui.taskCommentsList.innerHTML = '';
        if (comments.length === 0) {
            ui.taskCommentsList.innerHTML = `<div style="padding:1rem;" class="text-muted text-center"><small>${window.i18n ? window.i18n.t('task_no_comments') : 'No comments yet.'}</small></div>`;
            return;
        }

        comments.forEach(c => {
            const div = document.createElement('div');
            div.style.padding = "0.5rem";
            div.style.marginBottom = "0.5rem";
            div.style.background = "var(--bg-color)";
            div.style.borderRadius = "var(--border-radius)";
            div.style.fontSize = "0.9rem";
            div.innerHTML = `
                <div class="flex-between mb-1">
                    <strong>${c.username}</strong>
                    <small class="text-muted">${new Date(c.created_at).toLocaleString()}</small>
                </div>
                <div>${c.content} <br></div>
            `;
            ui.taskCommentsList.appendChild(div);
        });
        ui.taskCommentsList.scrollTop = ui.taskCommentsList.scrollHeight;
    }

    ui.btnDeleteTask.addEventListener('click', async () => {
        const id = document.getElementById('task-id-input').value;
        if (id && confirm(window.i18n ? window.i18n.t('alerts.confirm_delete_task_simple') : 'Delete this task?')) {
            try {
                await api.deleteTask(id);
                showToast(window.i18n ? window.i18n.t('alerts.task_deleted') : 'Task deleted');
                closeModal();
                loadBoardData(appState.currentBoard.id);
            } catch (err) { showToast(err.message, 'error'); }
        }
    });

    ui.btnAddColumn.addEventListener('click', async () => {
        const title = prompt(window.i18n ? window.i18n.t('alerts.prompt_enter_column') : 'Enter column title:');
        if (title) {
            try {
                await api.createColumn(appState.currentBoard.id, title);
                loadBoardData(appState.currentBoard.id);
            } catch (err) { showToast(err.message, 'error'); }
        }
    });

    // --- Team Mamanegement ---
    ui.btnTeam.addEventListener('click', async () => {
        if (!appState.currentBoard) return;
        openModal(ui.modalTeam);
        loadTeam();
    });

    async function loadTeam() {
        const list = document.getElementById('team-members-list');
        list.innerHTML = window.i18n ? window.i18n.t('txt_loading') : 'Loading...';
        try {
            const res = await api.getTeam(appState.currentBoard.id);
            list.innerHTML = '';

            const isBoardOwner = appState.currentBoard.role === 'owner';

            res.members.forEach(m => {
                const div = document.createElement('div');
                div.className = 'flex-between mb-2 mt-2';

                // Only render a select dropdown if the active user is the board owner, and the row isn't themself
                let roleDisplay = `<span class="badge ${m.role === 'owner' ? 'role-badge' : 'text-muted'}">${window.i18n ? window.i18n.t('role_' + m.role) : m.role}</span>`;

                if (isBoardOwner && m.id != appState.user.id) {
                    roleDisplay = `
                        <select class="form-control w-auto" style="padding: 2px 6px; font-size: 0.8rem; height: auto; display: inline-block;" onchange="changeMemberRole(${m.id}, this)">
                            <option value="owner" ${m.role === 'owner' ? 'selected' : ''}>${window.i18n ? window.i18n.t('role_owner') : 'Owner'}</option>
                            <option value="editor" ${m.role === 'editor' ? 'selected' : ''}>${window.i18n ? window.i18n.t('role_editor') : 'Editor'}</option>
                            <option value="viewer" ${m.role === 'viewer' ? 'selected' : ''}>${window.i18n ? window.i18n.t('role_viewer') : 'Viewer'}</option>
                        </select>
                    `;
                }

                div.innerHTML = `
                    <div style="flex: 1;">
                        <strong>${m.username}</strong> ${roleDisplay}
                        <div class="text-muted"><small>ID: ${m.id} | ${m.email}</small></div>
                    </div>
                    ${(isBoardOwner && m.id != appState.user.id) || (m.role !== 'owner') ?
                        `<button class="btn btn-danger btn-sm" onclick="removeMember(${m.id})">${window.i18n ? window.i18n.t('btn_delete_user_short') : 'Delete'}</button>` : ''}
                `;
                list.appendChild(div);
            });
        } catch (e) { list.innerHTML = window.i18n ? window.i18n.t('load_team_fail') : 'Failed to load team.'; }
    }

    ui.formAddMember.addEventListener('submit', async (e) => {
        e.preventDefault();
        const data = Object.fromEntries(new FormData(e.target));
        try {
            await api.addTeamMember(appState.currentBoard.id, data.user_id, data.role);
            showToast(window.i18n ? window.i18n.t('alerts.member_added') : 'Member added');
            ui.formAddMember.reset();
            document.getElementById('add-member-search').value = '';
            document.getElementById('add-member-user-id').value = '';
            loadTeam();
        } catch (err) { showToast(err.message, 'error'); }
    });

    setupAutocomplete('add-member-search', 'add-member-user-id', 'add-member-results');

    window.removeMember = async (userId) => {
        if (confirm(window.i18n ? window.i18n.t('alerts.member_remove_confirm') : 'Remove this member?')) {
            try {
                await api.removeTeamMember(appState.currentBoard.id, userId);
                showToast(window.i18n ? window.i18n.t('alerts.member_removed') : 'Member removed');
                loadTeam();
            } catch (e) { showToast(e.message, 'error'); }
        }
    };

    window.changeMemberRole = async (userId, selectEl) => {
        const newRole = selectEl.value;
        try {
            await api.updateTeamMemberRole(appState.currentBoard.id, userId, newRole);
            showToast(window.i18n ? window.i18n.t('alerts.role_updated') : 'Role updated successfully.');
            // If we just promoted someone to owner, we might lose our owner rights.
            // Refresh the entire team list.
            loadTeam();
            loadBoards(); // Refresh sidebar to catch role changes
        } catch (e) {
            showToast(e.message, 'error');
            loadTeam(); // revert the select menu visually
        }
    };

    // --- Board Settings ---
    ui.btnSettings.addEventListener('click', () => {
        if (!appState.currentBoard || appState.currentBoard.role !== 'owner') return;
        document.getElementById('settings-title-input').value = appState.currentBoard.title;
        document.getElementById('settings-desc-input').value = appState.currentBoard.description || '';
        openModal(ui.modalSettings);
    });

    ui.formSettings.addEventListener('submit', async (e) => {
        e.preventDefault();
        const data = Object.fromEntries(new FormData(e.target));
        try {
            await api.updateBoard(appState.currentBoard.id, data.title, data.description);
            appState.currentBoard.title = data.title;
            appState.currentBoard.description = data.description;

            // Re-render board list title
            const activeLi = ui.boardList.querySelector(`li[data-id="${appState.currentBoard.id}"]`);
            if (activeLi) activeLi.innerHTML = `<i class="fa-solid fa-chalkboard"></i> ${data.title}`;

            // Re-render header title
            ui.currentBoardTitle.innerHTML = `${data.title} ${'<button id="btn-edit-board" class="icon-btn small" title="' + (window.i18n ? window.i18n.t('alerts.btn_rename_board') : 'Rename Board') + '" style="margin-left:8px;font-size:1rem;"><i class="fa-solid fa-pen"></i></button>'}`;

            showToast(window.i18n ? window.i18n.t('alerts.board_updated') : 'Board updated successfully');
            closeModal();
        } catch (err) { showToast(err.message, 'error'); }
    });

    ui.btnDeleteBoard.addEventListener('click', async () => {
        const confirmMsg = window.i18n ? window.i18n.t('alerts.board_delete_critical').replace('{0}', appState.currentBoard.title) : `CRITICAL WARNING: Are you sure you want to completely delete the board "${appState.currentBoard.title}"? This cannot be undone.`;
        if (confirm(confirmMsg)) {
            try {
                await api.deleteBoard(appState.currentBoard.id);
                showToast(window.i18n ? window.i18n.t('alerts.board_deleted') : 'Board deleted permanently');
                closeModal();
                appState.boards = appState.boards.filter(b => b.id !== appState.currentBoard.id);
                appState.currentBoard = null;
                renderBoardList(); // Will also pick the next board or show empty state
                if (appState.boards.length === 0) {
                    ui.boardCanvas.querySelectorAll('.column').forEach(c => c.remove());
                    ui.wrapperAddColumn.classList.add('hidden');
                    switchView('view-board');
                }
            } catch (err) { showToast(err.message, 'error'); }
        }
    });

    // --- General UI Interactions ---
    function openProfileModal() {
        if (!appState.user) return;
        ui.formProfile.reset();
        document.getElementById('profile-username').value = appState.user.username;

        const dynamicLangSwitch = document.getElementById('lang-switch');
        if (dynamicLangSwitch && window.i18n) {
            dynamicLangSwitch.value = window.i18n.currentLang;
        }

        const pwdSection = document.getElementById('profile-password-section');
        const ldapWarning = document.getElementById('profile-ldap-warning');

        if (pwdSection && ldapWarning) {
            if (appState.user.auth_method === 'ldap') {
                pwdSection.classList.add('hidden');
                ldapWarning.classList.remove('hidden');
            } else {
                pwdSection.classList.remove('hidden');
                ldapWarning.classList.add('hidden');
            }
        }

        openModal(ui.modalProfile);
        document.body.classList.remove('sidebar-collapsed'); // adjust for mobile
        ui.sidebar.classList.remove('show-mobile');
    }

    ui.btnProfile.addEventListener('click', openProfileModal);
    if (ui.btnMobileNavProfile) ui.btnMobileNavProfile.addEventListener('click', openProfileModal);

    ui.formProfile.addEventListener('submit', async (e) => {
        e.preventDefault();
        const data = Object.fromEntries(new FormData(e.target));

        if (data.new_password !== data.confirm_password) {
            showToast(window.i18n ? window.i18n.t('alerts.pw_mismatch') : 'New passwords do not match!', 'error');
            return;
        }

        try {
            await api.changePassword(data.old_password, data.new_password);
            showToast(window.i18n ? window.i18n.t('alerts.password_updated') : 'Password updated successfully!');
            closeModal();
            ui.formProfile.reset();
        } catch (err) {
            showToast(err.message, 'error');
        }
    });

    ui.closeBtns.forEach(btn => btn.addEventListener('click', closeModal));

    // Auto-close modal if clicked outside
    ui.modalOverlay.addEventListener('click', (e) => {
        if (e.target === ui.modalOverlay) closeModal();
    });

    ui.toggleSidebar.addEventListener('click', () => {
        if (window.innerWidth <= 768) {
            ui.sidebar.classList.remove('show-mobile');
        } else {
            document.body.classList.toggle('sidebar-collapsed');
        }
    });

    function openAdminView() {
        switchView('view-admin');
        document.body.classList.remove('sidebar-collapsed');
        ui.sidebar.classList.remove('show-mobile');
    }

    if (ui.btnNavAdmin) {
        ui.btnNavAdmin.addEventListener('click', openAdminView);
    }
    if (ui.btnMobileNavAdmin) {
        ui.btnMobileNavAdmin.addEventListener('click', openAdminView);
    }

    // --- Admin Functions ---
    async function loadAdminUsers() {
        if (!appState.user || appState.user.role !== 'admin') return;
        ui.adminUsersList.innerHTML = `<tr><td colspan="5" style="text-align: center; padding: 1rem;">${window.i18n ? window.i18n.t('txt_loading') : 'Loading users...'}</td></tr>`;

        try {
            const res = await api.adminGetUsers();
            ui.adminUsersList.innerHTML = '';

            if (res.users.length === 0) {
                ui.adminUsersList.innerHTML = `<tr><td colspan="5" style="text-align: center; padding: 1rem;">${window.i18n ? window.i18n.t('no_users') : 'No users found.'}</td></tr>`;
                return;
            }

            res.users.forEach(u => {
                const tr = document.createElement('tr');
                tr.style.borderBottom = '1px solid var(--border-color)';

                const statusBadge = u.is_active == 1
                    ? `<span class="badge text-primary" style="background: rgba(138,43,226,0.1)">${window.i18n ? window.i18n.t('active') : 'Active'}</span>`
                    : `<span class="badge text-danger" style="background: rgba(220,53,69,0.1)">${window.i18n ? window.i18n.t('inactive_pending') : 'Inactive (Pending)'}</span>`;

                tr.innerHTML = `
                    <td style="padding: 1rem; color: var(--text-muted);">#${u.id}</td>
                    <td style="padding: 1rem;">
                        <strong>${u.username}</strong><br>
                        <small class="text-muted">${u.email}</small>
                    </td>
                    <td style="padding: 1rem;"><span class="badge text-muted">${u.role.toUpperCase()}</span></td>
                    <td style="padding: 1rem;">${statusBadge}</td>
                    <td style="padding: 1rem; text-align: right;">
                        <button class="btn btn-secondary small btn-manage-user" data-id="${u.id}">${window.i18n ? window.i18n.t('manage') : 'Manage'}</button>
                    </td>
                `;

                tr.querySelector('.btn-manage-user').addEventListener('click', () => openAdminUserModal(u));
                ui.adminUsersList.appendChild(tr);
            });
        } catch (err) {
            ui.adminUsersList.innerHTML = `<tr><td colspan="5" style="text-align: center; padding: 1rem; color: var(--danger-color)">Error: ${err.message}</td></tr>`;
        }
    }

    async function openAdminUserModal(userObj) {
        selectedAdminUser = userObj;

        document.getElementById('admin-edit-username').value = userObj.username;
        document.getElementById('admin-edit-email').textContent = userObj.email;
        document.getElementById('admin-edit-role').textContent = userObj.role.toUpperCase();

        document.getElementById('admin-edit-user-id').value = userObj.id;
        document.getElementById('admin-pw-user-id').value = userObj.id;
        document.getElementById('admin-transfer-user-id').value = userObj.id;

        // Update Toggle Button State
        if (userObj.is_active == 1) {
            ui.btnAdminToggleActive.textContent = window.i18n ? window.i18n.t('btn_deactivate') : "Deactivate Account";
            ui.btnAdminToggleActive.className = "btn btn-secondary";
        } else {
            ui.btnAdminToggleActive.textContent = window.i18n ? window.i18n.t('btn_reactivate') : "Re-activate Account";
            ui.btnAdminToggleActive.className = "btn btn-primary";
        }

        // Disable management of the current admin (self)
        const isSelf = userObj.id == appState.user.id;
        ui.btnAdminToggleActive.disabled = isSelf;
        ui.btnAdminDeleteUser.disabled = isSelf;
        ui.btnAdminToggleActive.title = isSelf ? "Cannot deactivate yourself" : "";
        ui.btnAdminDeleteUser.title = isSelf ? "Cannot delete yourself" : "";

        ui.formAdminPassword.reset();

        // Load boards for ownership transfer setup
        const selectBoards = document.getElementById('admin-transfer-board-id');
        selectBoards.innerHTML = '<option value="">' + (window.i18n ? window.i18n.t('opt_loading_boards') : 'Loading boards...') + '</option>';
        try {
            const res = await api.adminGetUserBoards(userObj.id);
            selectBoards.innerHTML = '<option value="">' + (window.i18n ? window.i18n.t('opt_select_board') : 'Select board...') + '</option>';
            res.boards.forEach(b => {
                const opt = document.createElement('option');
                opt.value = b.id;
                opt.textContent = `${b.title} (${window.i18n ? window.i18n.t('txt_current_role') : 'Current role'}: ${b.role})`;
                if (b.role === 'owner') opt.disabled = true; // Already owner
                selectBoards.appendChild(opt);
            });
        } catch (e) {
            selectBoards.innerHTML = '<option value="">' + (window.i18n ? window.i18n.t('opt_error_loading_boards') : 'Error loading boards') + '</option>';
        }

        openModal(ui.modalAdminUser);
    }

    if (ui.btnAdminToggleActive) {
        ui.btnAdminToggleActive.addEventListener('click', async () => {
            if (!selectedAdminUser) return;
            const newStatus = selectedAdminUser.is_active == 1 ? 0 : 1;
            const actionText = newStatus === 1 ? 'reactivate' : 'deactivate';

            const confirmMsg = window.i18n ? window.i18n.t('alerts.user_action_confirm').replace('{0}', actionText).replace('{1}', selectedAdminUser.username) : `Are you sure you want to ${actionText} ${selectedAdminUser.username}?`;
            if (confirm(confirmMsg)) {
                try {
                    await api.adminToggleActive(selectedAdminUser.id, newStatus);
                    showToast(window.i18n ? window.i18n.t('alerts.user_action_success').replace('{0}', actionText) : `User ${actionText}d successfully.`);
                    closeModal();
                    loadAdminUsers();
                    updateAdminPendingBadge();
                } catch (e) { showToast(e.message, 'error'); }
            }
        });
    }

    if (ui.formAdminUsername) {
        ui.formAdminUsername.addEventListener('submit', async (e) => {
            e.preventDefault();
            const data = Object.fromEntries(new FormData(e.target));
            if (!selectedAdminUser) return;

            try {
                await api.adminChangeUsername(data.user_id, data.new_username);
                showToast(window.i18n ? window.i18n.t('alerts.username_changed').replace('{0}', data.new_username) : `Username changed to ${data.new_username}.`);
                selectedAdminUser.username = data.new_username; // Update local state for subsequent actions
                loadAdminUsers(); // Refresh the table behind the modal
            } catch (err) { showToast(err.message, 'error'); }
        });
    }

    if (ui.formAdminPassword) {
        ui.formAdminPassword.addEventListener('submit', async (e) => {
            e.preventDefault();
            const data = Object.fromEntries(new FormData(e.target));
            if (!selectedAdminUser) return;

            try {
                await api.adminChangePassword(data.user_id, data.new_password);
                showToast(window.i18n ? window.i18n.t('alerts.admin_pw_changed').replace('{0}', selectedAdminUser.username) : `Password changed for ${selectedAdminUser.username}.`);
                ui.formAdminPassword.reset();
            } catch (err) { showToast(err.message, 'error'); }
        });
    }

    if (ui.formAdminTransfer) {
        ui.formAdminTransfer.addEventListener('submit', async (e) => {
            e.preventDefault();
            const data = Object.fromEntries(new FormData(e.target));
            if (!selectedAdminUser || !data.board_id) return;

            try {
                await api.adminTransferBoardOwnership(data.board_id, data.new_owner_user_id);
                showToast(window.i18n ? window.i18n.t('alerts.board_transferred').replace('{0}', selectedAdminUser.username) : `Transferred board ownership to ${selectedAdminUser.username}.`);
                closeModal();
                loadAdminUsers();
                if (appState.currentBoard && appState.currentBoard.id == data.board_id) {
                    loadBoards(); // refresh sidebar if we gave away current board
                }
            } catch (err) { showToast(err.message, 'error'); }
        });
    }

    if (ui.btnAdminDeleteUser) {
        ui.btnAdminDeleteUser.addEventListener('click', async () => {
            if (!selectedAdminUser) return;

            try {
                // Check if user is the sole owner of any boards
                const soleOwnerInfo = await api.adminCheckSoleOwner(selectedAdminUser.id);

                if (soleOwnerInfo.sole_owned_boards && soleOwnerInfo.sole_owned_boards.length > 0) {
                    // Show transfer modal
                    ui.adminDeleteConfirmUsernameDisplay.textContent = selectedAdminUser.username;
                    ui.adminDeleteConfirmInput.value = '';

                    // Populate select
                    ui.adminDeleteTransferOwner.innerHTML = `<option value="">${window.i18n ? window.i18n.t('ph_select_new_owner') : 'Select new owner...'}</option>`;
                    if (soleOwnerInfo.transfer_candidates) {
                        soleOwnerInfo.transfer_candidates.forEach(c => {
                            const opt = document.createElement('option');
                            opt.value = c.id;
                            opt.textContent = c.username;
                            ui.adminDeleteTransferOwner.appendChild(opt);
                        });
                    }

                    openModal(ui.modalAdminDeleteConfirm);
                } else {
                    // Standard deletion
                    const msg = window.i18n ? window.i18n.t('txt_type_confirm_deletion').replace('{0}', selectedAdminUser.username) : `Type the username "${selectedAdminUser.username}" to permanently delete this user and ALL their data.`;
                    const promptMsg = window.i18n ? window.i18n.t('alerts.type_username_confirm').replace('{0}', msg) : `CRITICAL WARNING: ${msg}`;
                    const username = prompt(promptMsg);
                    if (username === selectedAdminUser.username) {
                        await executeAdminDeleteUser(selectedAdminUser.id, null);
                    } else if (username !== null) {
                        alert(window.i18n ? window.i18n.t('alerts.username_mismatch') : "Username did not match. Deletion cancelled.");
                    }
                }
            } catch (err) {
                showToast(err.message, 'error');
            }
        });
    }

    if (ui.formAdminDeleteConfirm) {
        ui.formAdminDeleteConfirm.addEventListener('submit', async (e) => {
            e.preventDefault();
            const inputName = ui.adminDeleteConfirmInput.value;
            const newOwnerId = ui.adminDeleteTransferOwner.value;

            if (inputName !== selectedAdminUser.username) {
                showToast(window.i18n ? window.i18n.t('alerts.username_mismatch_alert') : 'Username does not match.', 'error');
                return;
            }

            if (!newOwnerId) {
                showToast(window.i18n ? window.i18n.t('alerts.select_new_owner') : 'Please select a new owner.', 'error');
                return;
            }

            await executeAdminDeleteUser(selectedAdminUser.id, newOwnerId);
        });
    }

    async function executeAdminDeleteUser(userId, newOwnerId) {
        try {
            await api.adminDeleteUser(userId, newOwnerId);
            showToast(window.i18n ? window.i18n.t('alerts.user_deleted') : `User permanently deleted.`);
            closeModal();
            loadAdminUsers();
            if (appState.currentBoard) {
                loadBoards(); // Refresh sidebar in case we inherited boards
            }
        } catch (e) {
            showToast(e.message, 'error');
        }
    }

    ui.btnAdminBack.addEventListener('click', () => {
        initApp(); // Redirects safely back to the boards view
    });

    // --- Inbox Logic ---
    let inboxPollingInterval = null;
    let currentChatUserId = null;

    async function updateUnreadMessagesCount() {
        if (!appState.user) return;
        try {
            const res = await api.getUnreadDMCount();
            if (res.unread_count > 0) {
                ui.inboxBadge.textContent = res.unread_count;
                ui.inboxBadge.classList.remove('hidden');
            } else {
                ui.inboxBadge.classList.add('hidden');
            }
        } catch (e) { }
    }

    function activateInboxChat(userId, username) {
        document.querySelectorAll('.inbox-contact-item').forEach(el => el.style.background = '');
        
        // Try to visually highlight if it exists in the list
        const existingNode = [...ui.inboxContactsList.querySelectorAll('.inbox-contact-item')].find(el => el.dataset.userid == userId);
        if (existingNode) existingNode.style.background = 'rgba(0,0,0,0.05)';

        currentChatUserId = userId;
        ui.inboxChatHeader.innerHTML = `
            <div style="display:flex; justify-content:space-between; align-items:center;">
                <span>${window.i18n ? window.i18n.t('chat_with') : 'Chat with'} <strong>${username}</strong></span>
                <button id="btn-delete-chat" class="icon-btn text-danger" title="${window.i18n ? window.i18n.t('btn_delete_chat') : 'Delete Chat'}"><i class="fa-solid fa-trash"></i></button>
            </div>
        `;
        document.getElementById('btn-delete-chat').addEventListener('click', async () => {
            if (confirm(window.i18n ? window.i18n.t('alerts.confirm_delete_chat') : 'Are you sure you want to delete this entire chat?')) {
                try {
                    await api.deleteChat(currentChatUserId);
                    showToast(window.i18n ? window.i18n.t('alerts.chat_deleted') : 'Chat deleted.');
                    openInbox(); // Reload the inbox, clearing out the chat and updating contacts
                } catch (e) {
                    showToast(e.message, 'error');
                }
            }
        });
        ui.inboxReceiverId.value = userId;
        ui.inboxContentInput.disabled = false;
        ui.inboxBtnSend.disabled = false;
        loadInboxChat();
    }

    async function loadInboxContacts() {
        try {
            const res = await api.getDMContacts();
            ui.inboxContactsList.innerHTML = '';
            if (res.contacts.length === 0) {
                ui.inboxContactsList.innerHTML = `<div class="text-muted text-center" style="padding-top:2rem;" data-i18n="inbox_no_contacts">${window.i18n ? window.i18n.t('inbox_no_contacts') : 'No contacts available.'}</div>`;
                return;
            }
            res.contacts.forEach(c => {
                const div = document.createElement('div');
                div.className = 'inbox-contact-item';
                div.dataset.userid = c.id;
                div.style.padding = '0.5rem';
                div.style.cursor = 'pointer';
                div.style.borderBottom = '1px solid var(--border-color)';
                div.style.display = 'flex';
                div.style.justifyContent = 'space-between';
                div.style.alignItems = 'center';

                div.innerHTML = `
                    <span>${c.username}</span>
                    ${c.unread_count > 0 ? `<span class="badge bg-danger" style="border-radius:12px; padding:2px 6px;">${c.unread_count}</span>` : ''}
                `;
                div.addEventListener('click', () => {
                    activateInboxChat(c.id, c.username);
                });
                ui.inboxContactsList.appendChild(div);
            });
        } catch (e) { }
    }

    async function loadInboxChat() {
        if (!currentChatUserId) return;
        try {
            const res = await api.getDMConversation(currentChatUserId);
            ui.inboxChatHistory.innerHTML = '';
            res.messages.forEach(m => {
                const div = document.createElement('div');
                const isMe = m.sender_id === appState.user.id;
                div.style.alignSelf = isMe ? 'flex-end' : 'flex-start';
                // background pro 'isMe' = moje barva, pro '!isMe' = příchozí = zelená barva
                div.style.background = isMe ? 'var(--primary-color)' : '#d4edda';
                div.style.color = isMe ? 'white' : '#155724'; // Tmavě zelený text pro perfektní kontrast s #d4edda
                div.style.padding = '0.5rem 1rem';
                div.style.borderRadius = '16px';
                div.style.maxWidth = '75%';
                div.innerHTML = `
                    <div style="font-size:0.75rem; opacity:0.8; margin-bottom:2px;">${isMe ? (window.i18n ? window.i18n.t('txt_you_sender') : 'You') : m.sender_name} - ${new Date(m.created_at).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}</div>
                    <div>${m.content}</div>
                `;
                ui.inboxChatHistory.appendChild(div);
            });
            ui.inboxChatHistory.scrollTop = ui.inboxChatHistory.scrollHeight;
            updateUnreadMessagesCount(); // refresh global badge
        } catch (e) { }
    }

    function openInbox() {
        openModal(ui.modalInbox);
        currentChatUserId = null;
        ui.inboxChatHeader.innerHTML = `<span data-i18n="inbox_select_contact">${window.i18n ? window.i18n.t('inbox_select_contact') : 'Select a contact from the list to start messaging.'}</span>`;
        ui.inboxChatHistory.innerHTML = '';
        ui.inboxContentInput.disabled = true;
        ui.inboxBtnSend.disabled = true;
        loadInboxContacts();
        if (inboxPollingInterval) clearInterval(inboxPollingInterval);
        inboxPollingInterval = setInterval(() => {
            if (currentChatUserId) loadInboxChat();
            loadInboxContacts();
        }, 5000);
    }

    ui.btnInbox.addEventListener('click', openInbox);
    if (ui.btnMobileNavInbox) ui.btnMobileNavInbox.addEventListener('click', openInbox);

    ui.formInboxSend.addEventListener('submit', async (e) => {
        e.preventDefault();
        const content = ui.inboxContentInput.value.trim();
        const receiverId = ui.inboxReceiverId.value;
        if (!content || !receiverId) return;

        try {
            await api.sendDirectMessage(receiverId, content);
            ui.inboxContentInput.value = '';
            loadInboxChat();
        } catch (err) { showToast(err.message, 'error'); }
    });

    // We will combine the loops at the bottom of the script

    // --- Board Chat Logic ---
    let boardChatPollingInterval = null;

    async function updateBoardChatUnreadCount() {
        if (!appState.currentBoard || !appState.currentBoard.id) return;
        try {
            const res = await api.getBoardChatUnread(appState.currentBoard.id);
            if (res.unread_count > 0) {
                ui.btnBoardChatBadge.textContent = res.unread_count;
                ui.btnBoardChatBadge.classList.remove('hidden');
            } else {
                ui.btnBoardChatBadge.classList.add('hidden');
            }
        } catch (e) { }
    }

    async function loadBoardChat() {
        if (!appState.currentBoard || !appState.currentBoard.id) return;
        try {
            const res = await api.getBoardChat(appState.currentBoard.id);
            ui.boardChatHistory.innerHTML = '';
            if (res.messages.length === 0) {
                ui.boardChatHistory.innerHTML = `<div class="text-muted text-center" style="padding-top:2rem;" data-i18n="board_chat_empty">${window.i18n ? window.i18n.t('board_chat_empty') || 'No messages in this project yet.' : 'No messages in this project yet.'}</div>`;
                return;
            }
            res.messages.forEach(m => {
                const div = document.createElement('div');
                const isMe = m.user_id === appState.user.id;
                div.style.alignSelf = isMe ? 'flex-end' : 'flex-start';
                div.style.background = isMe ? 'var(--primary-color)' : 'var(--card-bg)';
                div.style.color = isMe ? 'white' : 'var(--text-color)';
                div.style.padding = '0.5rem 1rem';
                div.style.borderRadius = '12px';
                div.style.maxWidth = '85%';
                div.style.border = isMe ? 'none' : '1px solid var(--border-color)';
                div.innerHTML = `
                    <div style="font-size:0.75rem; opacity:0.8; margin-bottom:2px;">${isMe ? (window.i18n ? window.i18n.t('txt_you_sender') : 'You') : m.sender_name} - ${new Date(m.created_at).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}</div>
                    <div>${m.content}</div>
                `;
                ui.boardChatHistory.appendChild(div);
            });
            ui.boardChatHistory.scrollTop = ui.boardChatHistory.scrollHeight;
            updateBoardChatUnreadCount(); // Refresh badge after loading history
        } catch (e) { }
    }

    ui.btnBoardChat.addEventListener('click', () => {
        ui.boardChatSidebar.classList.remove('hidden');
        if (appState.currentBoard.role === 'viewer') {
            ui.boardChatContentInput.disabled = true;
            ui.boardChatContentInput.placeholder = window.i18n ? window.i18n.t('ph_viewers_no_chat') || 'Viewers cannot send messages.' : "Viewers cannot send messages.";
        } else {
            ui.boardChatContentInput.disabled = false;
        }
        loadBoardChat();
        if (boardChatPollingInterval) clearInterval(boardChatPollingInterval);
        boardChatPollingInterval = setInterval(loadBoardChat, 5000);
    });

    ui.btnCloseBoardChat.addEventListener('click', () => {
        ui.boardChatSidebar.classList.add('hidden');
        if (boardChatPollingInterval) {
            clearInterval(boardChatPollingInterval);
            boardChatPollingInterval = null;
        }
    });

    ui.formBoardChat.addEventListener('submit', async (e) => {
        e.preventDefault();
        const content = ui.boardChatContentInput.value.trim();
        if (!content || !appState.currentBoard) return;

        try {
            await api.sendBoardChat(appState.currentBoard.id, content);
            ui.boardChatContentInput.value = '';
            loadBoardChat();
        } catch (err) { showToast(err.message, 'error'); }
    });

    async function updateAdminPendingBadge() {
        if (!appState.user || appState.user.role !== 'admin') return;
        try {
            const res = await api.adminGetPendingUsersCount();
            const count = res.count || 0;
            if (count > 0) {
                if (ui.adminPendingBadge) {
                    ui.adminPendingBadge.textContent = count;
                    ui.adminPendingBadge.classList.remove('hidden');
                }
                if (ui.mobileAdminPendingBadge) {
                    ui.mobileAdminPendingBadge.textContent = count;
                    ui.mobileAdminPendingBadge.classList.remove('hidden');
                }
            } else {
                if (ui.adminPendingBadge) ui.adminPendingBadge.classList.add('hidden');
                if (ui.mobileAdminPendingBadge) ui.mobileAdminPendingBadge.classList.add('hidden');
            }
        } catch (e) {
            // Silently ignore polling errors
        }
    }

    setInterval(() => {
        updateUnreadMessagesCount();
        updateBoardChatUnreadCount();
        updateAdminPendingBadge();
    }, 15000);

    ui.btnMobileSidebar.addEventListener('click', () => {
        if (window.innerWidth > 768 && document.body.classList.contains('sidebar-collapsed')) {
            document.body.classList.remove('sidebar-collapsed');
        } else {
            ui.sidebar.classList.add('show-mobile');
        }
    });

    // Close sidebar on mobile when clicking outside
    document.addEventListener('click', (e) => {
        if (window.innerWidth <= 768 && ui.sidebar.classList.contains('show-mobile')) {
            if (!ui.sidebar.contains(e.target) && e.target !== ui.btnMobileSidebar && !ui.btnMobileSidebar.contains(e.target)) {
                ui.sidebar.classList.remove('show-mobile');
            }
        }
    });

    // Boot the app
    window.i18n.loadLanguage(window.i18n.currentLang).then(() => {
        initApp();
    });
});
