/**
 * WordPress dependencies
 */
import Board from './../comment/board';
import { updateAutodraftIds, showNotice } from './../common/utils';

const { __ } = wp.i18n;
const { createRoot, useEffect, useState, useRef } = wp.element;
if (cfIsVersionCheck(multicollab_wp_version.wp_version, "6.6", "lt")) {
    var { PluginSidebar } = wp.editPost;  // For versions less than 6.6
} else {
    var { PluginSidebar } = wp.editor;  // For versions 6.6 and above, use wp.editor
}
const { registerPlugin } = wp.plugins;
const { select, useSelect, dispatch } = wp.data;

/**
 * Apply selection styling with performance optimization
 */
function applySelectionStyling(boardId, prefix) {
    requestAnimationFrame(() => {
        const selectedBoardElement = document.querySelector(`#${prefix}${boardId}.cls-board-outer`);
        if (selectedBoardElement) {
            selectedBoardElement.style.opacity = '0.2';
        }
    });
}

/**
 * Show loading notification at the top of boards
 */
function showLoadingNotification(commentNode) {
    let notification = document.getElementById("cf-boards-loading-notification");
    
    if (notification) {
        return; // Already showing
    }
    
    // Create notification at the top
    notification = document.createElement("div");
    notification.id = "cf-boards-loading-notification";
    notification.className = "cf-boards-loading-notification";
    notification.innerHTML = '<span class="cf-loading-text">'+ __( "Loading boards", "commenting-feature" ) +'</span>';
    
    // Insert at the beginning of commentNode
    commentNode.insertBefore(notification, commentNode.firstChild);
}

/**
 * Show loader - only shows one loader at a time, always at the bottom
 */
function showLoader(commentNode) {
    // Show notification at the top
    showLoadingNotification(commentNode);

    let loaderStyle = document.getElementById("cf-loader-board-box");
    
    if (loaderStyle) {
        // Move existing loader to bottom by re-appending it
        commentNode.appendChild(loaderStyle);
        return;
    }
    
    // Create new loader
    loaderStyle = document.createElement("div");
    loaderStyle.id = "cf-loader-board-box";
    loaderStyle.innerHTML = '<div class="loader"></div>';
    commentNode.appendChild(loaderStyle);
}

/**
 * Hide loading notification
 */
function hideLoadingNotification() {
    const notification = document.getElementById("cf-boards-loading-notification");
    if (notification) notification.remove();
}

/**
 * Hide loader
 */
function hideLoader() {
    const loaderStyle = document.getElementById("cf-loader-board-box");
    if (loaderStyle) loaderStyle.remove();
    
    // Also remove the loading notification
    hideLoadingNotification();
}

// Track loading state for unified loader management
let loadingState = {
    comments: false,
    suggestions: false
};

/**
 * Reset loading state - call before starting new board render cycle
 */
function resetLoadingState() {
    loadingState.comments = false;
    loadingState.suggestions = false;
}

/**
 * Update loading state and manage loader visibility
 */
function updateLoadingState(type, isLoading, commentNode) {
    loadingState[type] = isLoading;
    
    if (loadingState.comments || loadingState.suggestions) {
        showLoader(commentNode);
    } else {
        hideLoader();
    }
}

/**
 * Render comment boards from cache with batch DOM updates
 */
function renderCommentBoardsFromCache(commentBoardIds, commentNode, selecteBoardId, allThreads) {
    const fragment = document.createDocumentFragment();
    
    commentBoardIds.filter(Boolean).forEach((boardId) => {
        if (boardId && boardId.startsWith("el")) {
            const newNode = document.createElement("div");
            newNode.id = boardId;
            newNode.className = "cls-board-outer cm-board is_active";
            fragment.appendChild(newNode);
            allThreads.push(boardId);
        }
    });

    // Batch DOM update
    commentNode.appendChild(fragment);

    // Move loader to bottom after adding comment boards
    const existingLoader = document.getElementById("cf-loader-board-box");
    if (existingLoader) {
        commentNode.appendChild(existingLoader);
    }

    // Render React components in next frame
    requestAnimationFrame(() => {
        commentBoardIds.filter(Boolean).forEach((boardId) => {
            if (boardId && boardId.startsWith("el")) {
                const container = document.getElementById(boardId);
                const root = createRoot(container);
                root.render(<Board datatext={boardId} onLoadFetch={1} />);

                // if (selecteBoardId) {
                //     applySelectionStyling(boardId, '');
                // }
            }
        });
    });
}

/**
 * Fetch chunk with retry logic
 */
async function fetchChunkWithRetry(chunk, postId, userId, maxRetries) {
    for (let attempt = 1; attempt <= maxRetries; attempt++) {
        try {
            const response = await wp.apiFetch({
                path: `/multicollab/multicollab-get-comments-on-load-api/?currentPostID=${postId}&currentUserID=${userId}&elIDs=${encodeURIComponent(JSON.stringify(chunk))}`,
            });
            return response;
        } catch (error) {
            if (attempt === maxRetries) {
                throw error;
            }
            // Exponential backoff
            await new Promise(resolve => setTimeout(resolve, Math.pow(2, attempt) * 1000));
        }
    }
}

/**
 * Enhanced fetchBoardsInChunks with better error handling
 */
function fetchBoardsInChunks(boardIds, postId, userId, chunkSize = 10) {
    return new Promise((resolve, reject) => {
        const { setFetchedCommentCache } = dispatch('mdstore');
        const totalChunks = Math.ceil(boardIds.length / chunkSize);
        let completedChunks = 0;
        let failedChunks = 0;
        const maxRetries = 3;

        if (totalChunks === 0) {
            resolve();
            return;
        }

        // Process chunks with retry logic
        for (let i = 0; i < boardIds.length; i += chunkSize) {
            const chunk = boardIds.slice(i, i + chunkSize);
            fetchChunkWithRetry(chunk, postId, userId, maxRetries)
                .then((response) => {
                    // Cache the response
                    for (const [boardId, data] of Object.entries(response)) {
                        const cacheKey = `${postId}-${boardId}`;
                        setFetchedCommentCache(cacheKey, data);
                    }
                    
                    completedChunks++;
                    checkCompletion();
                })
                .catch((error) => {
                    console.error('Chunk failed after retries:', error);
                    failedChunks++;
                    completedChunks++;
                    checkCompletion();
                });
        }

        function checkCompletion() {
            if (completedChunks === totalChunks) {
                if (failedChunks > 0) {
                    console.warn(`${failedChunks} chunks failed to fetch`);
                }
                resolve();
            }
        }
    });
}

/**
 * Suggestion boards UI removed from this build; keep hide-sg CSS hook when permission hides suggestions.
 */
async function processSuggestionBoards() {
    if (multicollabRolePermissions.hide_suggestion === "1") {
        document.body.classList.add("hide-sg");
        const iframe = cfGetIframe();
        if (iframe) {
            iframe.contentDocument?.body.classList.add('hide-sg');
        }
    }
}

/**
 * Process comment boards
 */
async function processCommentBoards(commentBoardIds, currentPostID, currentUserID, commentNode, selecteBoardId, allThreads) {
    return new Promise((resolve, reject) => {
        if (commentBoardIds.length === 0) {
            resolve();
            return;
        }

        if (multicollabRolePermissions.hide_comment === "1") {
            document.body.classList.add("hide-comments");
            const iframe = cfGetIframe();
            if(iframe) {
                iframe.contentDocument?.body.classList.add('hide-comments');
            }
            resolve();
            return;
        }

        const cacheCommentBoardIds = select('mdstore').getFetchedCommentCache();
        
        if (cacheCommentBoardIds && 
            typeof cacheCommentBoardIds === "object" && 
            Object.keys(cacheCommentBoardIds).length > 0) {
            // Render from cache - no loader needed
            renderCommentBoardsFromCache(commentBoardIds, commentNode, selecteBoardId, allThreads);
            resolve();
        } else {
            // Show loader and fetch using unified loading state
            updateLoadingState('comments', true, commentNode);
            
            fetchBoardsInChunks(commentBoardIds, currentPostID, currentUserID, 50)
                .then(() => {
                    renderCommentBoardsFromCache(commentBoardIds, commentNode, selecteBoardId, allThreads);
                    updateLoadingState('comments', false, commentNode);
                    resolve();
                })
                .catch((err) => {
                    console.error("❌ Failed to fetch comment boards:", err);
                    updateLoadingState('comments', false, commentNode);
                    reject(err);
                });
        }
    });
}

/**
 * Handle URL navigation and focus
 */
function handleUrlNavigation(current_url, allThreads, urlParams, iframeDocument) {
    if (current_url && !allThreads.includes(current_url)) {
        const noticeMsg = __("The comment you are trying to access has been closed!", "commenting-feature");
        showNotice(noticeMsg);

        urlParams.delete("current_url");
        window.history.replaceState({}, "", `${location.pathname}?${urlParams}`);
    } else {
        document.querySelectorAll(".js-activity-centre .user-data-row").forEach(row => row.classList.remove("active"));

        if (current_url) {
            let blockElemet;
            if (iframeDocument) {
                // Select elements within the iframe document
                var elementsWithDataText = iframeDocument.querySelectorAll('[data-rich-text-format-boundary="true"]');
                elementsWithDataText.forEach(function(element) {
                    element.removeAttribute('data-rich-text-format-boundary');
                });
            } else {
                // Select elements in the main document
                var elementsWithDataText = document.querySelectorAll('[data-rich-text-format-boundary="true"]');
                elementsWithDataText.forEach(function(element) {
                    element.removeAttribute('data-rich-text-format-boundary');
                });
            }
            
            let referenceElementURL;
            const iframe = cfGetIframe();
            
            if (current_url.startsWith("el")) {
                if(iframeDocument) {
                    referenceElementURL = iframeDocument.querySelector(`[datatext="${current_url}"]`);
                } else {
                    referenceElementURL = document.querySelector(`[datatext="${current_url}"]`);
                }
            } else if (current_url.startsWith("sg")) {
                displaySuggestionBoards();
                document.querySelector(".suggestion-toggle .components-form-toggle")?.classList.remove("is-checked");
                const sid = current_url.replace('sg', '');
                
                if(iframe && iframeDocument) {
                    iframe.contentDocument?.body.classList.remove('hide-sg');
                    referenceElementURL = iframeDocument.getElementById(sid);
                } else {
                    document.body.classList.remove("hide-sg");
                    referenceElementURL = document.getElementById(sid);
                }

                if(!referenceElementURL) {
                    cfgetCustomAttribute().forEach((attrValue) => {
                        if(iframeDocument) {
                            if (!referenceElementURL && iframeDocument.querySelector(`[${attrValue}="${sid}"]`)) {
                                referenceElementURL = iframeDocument.querySelector(`[${attrValue}="${sid}"]`);
                                blockElemet = iframeDocument.querySelector(`[data-suggestion_id="${sid}"]`);
                                if (blockElemet) {
                                    blockElemet.classList.add('focus');
                                }
                            }
                        } else {
                            if (!referenceElementURL && document.querySelector(`[${attrValue}="${sid}"]`)) {
                                referenceElementURL = document.querySelector(`[${attrValue}="${sid}"]`);
                                blockElemet = document.querySelector(`[data-suggestion_id="${sid}"]`);
                                if (blockElemet) {
                                    blockElemet.classList.add('focus');
                                }
                            }
                        }
                    });
                }
            }

            document.querySelectorAll("#cf-comment-board-wrapper .cls-board-outer").forEach(el => el.style.opacity = "0.4");
            const focusedElement = document.querySelector(`#cf-comment-board-wrapper .cls-board-outer#${current_url}`);
            if (focusedElement) {
                focusedElement.classList.add("focus", "is-open");
                focusedElement.style.opacity = "1";
                focusedElement.style.top = `25px`;
            }

            if(referenceElementURL) {
                referenceElementURL.scrollIntoView({
                    behavior: "smooth",
                    block: "start"
                });
                referenceElementURL?.setAttribute('data-rich-text-format-boundary', 'true');
            }

            document.querySelector(`#${current_url} .cf-share-comment`)?.focus();

            urlParams.delete("current_url");
            window.history.replaceState({}, "", `${location.pathname}?${urlParams}`);
        }
    }
}

/**
 * Setup loading monitor
 */
function setupLoadingMonitor() {
    let loadAttempts = 0;
    const loadComments = setInterval(() => {
        let openBoards;
        if (multicollabRolePermissions.hide_suggestion !== "1" && multicollabRolePermissions.hide_comment === "1") {
            openBoards = document.querySelectorAll(".cls-board-outer.sg-board").length;
        } else if (multicollabRolePermissions.hide_comment !== "1" && multicollabRolePermissions.hide_suggestion === "1") {
            openBoards = document.querySelectorAll(".cls-board-outer.cm-board").length;
        } else {
            openBoards = document.querySelectorAll(".cls-board-outer").length;
        }

        if (openBoards === 0) {
            const event = new Event("editorLayoutUpdate");
            document.dispatchEvent(event);
        }

        loadAttempts++;
        if (document.querySelectorAll("#cf-comment-board-wrapper .commentContainer").length >= 1 || loadAttempts >= 10) {
            clearInterval(loadComments);
            document.getElementById("history-toggle")?.setAttribute("data-count", openBoards);
        }
    }, 1000);
}

/**
 * Updates awareness state for board activities with controlled sync
 */
const updateAwarenessForBoardActivity = (activity, data = {}) => {
    const isRealTime = select("core/editor").getEditedPostAttribute("meta")?._is_real_time_mode;
    
    if (isRealTime) {
        const postId = select("core/editor").getCurrentPostId();
        
        // Try to get the awareness instance from the global instances map
        if (window.multicollabInstances && window.multicollabInstances.has(postId)) {
            const instance = window.multicollabInstances.get(postId);
            
            if (instance && instance.provider && instance.provider.awareness) {
                // Update awareness state with board activity
                const activityData = {
                    type: activity,
                    timestamp: Date.now(),
                    data: data
                };
                
                instance.provider.awareness.setLocalStateField("boardActivity", activityData);
                
                // Clear the activity after a short delay
                setTimeout(() => {
                    instance.provider.awareness.setLocalStateField("boardActivity", null);
                }, 2000);
            }
        }
    }
};

/**
 * Send real-time notification to other users about comment changes
 */
const sendRealtimeNotification = (boardId, action, username) => {
    const isRealTime = select("core/editor").getEditedPostAttribute("meta")?._is_real_time_mode;
    if (!isRealTime) {
        return;
    }
    
    const postId = select("core/editor").getCurrentPostId();
    
    // Try to get the awareness instance from the global instances map
    if (window.multicollabInstances && window.multicollabInstances.has(postId)) {
        const instance = window.multicollabInstances.get(postId);
        
        if (instance && instance.provider && instance.provider.awareness) {
            // Send notification to other users
            const notificationData = {
                type: `comment_${action}`,
                boardId: boardId,
                username: username,
                timestamp: Date.now(),
                source: 'realtime_notification'
            };
            
            try {
                instance.provider.awareness.setLocalStateField("commentNotification", notificationData);
                
                // Clear notification after a short delay
                setTimeout(() => {
                    try {
                        instance.provider.awareness.setLocalStateField("commentNotification", null);
                    } catch (clearError) {
                        console.error('[Real-time Notification] Error clearing notification:', clearError);
                    }
                }, 3000);
                
            } catch (sendError) {
                console.error('[Real-time Notification] Error sending notification:', sendError);
            }
        }
    }
};



// Track ongoing syncs to prevent duplicates
const ongoingSyncs = new Set();
// Track last sync time for each board to prevent rapid re-syncs
const lastSyncTime = new Map();
// Cooldown period in milliseconds (2 seconds)
const SYNC_COOLDOWN = 2000;

/**
 * Enhanced real-time comment sync function for immediate updates
 */
const syncCommentImmediately = async (boardId, action, username, isRemoteSync = false) => {
    const isRealTime = select("core/editor").getEditedPostAttribute("meta")?._is_real_time_mode;
    if (!isRealTime) {
        return;
    }
    
    // Check if this board is already being synced
    const syncKey = `${boardId}-${action}-${username}`;
    if (ongoingSyncs.has(syncKey)) {
        return;
    }
    
    // Check cooldown period
    const now = Date.now();
    const lastSync = lastSyncTime.get(boardId);
    if (lastSync && (now - lastSync) < SYNC_COOLDOWN) {
        return;
    }
    
    // Mark this sync as ongoing and update last sync time
    ongoingSyncs.add(syncKey);
    lastSyncTime.set(boardId, now);
    
    const postId = select("core/editor").getCurrentPostId();
    const currentUserID = select("core").getCurrentUser()?.id;
    
    try {
        // Fetch fresh data immediately
        const response = await fetchChunkWithRetry([boardId], postId, currentUserID, 3);
        
        // Update cache with fresh data
        for (const [boardIdKey, data] of Object.entries(response)) {
            const cacheKey = `${postId}-${boardIdKey}`;
            dispatch('mdstore').setFetchedCommentCache(cacheKey, data);
        }
        
        // Find existing board element
        const existingBoard = document.querySelector(`#${boardId}`);
        
        if (existingBoard) {
            // Use advanced sync that preserves position and attributes based on user type
            await syncBoardWithPositionPreservation(boardId, existingBoard, action, username, isRemoteSync);
        } else {
            const commentNode = document.getElementById("cf-comment-board-wrapper");
            const allThreads = [];
            setBoardIdByValue(boardId);
            if (!commentNode) {
                const sidebar = wp.data.select("core/edit-post").getActiveGeneralSidebarName();

                if (sidebar === null) {
                    // Open sidebar if comment node doesn't exist
                    dispatch("core/edit-post").openGeneralSidebar("edit-post/cf-collab-sidebar");
                    // Wait a bit for sidebar to open, then try again
                    setTimeout(() => {
                        const newCommentNode = document.getElementById("cf-comment-board-wrapper");
                        if (newCommentNode) {
                            renderCommentBoardsFromCache([boardId], newCommentNode, null, allThreads);
                        }
                    }, 500);
                }
                
            } else {
                renderCommentBoardsFromCache([boardId], commentNode, null, allThreads);
            }
        }
    } catch (error) {
        console.error(`[Real-time Sync] Failed to sync comment for board ${boardId}:`, error);
        // Fallback to refresh
        setRefreshCount(prev => prev + 1);
    } finally {
        // Remove from ongoing syncs
        ongoingSyncs.delete(syncKey);
    }
};

/**
 * Sync board with fresh data (preserve styles based on user type)
 */
const syncBoardWithPositionPreservation = async (boardId, existingBoard, action, username, isRemoteUser = false) => {
    // Preserve board position and attributes
    const preservedAttributes = {
        style: existingBoard.style.cssText,
        className: existingBoard.className,
        dataset: { ...existingBoard.dataset },
        position: existingBoard.offsetTop,
        parent: existingBoard.parentNode,
        nextSibling: existingBoard.nextSibling,
        rect: existingBoard.getBoundingClientRect()
    };
    
    // Remove existing board for re-render
    existingBoard.remove();
    
    // Re-render with fresh data immediately
    const commentNode = document.getElementById("cf-comment-board-wrapper");
    if (commentNode) {
        const allThreads = [];
        renderCommentBoardsFromCache([boardId], commentNode, null, allThreads);
        
        // Restore board position and attributes based on user type
        const restoreAttributes = () => {
            const newBoard = document.querySelector(`#${boardId}`);
            if (newBoard) {
                // Restore style and position
                newBoard.style.cssText = preservedAttributes.style;
                newBoard.className = preservedAttributes.className;
                
                // Restore dataset attributes
                Object.keys(preservedAttributes.dataset).forEach(key => {
                    newBoard.dataset[key] = preservedAttributes.dataset[key];
                });
                
                if (isRemoteUser) {
                    // For remote users: Remove top and position styles
                    newBoard.style.removeProperty('top');
                    newBoard.style.removeProperty('position');
                } else {
                    // For local user: Restore position more accurately
                    if (preservedAttributes.position !== newBoard.offsetTop) {
                        newBoard.style.top = `${preservedAttributes.position}px`;
                        newBoard.style.position = 'absolute';
                    }
                    
                    // Ensure the board stays in the same visual position
                    if (preservedAttributes.rect) {
                        const currentRect = newBoard.getBoundingClientRect();
                        if (Math.abs(currentRect.top - preservedAttributes.rect.top) > 5) {
                            newBoard.style.top = `${preservedAttributes.rect.top}px`;
                        }
                    }
                }
            }
        };
        
        // Try to restore immediately, then again after a short delay
        restoreAttributes();
        setTimeout(restoreAttributes, 50);
        setTimeout(restoreAttributes, 200);
        
        // Send real-time notification to other users (only for local user)
        if (!isRemoteUser) {
            sendRealtimeNotification(boardId, action, username);
        }
    }
};




/**
 * Shows visual indicator for user activity on boards
 */

const showUserActivityIndicator = (username, boardId, activityType) => {
    // Create or update activity indicator
    let indicator = document.getElementById('multicollab-activity-indicator');
    if (!indicator) {
        indicator = document.createElement('div');
        indicator.id = 'multicollab-activity-indicator';
        indicator.style.cssText = `
            position: fixed;
            top: 20px;
            right: 20px;
            background:#f6f4fc;
            color: #002954;
            padding: 10px 15px;
            border-radius: 5px;
            z-index: 9999;
            font-size: 14px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.2);
            border-left: 4px solid #4b1bce;
            transition: opacity 0.3s ease;
        `;
        document.body.appendChild(indicator);
    }
    
    // Update indicator content based on activity type
    let activityText;
    switch (activityType) {
        case 'selected':
            activityText = 'viewing';
            break;
        case 'added':
            activityText = 'added a comment to';
            break;
        case 'edited':
            activityText = 'edited a comment in';
            break;
        case 'deleted':
            activityText = 'deleted a comment from';
            break;
        default:
            activityText = 'working on';
    }
    
    indicator.textContent = `${username} ${activityText} board`;
    indicator.style.opacity = '1';
    
    // Hide indicator after 3 seconds
    setTimeout(() => {
        indicator.style.opacity = '0';
        setTimeout(() => {
            if (indicator.parentNode) {
                indicator.parentNode.removeChild(indicator);
            }
        }, 300);
    }, 3000);
};
/**
 * Main CommentBoards component with optimized parallel processing
 */
function CommentBoards(selectedID = null, refreshCount = 0) {
    
    let selecteBoardId = selectedID['selectedId'];
    if(selecteBoardId && selecteBoardId.includes('sg')) {
        selecteBoardId = selecteBoardId.replace('sg', '');
    }

    useEffect(() => {
        const iframe = cfGetIframe();
        const iframeDocument = iframe ? iframe.contentWindow.document : null;
        const parentNode = document.getElementById("cf-comments-suggestions-parent");

        const isRealTimeCheck = select("core/editor").getEditedPostAttribute("meta")?._is_real_time_mode;
        const isBoardFocus = parentNode?.querySelector('.comment-focus');
        const isBoardEditFocus = parentNode?.querySelector('.cls-board-outer.focus .commentEdit');

        if((isBoardFocus || isBoardEditFocus) && isRealTimeCheck) {
            return;
        }

        if (parentNode) {
            parentNode.innerHTML = "";
        }
        if (!parentNode) {
            const parentNode = document.createElement("div");
            parentNode.id = "cf-comments-suggestions-parent";
            referenceNode.appendChild(parentNode);
        }

        const commentNode = document.createElement("div");
        commentNode.id = "cf-comment-board-wrapper";
        parentNode.appendChild(commentNode);

        showNoticeBoardonNewComments();

        const queryString = window.location.search;
        const urlParams = new URLSearchParams(queryString);
        let current_url = urlParams.get("current_url");

        const isPostLock = select("core/editor")?.isPostLocked();
        if (isPostLock && current_url) {
            setCookie("current_url", current_url, 5);
        }

        const shareUrl = getCookie("current_url");
        if (shareUrl) {
            current_url = shareUrl;
        }

        const getContent = select('core/editor').getEditedPostAttribute('content') || '';
        // Create a DOM parser
        const parser = new DOMParser();
        // Parse the content string into a DOM document
        const domContent = parser.parseFromString(getContent, 'text/html');

        let selectedNontextblock = wp.data.select('mdstore').getBoardIds();

                    // Set selected ID at the first position if available
            if (selecteBoardId && selectedNontextblock.includes(selecteBoardId)) {
                selectedNontextblock = [selecteBoardId, ...selectedNontextblock.filter(id => id !== selecteBoardId)];
                
                // Track board selection
                updateAwarenessForBoardActivity('board_selected', {
                    boardId: selecteBoardId,
                    boardType: selecteBoardId.startsWith('el') ? 'comment' : 'suggestion'
                });
            }

        const commentBoardIds = [];
        const suggestionBoardIds = [];

        selectedNontextblock.forEach(id => {
            if (id.startsWith('el')) {
                commentBoardIds.push(id);
            } else {
                suggestionBoardIds.push(id);
            }
        });

        const currentPostID = select("core/editor").getCurrentPostId();
        const currentUserID = select("core").getCurrentUser()?.id ?? null;

        let suggestionHistory = select("core/editor")
            ?.getEditedPostAttribute("meta")?._sb_suggestion_history;

        suggestionHistory = suggestionHistory ? JSON.parse(suggestionHistory) : {};

        const span_count = domContent.querySelectorAll("mdspan").length;
        const nontext_count = selectedNontextblock.length;
        const suggestion_count = domContent.querySelectorAll(".mdadded, .mdmodified, .mdremoved").length;

        if (span_count === 0 && nontext_count === 0 && suggestion_count === 0) {
            const editPostVisualEditor = document.querySelector(".commentOn .edit-post-visual-editor");
            if (editPostVisualEditor) {
                editPostVisualEditor.style.width = "100%";
            }
            const event = new Event("editorLayoutUpdate");
            document.dispatchEvent(event);

            updateAutodraftIds("");

            // Track when no boards are available
            updateAwarenessForBoardActivity('no_boards_available', {
                spanCount: span_count,
                nontextCount: nontext_count,
                suggestionCount: suggestion_count
            });

            if (current_url) {
                const noticeMsg = __("The comment you are trying to access has been closed!", "commenting-feature");
                showNotice(noticeMsg);

                urlParams.delete("current_url");
                window.history.replaceState({}, "", `${location.pathname}?${urlParams}`);
            }
        } else {
            const event = new Event("editorLayoutUpdate");
            document.dispatchEvent(event);
            document.body.classList.add("commentOn");

            const allThreads = [];

            // Reset loading state before starting new render cycle
            resetLoadingState();

            // Process both board types in parallel using Promise.all
            Promise.all([
                processSuggestionBoards(),
                processCommentBoards(commentBoardIds, currentPostID, currentUserID, commentNode, selecteBoardId, allThreads)
            ]).then(() => {
                // Handle completion of both processes
                updateAutodraftIds(allThreads);
                handleUrlNavigation(current_url, allThreads, urlParams, iframeDocument);
                setupLoadingMonitor();
                
                // Track board loading completion
                updateAwarenessForBoardActivity('boards_loaded', {
                    commentBoards: commentBoardIds.length,
                    suggestionBoards: suggestionBoardIds.length,
                    totalBoards: allThreads.length
                });
            }).catch((error) => {
                console.error("Error processing boards:", error);
                // Fallback handling
                updateAutodraftIds(allThreads);
                setupLoadingMonitor();
                
                // Track board loading error
                updateAwarenessForBoardActivity('boards_load_error', {
                    error: error.message
                });
            });
        }

        // Clear the selected board ID value
        wp.data.dispatch('core/editor').editPost({
            meta: {
                'cfBoardSelectedID': '',
            },
        });
        
       

    }, [refreshCount]);
}

/**
 * Renders the Collab sidebar.
 */
export default function CollabSidebar() {
    const selectedId = wp.data.select("core/editor").getEditedPostAttribute("meta")?.cfBoardSelectedID || '';
    const [refreshCount, setRefreshCount] = useState(0);
    
    // Track sidebar open/close state and comment changes
    useEffect(() => {
        const updateSidebarState = () => {
            const isRealTime = select("core/editor").getEditedPostAttribute("meta")?._is_real_time_mode;
            if (isRealTime) {
                const postId = select("core/editor").getCurrentPostId();
                
                if (window.multicollabInstances && window.multicollabInstances.has(postId)) {
                    const instance = window.multicollabInstances.get(postId);
                    if (instance && instance.provider && instance.provider.awareness) {
                        const sidebarElement = document.querySelector('.cf-editor-collab-sidebar');
                        const isVisible = sidebarElement && !sidebarElement.classList.contains('is-closed');
                        
                        // Only update if state actually changed
                        const currentState = instance.provider.awareness.getLocalState();
                        if (!currentState.sidebarState || currentState.sidebarState.isOpen !== isVisible) {
                            instance.provider.awareness.setLocalStateField("sidebarState", {
                                isOpen: isVisible,
                                timestamp: Date.now(),
                                action: isVisible ? 'opened' : 'closed'
                            });
                        }
                    }
                }
            }
        };
        
        // Update on mount
        updateSidebarState();
        
        // Listen for sidebar state changes
        const observer = new MutationObserver(updateSidebarState);
        const sidebarElement = document.querySelector('.cf-editor-collab-sidebar');
        if (sidebarElement) {
            observer.observe(sidebarElement, { 
                attributes: true, 
                attributeFilter: ['class'] 
            });
        }
        
        // Dynamic board activity detection with proper controls
        const detectBoardActivities = () => {
            // Check if real-time mode is enabled
            const isRealTime = select("core/editor").getEditedPostAttribute("meta")?._is_real_time_mode;
            if (!isRealTime) {
                return; // Stop monitoring if real-time mode is disabled
            }
            
            // Track board selection changes (only if changed)
            const selectedBoard = document.querySelector('#cf-comment-board-wrapper .cls-board-outer.focus');
            if (selectedBoard && selectedBoard.id !== window.lastSelectedBoard) {
                window.lastSelectedBoard = selectedBoard.id;
                updateAwarenessForBoardActivity('board_selected', {
                    boardId: selectedBoard.id,
                    boardType: selectedBoard.id.startsWith('el') ? 'comment' : 'suggestion'
                });
            }
            
            // Track board loading state (only if changed)
            const loadingBoards = document.querySelectorAll('#cf-comment-board-wrapper .cls-board-outer');
            const loadedCount = loadingBoards.length;
            if (loadedCount !== window.lastBoardCount) {
                window.lastBoardCount = loadedCount;
                if (loadedCount > 0) {
                    updateAwarenessForBoardActivity('boards_loaded', {
                        totalBoards: loadedCount,
                        commentBoards: document.querySelectorAll('#cf-comment-board-wrapper .cls-board-outer.cm-board').length,
                        suggestionBoards: document.querySelectorAll('#cf-comment-board-wrapper .cls-board-outer.sg-board').length
                    });
                } else {
                    updateAwarenessForBoardActivity('no_boards_available');
                }
            }
        };
        
        // Comment changes are now tracked directly in board.js functions
        // No need for DOM-based detection since we track actual user actions
        
        // Set up comment change monitoring with proper controls
        const commentObserver = new MutationObserver((mutations) => {
            // Check if real-time mode is enabled
            const isRealTime = select("core/editor").getEditedPostAttribute("meta")?._is_real_time_mode;
            if (!isRealTime) {
                return; // Stop monitoring if real-time mode is disabled
            }
            
            mutations.forEach((mutation) => {
                if (mutation.type === 'childList' || mutation.type === 'attributes') {
                    // Debounce the detection to avoid multiple rapid calls
                    clearTimeout(window.commentChangeTimeout);
                    window.commentChangeTimeout = setTimeout(detectCommentChanges, 500);
                }
            });
        });
        
        // Start monitoring comment changes only if real-time mode is enabled
        const commentWrapper = document.querySelector('#cf-comment-board-wrapper');
        if (commentWrapper) {
            commentObserver.observe(commentWrapper, {
                childList: true,
                subtree: true,
                attributes: true,
                attributeFilter: ['data-tracked', 'data-edited', 'data-deleted']
            });
        }
        
        // Set up periodic monitoring for dynamic activities with proper controls
        let activityMonitor = null;
        const startActivityMonitoring = () => {
            const isRealTime = select("core/editor").getEditedPostAttribute("meta")?._is_real_time_mode;
            if (isRealTime && !activityMonitor) {
                activityMonitor = setInterval(() => {
                    detectBoardActivities();
                }, 5000); // Check every 5 seconds instead of 2 seconds
            }
        };
        
        const stopActivityMonitoring = () => {
            if (activityMonitor) {
                clearInterval(activityMonitor);
                activityMonitor = null;
            }
        };
        

        
        // Start monitoring initially
        startActivityMonitoring();
        
        // Initial detection
        setTimeout(() => {
            detectBoardActivities();
        }, 1000);
        
        // Monitor real-time mode changes
        const handleRealtimeModeChange = () => {
            const isRealTime = select("core/editor").getEditedPostAttribute("meta")?._is_real_time_mode;
            if (isRealTime) {
                startActivityMonitoring();
            } else {
                stopActivityMonitoring();
            }
        };
        
        // Listen for real-time mode changes
        const realtimeModeObserver = new MutationObserver(() => {
            handleRealtimeModeChange();
        });
        
        // Observe the meta field for real-time mode changes
        const metaField = document.querySelector('meta[name="real-time-mode"]');
        if (metaField) {
            realtimeModeObserver.observe(metaField, { attributes: true });
        }
        
        // AJAX monitoring removed - comment tracking is now handled directly in board.js functions
        
        // Comment board sync is now handled by handleRealtimeNotification
        // This ensures proper remote sync handling and avoids duplicate processing
        
        // Track user interactions dynamically
        const trackUserInteraction = (interaction, data = {}) => {
            const isRealTime = select("core/editor").getEditedPostAttribute("meta")?._is_real_time_mode;
            if (isRealTime) {
                updateAwarenessForBoardActivity(interaction, {
                    timestamp: Date.now(),
                    ...data
                });
            }
        };
        
        // Listen for real-time board activities from other users (non-comment activities only)
        const handleBoardActivity = (event) => {
            const { type, data, userId, username, timestamp } = event.detail;
            
            // Get current user to check if this is a remote notification
            const currentUser = select("core").getCurrentUser();
            const isRemoteUser = currentUser && (username !== currentUser.name && username !== (currentUser.display_name ?? ""));
            
            // Only handle non-comment activities to avoid duplication with handleRealtimeNotification
            if (type === 'board_selected') {
                // Only show activity indicator for remote users
                if (isRemoteUser) {
                    showUserActivityIndicator(username, data.boardId, 'selected');
                }
            }
            
            // Comment activities (added, edited, deleted) are handled by handleRealtimeNotification
            // to avoid duplicate processing and ensure proper remote sync handling
        };
        
        // Listen for real-time sidebar state changes from other users
        const handleSidebarState = (event) => {
            const { isOpen, username } = event.detail;
        };
        
        // Track notification debouncing
        const notificationDebounce = new Map();
        
        // Listen for real-time comment notifications from other users
        const handleRealtimeNotification = () => {
            const isRealTime = select("core/editor").getEditedPostAttribute("meta")?._is_real_time_mode;
            if (!isRealTime) {
                return;
            }
            
            const postId = select("core/editor").getCurrentPostId();
            
            // Function to setup awareness listener with improved retry logic
            const setupAwarenessListener = (retryCount = 0) => {
                const maxRetries = 5;
                const retryDelays = [1000, 2000, 3000, 5000, 8000]; // Progressive delays
                
                // Check if multicollab instances are available
                if (!window.multicollabInstances) {
                    if (retryCount < maxRetries) {
                        setTimeout(() => {
                            setupAwarenessListener(retryCount + 1);
                        }, retryDelays[retryCount] || 2000);
                    }
                    return false;
                }
                
                // Check if the specific post instance exists
                if (!window.multicollabInstances.has(postId)) {
                    if (retryCount < maxRetries) {
                        setTimeout(() => {
                            setupAwarenessListener(retryCount + 1);
                        }, retryDelays[retryCount] || 2000);
                    }
                    return false;
                }
                
                const instance = window.multicollabInstances.get(postId);
                
                // Check if instance has provider and awareness
                if (!instance || !instance.provider || !instance.provider.awareness) {
                    if (retryCount < maxRetries) {
                        setTimeout(() => {
                            setupAwarenessListener(retryCount + 1);
                        }, retryDelays[retryCount] || 2000);
                    }
                    return false;
                }
                
                // Setup awareness listener
                instance.provider.awareness.on('change', (changes) => {
                    // Get all awareness states to check for comment notifications
                    const states = instance.provider.awareness.getStates();
                    
                    // Check each client's state for comment notifications
                    states.forEach((state, clientId) => {
                        // Check for board activity notifications (from updateAwarenessForBoardActivity)
                        if (state && state.boardActivity && state.boardActivity.type && state.boardActivity.type.startsWith('comment_')) {
                            const activity = state.boardActivity;
                            
                            const { type, data } = activity;
                            const boardId = data?.boardId;
                            const username = state.username;
                            
                            if (boardId && username) {
                                // Get current user to check if this is a remote notification
                                const currentUser = select("core").getCurrentUser();
                                const isRemoteUser = currentUser && (username !== currentUser.name && username !== (currentUser.display_name ?? ""));
                                
                                if (type === 'comment_added' || type === 'comment_edited' || type === 'comment_deleted') {
                                    // Only process for remote users (not the user who made the change)
                                    if (isRemoteUser) {
                                        // Extract action from type (remove 'comment_' prefix)
                                        const action = type.replace('comment_', '');
                                        
                                        // Create debounce key
                                        const debounceKey = `${boardId}-${type}-${username}`;
                                        
                                        // Clear existing timeout
                                        if (notificationDebounce.has(debounceKey)) {
                                            clearTimeout(notificationDebounce.get(debounceKey));
                                        }
                                        
                                        // Set new timeout for debounced processing
                                        const timeoutId = setTimeout(() => {
                                            // Check if board is still in cooldown
                                            const now = Date.now();
                                            const lastSync = lastSyncTime.get(boardId);
                                            if (lastSync && (now - lastSync) < SYNC_COOLDOWN) {
                                                notificationDebounce.delete(debounceKey);
                                                return;
                                            }
                                            
                                            // Handle deleted comments - check if it's a reply deletion or entire board deletion
                                            if (action === 'deleted') {
                                                // Check if this is a reply deletion (board still has other comments) or entire board deletion
                                                // For now, we'll sync the board to get the updated data and let the sync logic handle it
                                                // This ensures we get the correct state after the deletion
                                                syncCommentImmediately(boardId, action, username, true)
                                                    .then(() => {
                                                        showUserActivityIndicator(username, boardId, action);
                                                        setTimeout(() => {
                                                            // Check if the board is now empty and should be removed
                                                            const updatedBoard = document.querySelector(`#${boardId}`);
                                                            if (updatedBoard) {
                                                                // Check if the board has any content (comments/replies)
                                                                const hasContent = updatedBoard.querySelector('.commentContainer');
                                                                if (!hasContent) {
                                                                    updatedBoard.remove();
                                                                }
                                                            }
                                                        }, 500);
                                                    })
                                                    .catch((error) => {
                                                        console.error(`[Real-time Notification] Failed to sync board ${boardId} after deletion:`, error);
                                                    })
                                                    .finally(() => {
                                                        // Remove from debounce map
                                                        notificationDebounce.delete(debounceKey);
                                                    });
                                            } else {
                                                // Sync the board with fresh data (remote user only) for added/edited comments
                                                syncCommentImmediately(boardId, action, username, true)
                                                    .then(() => {
                                                        showUserActivityIndicator(username, boardId, action);
                                                    })
                                                    .catch((error) => {
                                                        console.error(`[Real-time Notification] Failed to sync board ${boardId}:`, error);
                                                    })
                                                    .finally(() => {
                                                        // Remove from debounce map
                                                        notificationDebounce.delete(debounceKey);
                                                    });
                                            }
                                        }, 1000); // Increased to 1000ms debounce delay
                                        
                                        // Store timeout ID
                                        notificationDebounce.set(debounceKey, timeoutId);
                                    }
                                }
                            }
                        }
                    });
                });
                
                return true;
            };
            
            // Start the setup process
            setupAwarenessListener();
        };
        
        // Add event listeners
        document.addEventListener('multicollab-board-activity', handleBoardActivity);
        document.addEventListener('multicollab-sidebar-state', handleSidebarState);
        
        // Start listening for real-time notifications
        handleRealtimeNotification();
        

        

        
        return () => {
            observer.disconnect();
            commentObserver.disconnect();
            realtimeModeObserver.disconnect();
            stopActivityMonitoring();
            clearTimeout(window.commentChangeTimeout);
            
            // Clear all debounced notifications
            notificationDebounce.forEach((timeoutId) => {
                clearTimeout(timeoutId);
            });
            notificationDebounce.clear();
            
            // Clear ongoing syncs and last sync times
            ongoingSyncs.clear();
            lastSyncTime.clear();
            
            document.removeEventListener('multicollab-board-activity', handleBoardActivity);
            document.removeEventListener('multicollab-sidebar-state', handleSidebarState);
        };
    }, []);
    
    return (
        <>
            <PluginSidebar
                //isPinnable={ false }
                header={false}
                identifier="edit-post/cf-collab-sidebar"
                className="cf-editor-collab-sidebar"
                headerClassName="cf-editor-collab-sidebar__header"
            >
                <div id="cf-comments-suggestions-parent">
                    <CommentBoards selectedId={selectedId} refreshCount={refreshCount} />
                </div>
            </PluginSidebar>
        </>
    );
}

registerPlugin("cf-collab-sidebar", {
    icon: null,
    render: CollabSidebar,
});