// js/dock_logic.js
(function DockLogic(global) { // 传入 window
    // --- DOM Elements ---
    let dockElement = null;
    let progressPercentageSpan = null; // For collapsed display
    let progressPercentageVerboseSpan = null; // For expanded display
    let highlightCountElement = null;
    let annotationCountElement = null;
    let imageCountElement = null;
    let tableCountElement = null;
    let formulaCountElement = null;
    let totalWordCountElement = null;
    let dockToggleBtn = null;
    let settingsLink = null;

    // --- State ---
    let currentDocId = null;
    let currentVisibleTabIdForDock = null; // ADDED: To store current tab for dock logic
    let isContentLoadingForStats = false; // NEW: Flag to indicate if stats are pending full content
    let dockDisplayConfig = {
        readingProgress: true,
        highlights: true,
        annotations: true,
        images: true,
        tables: true,
        formulas: true,
        words: true
    };

    // Helper function to get the current scrollable element
    function getCurrentScrollableElement() {
        if (global.ImmersiveLayout && global.ImmersiveLayout.isActive()) {
            // 沉浸模式：滚动容器取决于当前活动的标签页
            const immersiveMainArea = document.getElementById('immersive-main-content-area');
            if (immersiveMainArea) {
                // 1. 优先查找带有内联样式的 .tab-content
                const tabContentScroller = immersiveMainArea.querySelector('.tab-content[style*="overflow-y: auto"], .tab-content[style*="overflow: auto"]');
                if (tabContentScroller) {
                    console.log("[DockLogic] 找到带内联样式的滚动容器:", tabContentScroller.className);
                    return tabContentScroller;
                }

                // 2. 查找活动的内容包装器
                const activeTabContent = immersiveMainArea.querySelector('.tab-content .content-wrapper, .tab-content .chunk-compare-container');
                if (activeTabContent) {
                    // 检查父元素 .tab-content 是否可滚动
                    const tabContentParent = activeTabContent.closest('.tab-content');
                    if (tabContentParent && (tabContentParent.style.overflowY === 'auto' ||
                                           tabContentParent.style.overflow === 'auto' ||
                                           getComputedStyle(tabContentParent).overflowY === 'auto')) {
                        console.log("[DockLogic] 找到可滚动的 .tab-content 父元素");
                        return tabContentParent;
                    }
                    // 回退到内容包装器本身
                    console.log("[DockLogic] 回退到内容包装器:", activeTabContent.className);
                    return activeTabContent;
                }

                // 3. 尝试 .container
                const mainContainerInImmersive = immersiveMainArea.querySelector('.container');
                if (mainContainerInImmersive) {
                    console.log("[DockLogic] 找到 .container");
                    return mainContainerInImmersive;
                }

                // 4. 最后回退到 immersiveMainArea
                console.log("[DockLogic] 使用兜底方案：immersiveMainArea");
                return immersiveMainArea;
            }
        }

        // 非沉浸模式：使用 .app-main（侧边栏布局中的主内容区）
        const appMain = document.querySelector('.app-main');
        if (appMain) {
            console.log("[DockLogic] 非沉浸模式，使用 .app-main");
            return appMain;
        }

        // 最终回退到 document.documentElement（旧布局或特殊情况）
        console.log("[DockLogic] 最终回退到 document.documentElement");
        return document.documentElement;
    }

    // --- 新增：动态绑定/解绑 scroll 事件 ---
    let lastScrollableElement = null;
    function bindScrollForCurrentScrollable() {
        // 解绑旧的
        if (lastScrollableElement) {
            lastScrollableElement.removeEventListener('scroll', debouncedUpdateReadingProgress);
            lastScrollableElement = null;
        }
        // 获取当前滚动元素
        const el = getCurrentScrollableElement();
        if (el) {
            console.log(`[DockLogic] 绑定滚动事件到元素:`, el.id || el.className || el.tagName);
            el.addEventListener('scroll', debouncedUpdateReadingProgress);
            lastScrollableElement = el;

            // 立即更新一次阅读进度，确保显示正确
            setTimeout(() => _updateReadingProgress(), 50);
        } else {
            console.warn(`[DockLogic] 未找到可滚动元素，无法绑定滚动事件`);
        }
    }
    function unbindScrollForCurrentScrollable() {
        if (lastScrollableElement) {
            lastScrollableElement.removeEventListener('scroll', debouncedUpdateReadingProgress);
            lastScrollableElement = null;
        }
    }

    function debounce(func, delay) {
        let timeout;
        return function(...args) {
            const context = this;
            clearTimeout(timeout);
            timeout = setTimeout(() => func.apply(context, args), delay);
        };
    }

    function _updateReadingProgress() {
        if (!progressPercentageSpan || !progressPercentageVerboseSpan || !dockElement) {
            // console.warn("Dock progress elements not ready for updateReadingProgress");
            return;
        }

        const scrollableElement = getCurrentScrollableElement();

        const scrollTop = scrollableElement.scrollTop;
        const scrollHeight = scrollableElement.scrollHeight;
        const clientHeight = scrollableElement.clientHeight;

        if (scrollHeight <= clientHeight) { // Content fits viewport, no scrollbar
            progressPercentageSpan.textContent = '100';
            progressPercentageVerboseSpan.textContent = '100';
            dockElement.classList.add('visible');
            return;
        }

        const maxScrollTop = scrollHeight - clientHeight;
        const scrollFraction = maxScrollTop > 0 ? (scrollTop / maxScrollTop) : 0;
        const percentage = Math.min(100, Math.max(0, Math.round(scrollFraction * 100)));

        progressPercentageSpan.textContent = percentage;
        progressPercentageVerboseSpan.textContent = percentage;
        dockElement.classList.add('visible');
    }
    // Expose debounced version for scroll event
    const debouncedUpdateReadingProgress = debounce(_updateReadingProgress, 100);


    function _updateHighlightSummary(docData) {
      if (highlightCountElement && docData && Array.isArray(docData.annotations)) {
        const count = docData.annotations.filter(ann => ann.highlightColor).length;
        highlightCountElement.textContent = count;
      } else if (highlightCountElement) {
        highlightCountElement.textContent = '0';
      }
    }

    function _updateAnnotationSummary(docData) {
      if (annotationCountElement && docData && Array.isArray(docData.annotations)) {
        const count = docData.annotations.filter(ann =>
          ann.body && ann.body.length > 0 && ann.body[0].value && ann.body[0].value.trim() !== '' && ann.motivation === 'commenting'
        ).length;
        annotationCountElement.textContent = count;
      } else if (annotationCountElement) {
        annotationCountElement.textContent = '0';
      }
    }

    function _updateImageCount(docData) {
      if (imageCountElement && docData && docData.images) {
        imageCountElement.textContent = docData.images.length;
      } else if (imageCountElement) {
        imageCountElement.textContent = '0';
      }
    }

    function _updateTableCount(contentElement) {
      if (tableCountElement && contentElement) {
        // If content is still loading (indicated by flag and element having no direct children yet), show placeholder.
        if (isContentLoadingForStats && contentElement.children.length === 0) {
            tableCountElement.textContent = '...';
        } else {
            const tables = contentElement.getElementsByTagName('table');
            tableCountElement.textContent = tables.length;
        }
      } else if (tableCountElement) {
        tableCountElement.textContent = '0'; // Default if no contentElement
      }
    }

    function _updateFormulaCount(contentElement) {
      if (formulaCountElement && contentElement) {
        if (isContentLoadingForStats && contentElement.children.length === 0) {
            formulaCountElement.textContent = '...';
        } else {
            const katexElements = contentElement.querySelectorAll('.katex, .katex-display');
            const mermaidElements = contentElement.querySelectorAll('.mermaid > svg'); // Mermaid renders an SVG
            formulaCountElement.textContent = katexElements.length + mermaidElements.length;
        }
      } else if (formulaCountElement) {
        formulaCountElement.textContent = '0';
      }
    }

    function _updateWordCount(contentElement) {
      if (totalWordCountElement && contentElement) {
        // Using a heuristic: if content is flagged as loading and text is very short or non-existent
        if (isContentLoadingForStats && (!contentElement.textContent || contentElement.textContent.trim().length < 10)) {
            totalWordCountElement.textContent = '...';
        } else {
            const text = contentElement.textContent || contentElement.innerText || "";
            const charCount = text.replace(/\\s/g, '').length; // Count non-whitespace characters
            totalWordCountElement.textContent = charCount > 0 ? charCount : '0';
        }
      } else if (totalWordCountElement) {
        totalWordCountElement.textContent = '0';
      }
    }

    /**
     * Updates all statistics displayed in the dock.
     * @param {Object} docData - The main data object for the current document.
     * @param {string} currentVisibleTabId - The ID of the currently visible tab (e.g., 'ocr', 'translation').
     */
    function _updateAllDockStats(docData, currentVisibleTabId) {
      currentVisibleTabIdForDock = currentVisibleTabId;

      if (!docData) {
        // console.warn("Doc data not available for updating dock stats.");
        if(highlightCountElement) highlightCountElement.textContent = '0';
        if(annotationCountElement) annotationCountElement.textContent = '0';
        if(imageCountElement) imageCountElement.textContent = '0';
        if(tableCountElement) tableCountElement.textContent = '0';
        if(formulaCountElement) formulaCountElement.textContent = '0';
        if(totalWordCountElement) totalWordCountElement.textContent = '0';
        isContentLoadingForStats = false; // No data, so not "loading stats"
        _applyDisplayConfigToElements();
        return;
      }

      let activeContentElement = null;
      if (currentVisibleTabIdForDock === 'ocr' && document.getElementById('ocr-content-wrapper')) {
        activeContentElement = document.getElementById('ocr-content-wrapper');
      } else if (currentVisibleTabIdForDock === 'translation' && document.getElementById('translation-content-wrapper')) {
        activeContentElement = document.getElementById('translation-content-wrapper');
      }

      // Set loading flag if activeContentElement exists but seems empty (initial batch render ongoing)
      if (activeContentElement && activeContentElement.children.length === 0) {
          isContentLoadingForStats = true;
          // console.log("DockLogic: Content is loading, placeholder '...' may be shown for some stats.");
      } else {
          isContentLoadingForStats = false; // Content is present or not an OCR/Translation tab needing batch render
          // console.log("DockLogic: Content present or not OCR/Trans, proceeding with normal stat calculation.");
      }

      // Handle highlights and annotations based on tab (these don't typically show '...')
      if (currentVisibleTabIdForDock === 'chunk-compare') {
        if (highlightCountElement) highlightCountElement.textContent = '0';
        if (annotationCountElement) annotationCountElement.textContent = '0';
        // These will be hidden by _applyDisplayConfigToElements's override for chunk-compare
      } else {
        // OCR or Translation tabs: update based on config and data
        if (dockDisplayConfig.highlights) _updateHighlightSummary(docData);
        if (dockDisplayConfig.annotations) _updateAnnotationSummary(docData);
      }

      // Handle images (always based on docData, visibility by config + override)
      if (dockDisplayConfig.images) {
        _updateImageCount(docData);
      }

      // Stats dependent on activeContentElement (tables, formulas, words)
      if (activeContentElement) { // OCR or Translation content is active
        if (dockDisplayConfig.tables) _updateTableCount(activeContentElement);
        if (dockDisplayConfig.formulas) _updateFormulaCount(activeContentElement);
        if (dockDisplayConfig.words) _updateWordCount(activeContentElement);
      } else { // No active OCR/Translation content (e.g., chunk-compare or error state)
        if (tableCountElement) tableCountElement.textContent = '0';
        if (formulaCountElement) formulaCountElement.textContent = '0';
        if (totalWordCountElement) totalWordCountElement.textContent = '0';

        // If it's not chunk-compare and no active element, but we previously thought content was loading for stats
        // ensure placeholders are shown if this update call happens too early.
        if (currentVisibleTabIdForDock !== 'chunk-compare' && isContentLoadingForStats) {
            if (tableCountElement && dockDisplayConfig.tables) tableCountElement.textContent = '...';
            if (formulaCountElement && dockDisplayConfig.formulas) formulaCountElement.textContent = '...';
            if (totalWordCountElement && dockDisplayConfig.words) totalWordCountElement.textContent = '...';
        }
      }

      _applyDisplayConfigToElements();

      // Fallback: If stats were showing '...' and are still '...' after a delay, revert to '0'.
      // This handles cases where the final, definitive update from history_detail might be missed or severely delayed for large docs.
      if (isContentLoadingForStats) { // Only set this timeout if we actually entered a "loading stats" state
          setTimeout(() => {
              // Check if we are still in a loading state for these stats
              // This inner check of isContentLoadingForStats is important because a proper update
              // might have occurred in the meantime, clearing the flag.
              if (isContentLoadingForStats) {
                  // console.log("DockLogic: Fallback timeout executed. Converting '...' to '0' if still present.");
                  if (tableCountElement && tableCountElement.textContent === '...' && dockDisplayConfig.tables) tableCountElement.textContent = '0';
                  if (formulaCountElement && formulaCountElement.textContent === '...' && dockDisplayConfig.formulas) formulaCountElement.textContent = '0';
                  if (totalWordCountElement && totalWordCountElement.textContent === '...' && dockDisplayConfig.words) totalWordCountElement.textContent = '0';
                  // It's probably safe to assume loading is "done" from the fallback's perspective,
                  // but a subsequent call to _updateAllDockStats with full content will properly clear it.
              }
          }, 3000); // Adjust delay as needed, e.g., 3 seconds.
      }
    }

    /**
     * Applies the current display configuration to the DOM elements.
     * Overrides highlights and annotations to be hidden if in 'chunk-compare' mode.
     */
    function _applyDisplayConfigToElements() {
        const elementsMap = {
            readingProgress: [progressPercentageVerboseSpan, progressPercentageSpan],
            highlights: [highlightCountElement],
            annotations: [annotationCountElement],
            images: [imageCountElement],
            tables: [tableCountElement],
            formulas: [formulaCountElement],
            words: [totalWordCountElement]
        };

        const wrapperSelectors = {
            readingProgress: '.dock-stat-item-wrapper-progress',
            highlights: '.dock-stat-item-wrapper-highlight',
            annotations: '.dock-stat-item-wrapper-annotation',
            images: '.dock-stat-item-wrapper-img',
            tables: '.dock-stat-item-wrapper-tbl',
            formulas: '.dock-stat-item-wrapper-formula',
            words: '.dock-stat-item-wrapper-words'
        };

        for (const key in dockDisplayConfig) {
            let originalShouldShow = dockDisplayConfig[key];
            let effectiveShouldShow = originalShouldShow;

            if (currentVisibleTabIdForDock === 'chunk-compare') {
                if (key === 'readingProgress') {
                    effectiveShouldShow = dockDisplayConfig.readingProgress;
                } else {
                    effectiveShouldShow = false;
                }
            }

            const shouldShow = effectiveShouldShow;
            const wrapperSelector = wrapperSelectors[key];
            // const statElements = elementsMap[key]; // Not directly used if relying on wrapperSelector

            if (wrapperSelector) {
                let wrapperEl = null;
                if (key === 'readingProgress') {
                    const verboseWrapper = progressPercentageVerboseSpan ? progressPercentageVerboseSpan.closest(wrapperSelector) : null;
                    const collapsedDisplay = document.getElementById('dock-collapsed-progress-display');
                    if (verboseWrapper) verboseWrapper.style.display = shouldShow ? '' : 'none';
                    if (collapsedDisplay) collapsedDisplay.style.display = shouldShow ? '' : 'none';
                } else if (elementsMap[key] && elementsMap[key][0]) { // Use the first element in the map to find its wrapper
                     wrapperEl = elementsMap[key][0].closest(wrapperSelector);
                     if (wrapperEl) {
                        wrapperEl.style.display = shouldShow ? '' : 'none';
                     }
                }
            } else if (elementsMap[key]) {
                elementsMap[key].forEach(el => {
                    if(el) el.style.display = shouldShow ? '' : 'none';
                });
            }
        }
    }

    /**
     * Initializes the Dock component.
     * Caches DOM elements, restores toggle state, and attaches event listeners.
     * @param {string} docId - The ID of the current document.
     */
    function initialize(docId) {
        currentDocId = docId;
        currentVisibleTabIdForDock = null;

        dockElement = document.getElementById('bottom-left-dock');
        progressPercentageSpan = document.getElementById('reading-progress-percentage');
        progressPercentageVerboseSpan = document.getElementById('reading-progress-percentage-verbose');
        highlightCountElement = document.getElementById('highlight-count');
        annotationCountElement = document.getElementById('annotation-count');
        imageCountElement = document.getElementById('image-count');
        tableCountElement = document.getElementById('table-count');
        formulaCountElement = document.getElementById('formula-count');
        totalWordCountElement = document.getElementById('total-word-count');
        dockToggleBtn = document.getElementById('dock-toggle-btn');
        settingsLink = document.getElementById('settings-link');

        // 参考文献计数元素（可选）
        const referenceCountElement = document.getElementById('reference-count');

        if (!dockElement || !progressPercentageSpan || !progressPercentageVerboseSpan ||
            !highlightCountElement || !annotationCountElement || !imageCountElement ||
            !tableCountElement || !formulaCountElement || !totalWordCountElement ||
            !dockToggleBtn || !settingsLink) {
            console.error("DockLogic: One or more Dock UI elements not found during initialization.");
            return;
        }

        if (global.DockLogic && global.DockLogic.loadDisplayConfig) {
            global.DockLogic.loadDisplayConfig();
        }

        _updateReadingProgress();
        _applyDisplayConfigToElements();

        const dockCollapsedKey = `dockCollapsed_${currentDocId}`;
        const isCollapsed = localStorage.getItem(dockCollapsedKey) === 'true';
        if (isCollapsed) {
            dockElement.classList.add('dock-collapsed');
            dockToggleBtn.innerHTML = '<i class="fa fa-chevron-up"></i>';
            dockToggleBtn.title = '展开';
        } else {
            dockElement.classList.remove('dock-collapsed');
            dockToggleBtn.innerHTML = '<i class="fa fa-chevron-down"></i>';
            dockToggleBtn.title = '折叠';
        }

        dockToggleBtn.onclick = function(event) {
            event.preventDefault();
            const currentlyCollapsed = dockElement.classList.toggle('dock-collapsed');
            if (currentlyCollapsed) {
                this.innerHTML = '<i class="fa fa-chevron-up"></i>';
                this.title = '展开';
                localStorage.setItem(dockCollapsedKey, 'true');
            } else {
                this.innerHTML = '<i class="fa fa-chevron-down"></i>';
                this.title = '折叠';
                localStorage.setItem(dockCollapsedKey, 'false');
            }
        };

        global.removeEventListener('scroll', debouncedUpdateReadingProgress);
        global.addEventListener('scroll', debouncedUpdateReadingProgress);
        // 新增：自动绑定到当前滚动容器
        bindScrollForCurrentScrollable();

        const highlightStatClickable = dockElement.querySelector('.dock-stat-item-wrapper-highlight .stat-item-clickable[data-stat-type="highlight"]');
        const annotationStatClickable = dockElement.querySelector('.dock-stat-item-wrapper-annotation .stat-item-clickable[data-stat-type="annotation"]');

        if (highlightStatClickable) {
            highlightStatClickable.addEventListener('click', function() {
                if (typeof global.openAnnotationsSummaryModal === 'function') {
                    global.openAnnotationsSummaryModal('all', 'all');
                } else {
                    console.warn('openAnnotationsSummaryModal function not found on window.');
                }
            });
        }

        if (annotationStatClickable) {
            annotationStatClickable.addEventListener('click', function() {
                if (typeof global.openAnnotationsSummaryModal === 'function') {
                    global.openAnnotationsSummaryModal('all', 'all');
                } else {
                    console.warn('openAnnotationsSummaryModal function not found on window.');
                }
            });
        }
    }

    // Expose public interface
    global.DockLogic = {
        init: initialize,
        updateStats: _updateAllDockStats,
        forceUpdateReadingProgress: function() {
            // 增加延迟，确保DOM结构已更新
            setTimeout(() => {
                console.log("[DockLogic] 强制更新阅读进度");
                _updateReadingProgress();
                bindScrollForCurrentScrollable(); // 每次强制刷新后也重新绑定
            }, 200); // 增加延迟时间
        },
        updateDisplayConfig: function(newConfig) {
            if (typeof newConfig === 'object' && newConfig !== null) {
                for (const key in dockDisplayConfig) {
                    if (newConfig.hasOwnProperty(key) && typeof newConfig[key] === 'boolean') {
                        dockDisplayConfig[key] = newConfig[key];
                    }
                }
                _applyDisplayConfigToElements();
                if (currentDocId) {
                     localStorage.setItem(`dockDisplayConfig_${currentDocId}`, JSON.stringify(dockDisplayConfig));
                } else {
                     localStorage.setItem('dockDisplayConfig_global', JSON.stringify(dockDisplayConfig));
                }
            }
        },
        loadDisplayConfig: function() {
            let savedConfig = null;
            if (currentDocId) {
                savedConfig = localStorage.getItem(`dockDisplayConfig_${currentDocId}`);
            }
            if (!savedConfig) {
                savedConfig = localStorage.getItem('dockDisplayConfig_global');
            }

            if (savedConfig) {
                try {
                    const parsedConfig = JSON.parse(savedConfig);
                    dockDisplayConfig = { ...dockDisplayConfig, ...parsedConfig };
                } catch (e) {
                    console.error("Error parsing saved dock display config:", e);
                }
            }
            // _applyDisplayConfigToElements(); // This might be called too early if DOM elements for stats are not ready
                                          // It's better called within init after elements are cached,
                                          // and also after any _updateAllDockStats call.
        },
        getCurrentDisplayConfig: function() {
            return { ...dockDisplayConfig };
        },
        bindScrollForCurrentScrollable,
        unbindScrollForCurrentScrollable
    };

})(window);