import * as TableManager from '../core/table-system/manager.js';
import { log } from '../core/table-system/logger.js';
import { extension_settings, getContext } from '/scripts/extensions.js';
import { extensionName } from '../utils/settings.js';
import { updateOrInsertTableInChat } from './message-table-renderer.js';
import { saveSettingsDebounced } from '/script.js';
import { startBatchFilling } from '../core/table-system/batch-filler.js';
import { resetSecondaryFillerLock, isSecondaryFillerRunning, abortCurrentSecondaryFiller } from '../core/table-system/secondary-filler.js';
import { showHtmlModal } from './page-window.js';
import { DEFAULT_AI_RULE_TEMPLATE, DEFAULT_AI_FLOW_TEMPLATE } from '../core/table-system/settings.js';
import { world_names, loadWorldInfo } from '/scripts/world-info.js';
import { safeCharLorebooks, safeLorebookEntries } from '../core/tavernhelper-compatibility.js';
import { characters, this_chid, eventSource, event_types } from "/script.js";
import { fetchNccsModels, testNccsApiConnection } from '../core/api/NccsApi.js';
import { showGraphVisualization } from '../core/relationship-graph/visualizer.js';
import { escapeHTML } from '../utils/utils.js';
import { configManager } from '../utils/config/ConfigManager.js';
import { ruleProfileManager } from '../utils/config/RuleProfileManager.js';
import { bindTableTemplateEditors } from './table/template-bindings.js';
import { bindNccsApiEvents as bindNccsApiSettingsEvents } from './table/nccs-bindings.js';
import { bindChatTableDisplaySetting as bindChatTableDisplaySettings } from './table/chat-display-bindings.js';

const isTouchDevice = () => window.matchMedia('(pointer: coarse)').matches;
const getAllTablesContainer = () => document.getElementById('all-tables-container');

/**
 * 通用：填充规则配置下拉选单
 * @param {HTMLSelectElement} select
 * @param {string} slot — RULE_SLOTS 中的功能槽名
 */
function _populateRuleProfileSelect(select, slot, detail) {
    const profiles = detail?.profiles ?? ruleProfileManager.listProfiles();
    const assigned = detail?.assignments?.[slot] ?? ruleProfileManager.getAssignment(slot) ?? '';
    const options = [
        '<option value="">— 未分配 —</option>',
        ...profiles.map(p =>
            `<option value="${p.id}" ${p.id === assigned ? 'selected' : ''}>${escapeHTML(p.name || p.id)}</option>`
        ),
    ];
    select.innerHTML = options.join('');
}

function getLiveExtensionSettings() {
    if (!extension_settings[extensionName]) {
        extension_settings[extensionName] = {};
    }

    return extension_settings[extensionName];
}

function isTableSystemEnabled() {
    return getLiveExtensionSettings().table_system_enabled !== false;
}

let isResizing = false;
let activeTableIndex = 0; // 【V155.0】当前激活的表格索引


function toggleRowContextMenu(event) {
    event.preventDefault();
    event.stopPropagation();

    const targetTd = event.target.closest('td.index-col');
    if (!targetTd) return;

    const tableWrapper = targetTd.closest('.amily2-table-wrapper');
    if (!tableWrapper) return;

    const isActive = targetTd.classList.contains('amily2-menu-open');
    document.querySelectorAll('.amily2-menu-open').forEach(openEl => {
        if (openEl !== targetTd) {
            openEl.classList.remove('amily2-menu-open');
            openEl.style.zIndex = '';
            openEl.style.position = '';
            const otherWrapper = openEl.closest('.amily2-table-wrapper');
            if (otherWrapper) {
                otherWrapper.style.overflowX = 'auto';
                otherWrapper.style.zIndex = '';
                otherWrapper.style.position = '';
            }
        }
    });

    targetTd.classList.toggle('amily2-menu-open');

    if (targetTd.classList.contains('amily2-menu-open')) {
        tableWrapper.style.overflowX = 'visible';
        tableWrapper.style.position = 'relative';
        tableWrapper.style.zIndex = '10';
        targetTd.style.position = 'relative';
        targetTd.style.zIndex = '100';
    } else {
        tableWrapper.style.overflowX = 'auto';
        tableWrapper.style.position = '';
        tableWrapper.style.zIndex = '';
        targetTd.style.position = '';
        targetTd.style.zIndex = '';
    }

    const closeMenu = (e) => {
        if (!targetTd.contains(e.target)) {
            targetTd.classList.remove('amily2-menu-open');
            targetTd.style.position = '';
            targetTd.style.zIndex = '';
            tableWrapper.style.overflowX = 'auto';
            tableWrapper.style.position = '';
            tableWrapper.style.zIndex = '';
            document.removeEventListener('click', closeMenu, true);
        }
    };

    if (targetTd.classList.contains('amily2-menu-open')) {
        setTimeout(() => {
            document.addEventListener('click', closeMenu, true);
        }, 0);
    }
}


function toggleColumnContextMenu(event) {
    if (isResizing || event.target.classList.contains('amily2-resizer')) {
        return;
    }
    event.preventDefault();
    event.stopPropagation();

    const targetTh = event.target.closest('th');
    if (!targetTh) return;

    const tableWrapper = targetTh.closest('.amily2-table-wrapper');
    if (!tableWrapper) return;

    const isActive = targetTh.classList.contains('amily2-menu-open');

    document.querySelectorAll('th.amily2-menu-open').forEach(openTh => {
        if (openTh !== targetTh) {
            openTh.classList.remove('amily2-menu-open');
            const otherWrapper = openTh.closest('.amily2-table-wrapper');
            if (otherWrapper) {
                otherWrapper.style.overflowX = 'auto';
                otherWrapper.style.zIndex = '';
                otherWrapper.style.position = '';
            }
        }
    });

    targetTh.classList.toggle('amily2-menu-open');

    if (targetTh.classList.contains('amily2-menu-open')) {
        tableWrapper.style.overflowX = 'visible';
        tableWrapper.style.position = 'relative'; 
        tableWrapper.style.zIndex = '10';
    } else {
        tableWrapper.style.overflowX = 'auto';
        tableWrapper.style.position = '';
        tableWrapper.style.zIndex = '';
    }

    const closeMenu = (e) => {
        if (!targetTh.contains(e.target)) {
            targetTh.classList.remove('amily2-menu-open');
            tableWrapper.style.overflowX = 'auto';
            tableWrapper.style.position = '';
            tableWrapper.style.zIndex = '';
            document.removeEventListener('click', closeMenu, true);
        }
    };

    if (targetTh.classList.contains('amily2-menu-open')) {
        setTimeout(() => {
            document.addEventListener('click', closeMenu, true);
        }, 0);
    }
}


function toggleHeaderIndexContextMenu(event) {
    event.preventDefault();
    event.stopPropagation();

    const targetTh = event.target.closest('th.index-col');
    if (!targetTh) return;

    const menu = targetTh.querySelector('.amily2-context-menu');
    if (!menu) return;

    const isActive = menu.classList.contains('amily2-menu-active');

    document.querySelectorAll('.amily2-context-menu.amily2-menu-active').forEach(activeMenu => {
        activeMenu.classList.remove('amily2-menu-active');
    });

    if (!isActive) {
        menu.classList.add('amily2-menu-active');
    }

    const closeMenu = (e) => {
        if (!menu.contains(e.target)) {
            menu.classList.remove('amily2-menu-active');
            document.removeEventListener('click', closeMenu, true);
        }
    };

    setTimeout(() => {
        if (menu.classList.contains('amily2-menu-active')) {
            document.addEventListener('click', closeMenu, true);
        }
    }, 0);
}


function showInputDialog({ title, label, currentValue, placeholder, onSave }) {
    const dialogHtml = `
        <dialog class="popup custom-input-dialog">
            <div class="popup-body">
                <h4 style="margin-top:0; color: #e0e0e0; border-bottom: 1px solid rgba(255,255,255,0.2); padding-bottom: 10px; display: flex; align-items: center; gap: 8px;">
                    <i class="fas fa-edit" style="color: #9e8aff;"></i> ${escapeHTML(title)}
                </h4>
                <div class="popup-content" style="padding: 20px 10px;">
                    <div style="display: flex; flex-direction: column; gap: 12px;">
                        <label style="color: #ccc; font-weight: bold;">${escapeHTML(label)}</label>
                        <input type="text" id="generic-input" class="text_pole" 
                               value="${escapeHTML(currentValue)}" 
                               style="padding: 10px; border-radius: 6px; border: 1px solid rgba(255,255,255,0.3); background: rgba(0,0,0,0.2); color: #fff; font-size: 1em;"
                               placeholder="${escapeHTML(placeholder)}">
                        <small style="color: #aaa; font-style: italic;">提示：输入内容将用于更新项目。</small>
                    </div>
                </div>
                <div class="popup-controls" style="display: flex; gap: 10px; justify-content: flex-end; padding-top: 15px; border-top: 1px solid rgba(255,255,255,0.1);">
                    <div class="popup-button-cancel menu_button interactable" style="background: rgba(120,120,120,0.2); border-color: rgba(120,120,120,0.4);">
                        <i class="fas fa-times"></i> 取消
                    </div>
                    <div class="popup-button-ok menu_button menu_button_primary interactable" style="background: rgba(158,138,255,0.3); border-color: rgba(158,138,255,0.6);">
                        <i class="fas fa-check"></i> 确认
                    </div>
                </div>
            </div>
        </dialog>`;

    const dialogElement = $(dialogHtml).appendTo('body');
    const input = dialogElement.find('#generic-input');

    const closeDialog = () => {
        dialogElement[0].close();
        dialogElement.remove();
    };

    const save = () => {
        const newValue = input.val().trim();
        if (newValue && newValue !== currentValue) {
            onSave(newValue);
        } else if (!newValue) {
            toastr.warning('名称不能为空！');
            input.focus();
            return;
        }
        closeDialog();
    };

    dialogElement.find('.popup-button-ok').on('click', save);
    dialogElement.find('.popup-button-cancel').on('click', closeDialog);
    input.on('keypress', (e) => { if (e.which === 13) save(); });
    input.on('keydown', (e) => { if (e.which === 27) closeDialog(); });

    dialogElement[0].showModal();
    input.focus().select();
}


function showColumnNameEditor(tableIndex, colIndex, currentName) {
    showInputDialog({
        title: '编辑列名',
        label: '列名：',
        currentValue: currentName,
        placeholder: '请输入列名...',
        onSave: (newName) => {
            TableManager.updateHeader(tableIndex, colIndex, newName);
            renderTables();
            toastr.success(`列名已更新为 "${newName}"`);
        }
    });
}


function showTableNameEditor(tableIndex, currentName) {
    showInputDialog({
        title: '编辑表名',
        label: '表名：',
        currentValue: currentName,
        placeholder: '请输入表名...',
        onSave: (newName) => {
            TableManager.renameTable(tableIndex, newName);
            renderTables();
            toastr.success(`表名已更新为 "${newName}"`);
        }
    });
}


function positionContextMenu(menu, trigger) {
    menu.style.position = 'absolute';
    menu.style.zIndex = '10000';
    menu.style.left = '0';
    menu.style.right = 'auto';
    menu.style.marginTop = '';
    menu.style.marginBottom = '';
    menu.style.maxHeight = '';
    menu.style.overflowY = '';

    const viewportHeight = window.innerHeight;
    const triggerRect = trigger.getBoundingClientRect();
    const menuHeight = 200; 
    const scrollContainer = trigger.closest('.hly-scroll');
    const containerRect = scrollContainer ? scrollContainer.getBoundingClientRect() : { top: 0, bottom: viewportHeight };

    const spaceBelow = Math.min(viewportHeight, containerRect.bottom) - triggerRect.bottom;
    const spaceAbove = triggerRect.top - Math.max(0, containerRect.top);

    if (spaceBelow < menuHeight && spaceAbove > spaceBelow) {
        menu.style.top = 'auto';
        menu.style.bottom = '100%';
        menu.style.marginBottom = '2px';
    } else {
        menu.style.top = '100%';
        menu.style.bottom = 'auto';
        menu.style.marginTop = '2px';
    }

    const menuWidth = 160;
    const table = trigger.closest('table');
    const tableWrapper = table ? table.closest('div[style*="overflowX"]') : null;
    
    if (tableWrapper) {
        const wrapperRect = tableWrapper.getBoundingClientRect();
        const triggerLeftInWrapper = triggerRect.left - wrapperRect.left;

        if (triggerLeftInWrapper + menuWidth > wrapperRect.width - 20) {
            menu.style.left = 'auto';
            menu.style.right = '0';
        }
    }
}


export function renderTables() {
    let tables = TableManager.getMemoryState();
    if (!tables) {
        log('内存状态为空，从聊天记录加载作为后备。', 'warn');
        tables = TableManager.loadTables();
    }
    
    const container = getAllTablesContainer();

    if (!tables || !container) {
        console.error('[内存储司-工部] 缺少表格数据或容器，无法渲染。');
        return;
    }

    // 【V155.0】验证 activeTableIndex
    if (activeTableIndex >= tables.length) {
        activeTableIndex = Math.max(0, tables.length - 1);
    }

    const highlights = TableManager.getHighlights();
    const updatedTables = TableManager.getUpdatedTables();
    const fragment = document.createDocumentFragment();

    // 【V155.1 移动端适配】注入样式
    if (!document.getElementById('amily2-table-tabs-style')) {
        const style = document.createElement('style');
        style.id = 'amily2-table-tabs-style';
        style.textContent = `
            .amily2-table-tabs {
                display: flex;
                overflow-x: auto;
                gap: 8px;
                margin-bottom: 10px;
                padding-bottom: 8px;
                border-bottom: 1px solid rgba(255,255,255,0.1);
                align-items: center;
                -webkit-overflow-scrolling: touch; /* iOS 平滑滚动 */
                scrollbar-width: none; /* Firefox 隐藏滚动条 */
            }
            .amily2-table-tabs::-webkit-scrollbar {
                display: none; /* Chrome/Safari 隐藏滚动条 */
            }
            .amily2-table-tabs .menu_button {
                flex-shrink: 0; /* 防止标签被压缩 */
                white-space: nowrap;
            }
            /* 移动端表头适配 */
            @media (max-width: 768px) {
                .amily2-table-header-container {
                    flex-wrap: wrap;
                    gap: 8px;
                }
                .amily2-table-header-container h3 {
                    width: 100%;
                    margin-bottom: 5px;
                }
                .amily2-table-header-container .table-controls {
                    width: 100%;
                    justify-content: space-between;
                }
                .amily2-table-header-container .table-controls .menu_button {
                    flex: 1;
                    justify-content: center;
                }
            }
        `;
        document.head.appendChild(style);
    }

    // 1. 渲染标签页 (Tabs)
    const tabsContainer = document.createElement('div');
    tabsContainer.className = 'amily2-table-tabs';
    // 移除内联样式，改用上方注入的 CSS 类
    // tabsContainer.style.cssText = ... 

    tables.forEach((table, index) => {
        const tab = document.createElement('button');
        tab.className = `menu_button small_button ${index === activeTableIndex ? 'active' : ''}`;
        tab.style.whiteSpace = 'nowrap';
        
        // 高亮当前标签
        if (index === activeTableIndex) {
            tab.style.backgroundColor = 'rgba(158, 138, 255, 0.4)';
            tab.style.borderColor = 'rgba(158, 138, 255, 0.8)';
            tab.style.boxShadow = '0 0 8px rgba(158, 138, 255, 0.3)';
        }
        
        // 如果表格有更新，添加标记
        if (updatedTables.has(index)) {
            tab.innerHTML = `${escapeHTML(table.name)} <span style="color: #87CEFA; font-size: 1.2em; line-height: 0;">•</span>`;
        } else {
            tab.textContent = table.name;
        }

        tab.onclick = () => {
            activeTableIndex = index;
            renderTables();
        };
        tabsContainer.appendChild(tab);
    });

    // 添加“新建表格”按钮到标签栏
    const addBtn = document.createElement('button');
    addBtn.className = 'menu_button small_button';
    addBtn.innerHTML = '<i class="fas fa-plus"></i>';
    addBtn.title = '新建表格';
    addBtn.style.marginLeft = '5px';
    addBtn.onclick = () => {
        const newName = prompt('请输入新表格的名称：', '新表格');
        if (newName && newName.trim()) {
            TableManager.addTable(newName.trim());
            // 切换到新创建的表格
            const newTables = TableManager.getMemoryState();
            activeTableIndex = newTables.length - 1;
            renderTables();
        }
    };
    tabsContainer.appendChild(addBtn);

    fragment.appendChild(tabsContainer);

    // 2. 渲染当前激活的表格 (Active Table)
    if (tables.length > 0 && tables[activeTableIndex]) {
        const tableIndex = activeTableIndex;
        const tableData = tables[tableIndex];

        const header = document.createElement('div');
        header.className = 'amily2-table-header-container';
        const title = document.createElement('h3');
        if (updatedTables.has(tableIndex)) {
            title.classList.add('table-updated'); 
        }
        title.innerHTML = `<i class="fas fa-table table-rename-icon" data-table-index="${tableIndex}" title="重命名"></i> ${escapeHTML(tableData.name)}`;
        const controls = document.createElement('div');
        controls.className = 'table-controls';

        // 左右移动表格（原上下移动）
        // 【移动端优化】增加按钮的触摸区域和间距
        const moveLeftBtn = tableIndex > 0 ? `<button class="menu_button small_button move-table-up-btn" data-table-index="${tableIndex}" title="向左移动标签"><i class="fas fa-arrow-left"></i></button>` : '';
        const moveRightBtn = tableIndex < tables.length - 1 ? `<button class="menu_button small_button move-table-down-btn" data-table-index="${tableIndex}" title="向右移动标签"><i class="fas fa-arrow-right"></i></button>` : '';

        controls.innerHTML = `
            ${moveLeftBtn}
            ${moveRightBtn}
            <button class="menu_button small_button edit-rules-btn" data-table-index="${tableIndex}" title="编辑规则"><i class="fa-solid fa-scroll"></i></button>
            <button class="menu_button small_button danger delete-table-btn" data-table-index="${tableIndex}" title="废黜此表"><i class="fas fa-trash-alt"></i></button>
        `;
        header.appendChild(title);
        header.appendChild(controls);
        fragment.appendChild(header);

        const tableWrapper = document.createElement('div');
        tableWrapper.className = 'amily2-table-wrapper';

        const tableElement = document.createElement('table');
        tableElement.id = `amily2-table-${tableIndex}`;
        tableElement.dataset.tableIndex = tableIndex;

        const colgroup = document.createElement('colgroup');
        const indexCol = document.createElement('col');
        indexCol.style.width = '40px';
        colgroup.appendChild(indexCol);

        if (tableData.headers) {
            tableData.headers.forEach((_, colIndex) => {
                const col = document.createElement('col');
                const colWidth = (tableData.columnWidths && tableData.columnWidths[colIndex]) ? tableData.columnWidths[colIndex] : 90;
                col.style.width = `${colWidth}px`;
                colgroup.appendChild(col);
            });
        }
        tableElement.appendChild(colgroup);

        let totalWidth = 0;
        const cols = colgroup.querySelectorAll('col');
        cols.forEach(col => {
            totalWidth += parseInt(col.style.width, 10);
        });
        tableElement.style.minWidth = '100%';
        if (totalWidth > 0) {
             tableElement.style.width = `${Math.max(totalWidth, 0)}px`;
             tableElement.style.minWidth = `${totalWidth}px`;
             tableElement.style.width = '100%';
        }

        const thead = tableElement.createTHead();
        const headerRow = thead.insertRow();
        
        const indexTh = document.createElement('th');
        indexTh.className = 'index-col';
        indexTh.textContent = '#';
        indexTh.style.cursor = 'pointer';
        indexTh.title = '点击添加第一行';

        if (!tableData.rows || tableData.rows.length === 0) {
            const headerMenu = document.createElement('div');
            headerMenu.className = 'amily2-context-menu amily2-header-menu';
            headerMenu.style.display = 'none';  // 默认隐藏
            
            const addRowButton = document.createElement('button');
            addRowButton.innerHTML = '<i class="fas fa-plus-circle"></i> 创建第一行';
            addRowButton.className = 'menu_button small_button';
            addRowButton.addEventListener('click', (e) => {
                e.stopPropagation();
                TableManager.addRow(tableIndex);
                renderTables();
            });
            
            headerMenu.appendChild(addRowButton);
            indexTh.appendChild(headerMenu);
            
            indexTh.addEventListener('click', (e) => {
                e.preventDefault();
                e.stopPropagation();
                console.log('Header # clicked for table', tableIndex);

                TableManager.addRow(tableIndex);
                renderTables();
                toastr.success('已添加第一行');
            });
        }
        
        headerRow.appendChild(indexTh);

        tableData.headers.forEach((headerText, colIndex) => {
            const th = document.createElement('th');
            th.dataset.colIndex = colIndex;
            th.style.cursor = 'pointer';

            const headerContent = document.createElement('span');
            headerContent.className = 'amily2-header-text';
            headerContent.textContent = headerText; // textContent is safe
            th.appendChild(headerContent);

            const menu = document.createElement('div');
            menu.className = 'amily2-context-menu';

            const actions = [
                { label: '向左移动', action: 'move-left', icon: 'fa-arrow-left' },
                { label: '向右移动', action: 'move-right', icon: 'fa-arrow-right' },
                { label: '在左加列', action: 'add-left', icon: 'fa-plus-circle' },
                { label: '在右加列', action: 'add-right', icon: 'fa-plus-circle' },
                { label: '编辑列名', action: 'rename', icon: 'fa-pen' },
                { label: '删除该列', action: 'delete', icon: 'fa-trash-alt', isDanger: true }
            ];

            actions.forEach(({ label, action, icon, isDanger }) => {
                const button = document.createElement('button');
                button.textContent = label;
                button.className = 'menu_button small_button';
                if (isDanger) button.classList.add('danger');
                
                button.addEventListener('click', (e) => {
                    e.stopPropagation();
                    switch (action) {
                        case 'move-left':
                            TableManager.moveColumn(tableIndex, colIndex, 'left');
                            break;
                        case 'move-right':
                            TableManager.moveColumn(tableIndex, colIndex, 'right');
                            break;
                        case 'add-left':
                            TableManager.insertColumn(tableIndex, colIndex, 'left');
                            break;
                        case 'add-right':
                            TableManager.insertColumn(tableIndex, colIndex, 'right');
                            break;
                        case 'rename':
                            showColumnNameEditor(tableIndex, colIndex, headerText);
                            break;
                        case 'delete':
                            if (confirm(`您确定要删除 “${headerText}” 列吗？`)) {
                                TableManager.deleteColumn(tableIndex, colIndex);
                            }
                            break;
                    }
                    renderTables(); 
                });
                menu.appendChild(button);
            });

            th.appendChild(menu);

            const resizer = document.createElement('div');
            resizer.className = 'amily2-resizer';
            th.appendChild(resizer);

            const startResize = (startEvent) => {
                startEvent.preventDefault();
                startEvent.stopPropagation();

                isResizing = true;

                const table = startEvent.target.closest('table');
                const th = startEvent.target.parentElement;
                const col = table.querySelector(`colgroup > col:nth-child(${th.cellIndex + 1})`);

                const isTouchEvent = startEvent.type.startsWith('touch');
                const startX = isTouchEvent ? startEvent.touches[0].clientX : startEvent.clientX;
                const startWidth = th.offsetWidth;

                const onMove = (moveEvent) => {
                    const currentX = isTouchEvent ? moveEvent.touches[0].clientX : moveEvent.clientX;
                    const newWidth = startWidth + (currentX - startX);
                    if (newWidth > 50) {
                        col.style.width = `${newWidth}px`;
                    }
                };

                const onEnd = () => {
                    document.removeEventListener('mousemove', onMove);
                    document.removeEventListener('mouseup', onEnd);
                    document.removeEventListener('touchmove', onMove);
                    document.removeEventListener('touchend', onEnd);

                    const finalWidth = parseInt(col.style.width, 10);
                    TableManager.updateColumnWidth(tableIndex, colIndex, finalWidth);

                    setTimeout(() => { isResizing = false; }, 0);
                };

                if (isTouchEvent) {
                    document.addEventListener('touchmove', onMove, { passive: false });
                    document.addEventListener('touchend', onEnd);
                } else {
                    document.addEventListener('mousemove', onMove);
                    document.addEventListener('mouseup', onEnd);
                }
            };

            resizer.addEventListener('mousedown', startResize);
            resizer.addEventListener('touchstart', startResize, { passive: false });

            headerRow.appendChild(th);
        });

        const tbody = tableElement.createTBody();
        if (tableData.rows && tableData.rows.length > 0) {
            tableData.rows.forEach((rowData, rowIndex) => {
                const row = tbody.insertRow();
                row.dataset.rowIndex = rowIndex;

                // 【延迟删除】根据行状态添加样式
                const rowStatus = tableData.rowStatuses ? tableData.rowStatuses[rowIndex] : 'normal';
                if (rowStatus === 'pending-deletion') {
                    row.classList.add('pending-deletion-row');
                }

                const indexCell = row.insertCell();
                indexCell.className = 'index-col';

                const rowIndexSpan = document.createElement('span');
                rowIndexSpan.textContent = rowIndex + 1;
                indexCell.appendChild(rowIndexSpan);

                const menu = document.createElement('div');
                menu.className = 'amily2-context-menu amily2-row-context-menu';

                let actions;

                if (rowStatus === 'pending-deletion') {
                    actions = [
                        { label: '恢复该行', action: 'restore-row', icon: 'fa-undo', isSuccess: true, btnClass: 'restore-row-btn' }
                    ];
                } else {
                    actions = [
                        { label: '向上移动', action: 'move-up', icon: 'fa-arrow-up', btnClass: 'move-row-up-btn' },
                        { label: '向下移动', action: 'move-down', icon: 'fa-arrow-down', btnClass: 'move-row-down-btn' },
                        { label: '在上加行', action: 'add-above', icon: 'fa-plus-circle', btnClass: 'add-row-above-btn' },
                        { label: '在下加行', action: 'add-below', icon: 'fa-plus-circle', btnClass: 'add-row-below-btn' },
                        { label: '删除该行', action: 'delete-row', icon: 'fa-trash-alt', isDanger: true, btnClass: 'delete-row-btn' }
                    ];
                }

                actions.forEach(({ label, action, icon, isDanger, isSuccess }) => {
                    const button = document.createElement('button');
                    button.innerHTML = `<i class="fas ${icon}"></i> ${label}`;
                    button.className = 'menu_button small_button';
                    if (isDanger) button.classList.add('danger');
                    if (isSuccess) button.classList.add('success'); // Use a success style for restore

                    button.addEventListener('click', (e) => {
                        e.stopPropagation();
                        
                        switch (action) {
                            case 'move-up':
                                TableManager.moveRow(tableIndex, rowIndex, 'up');
                                break;
                            case 'move-down':
                                TableManager.moveRow(tableIndex, rowIndex, 'down');
                                break;
                            case 'add-above':
                                TableManager.insertRow(tableIndex, rowIndex, 'above');
                                break;
                            case 'add-below':
                                TableManager.insertRow(tableIndex, rowIndex, 'below');
                                break;
                            case 'delete-row':
                                TableManager.deleteRow(tableIndex, rowIndex);
                                break;
                            case 'restore-row':
                                TableManager.restoreRow(tableIndex, rowIndex);
                                break;
                        }
                        if (action === 'delete-row' || action === 'restore-row') {
                        } else {
                            renderTables();
                        }
                    });
                    menu.appendChild(button);
                });
                indexCell.appendChild(menu);

                rowData.forEach((cellData, colIndex) => {
                    const cell = row.insertCell();
                    
                    const cellContent = document.createElement('div');
                    cellContent.className = 'amily2-cell-content';
                    cellContent.textContent = cellData; 
                    cell.appendChild(cellContent);

                    if (rowStatus !== 'pending-deletion' && !isTouchDevice()) {
                        cell.setAttribute('contenteditable', 'true');
                    }
                    cell.dataset.colIndex = colIndex;
                    cell.dataset.label = tableData.headers[colIndex] || '';

                    const highlightKey = `${tableIndex}-${rowIndex}-${colIndex}`;
                    if (highlights.has(highlightKey)) {
                        cell.classList.add('cell-highlight');
                    }
                });
            });
        }
        tableWrapper.appendChild(tableElement);
        fragment.appendChild(tableWrapper);
    } else {
        // 如果没有表格，显示占位符
        const placeholder = document.createElement('div');
        placeholder.id = 'add-table-placeholder';
        placeholder.innerHTML = '<i class="fas fa-plus"></i>';
        placeholder.title = '点击创建第一个表格';
        placeholder.addEventListener('click', () => {
            const newName = prompt('请输入新表格的名称：', '新表格');
            if (newName && newName.trim()) {
                TableManager.addTable(newName.trim());
                renderTables();
            }
        });
        fragment.appendChild(placeholder);
    }

    container.innerHTML = '';
    container.appendChild(fragment);

    updateOrInsertTableInChat();
}



function openRuleEditor(tableIndex) {
    const tables = TableManager.getMemoryState();
    if (!tables || !tables[tableIndex]) return;
    const table = tables[tableIndex];

    if (table.charLimitRule && !table.charLimitRules) {
        table.charLimitRules = {};
        if (table.charLimitRule.columnIndex !== -1) {
            table.charLimitRules[table.charLimitRule.columnIndex] = table.charLimitRule.limit;
        }
    }
    const charLimitRules = table.charLimitRules || {};

    const renderCharLimitRules = (rules) => {
        return Object.entries(rules).map(([colIndex, limit]) => {
            const header = table.headers[colIndex] || `未知列 (${colIndex})`;
            return `
                <div class="char-limit-rule-item" style="display: flex; justify-content: space-between; align-items: center; padding: 8px; background: rgba(0,0,0,0.1); border-radius: 4px;">
                    <span><i class="fas fa-file-alt" style="margin-right: 8px; color: #9e8aff;"></i><b>${escapeHTML(header)}</b>: 不超过 ${limit} 字</span>
                    <button class="menu_button danger small_button remove-char-limit-rule-btn" data-col-index="${colIndex}" title="删除此规则">
                        <i class="fas fa-trash-alt"></i>
                    </button>
                </div>
            `;
        }).join('');
    };

    const getColumnOptions = (rules) => {
        return table.headers.map((header, index) => {
            if (rules[index]) return '';
            return `<option value="${index}">${escapeHTML(header)}</option>`;
        }).join('');
    };

    const dialogHtml = `
        <dialog class="popup wide_dialogue_popup large_dialogue_popup">
          <div class="popup-body">
            <h4 style="margin-top:0; color: #eee; border-bottom: 1px solid rgba(255,255,255,0.2); padding-bottom: 10px;">
                <i class="fa-solid fa-scroll"></i> 编辑 “${escapeHTML(table.name)}” 的规则
            </h4>
            <div class="popup-content" style="height: 70vh; overflow-y: auto;">
                <div class="rule-editor-form" style="display: flex; flex-direction: column; gap: 15px; padding: 10px;">
                    
                    <div class="rule-editor-field" style="border: 1px solid #444; padding: 10px; border-radius: 5px;">
                        <label style="font-weight: bold; color: #9e8aff;">内容长度限制 (0为禁用)</label>
                        
                        <div id="current-char-limit-rules" style="margin-top: 10px; display: flex; flex-direction: column; gap: 8px;">
                            ${renderCharLimitRules(charLimitRules)}
                        </div>
                        
                        <div id="add-char-limit-rule-area" style="margin-top: 15px; padding-top: 15px; border-top: 1px solid #333;">
                            <div style="display: flex; gap: 10px; align-items: center;">
                                <select id="new-rule-column-select" class="text_pole" style="flex: 1;">
                                    <option value="-1">-- 选择要添加规则的列 --</option>
                                    ${getColumnOptions(charLimitRules)}
                                </select>
                                <input type="number" id="new-rule-limit-input" class="text_pole" min="0" value="0" style="width: 80px;">
                                <button id="add-char-limit-rule-btn" class="menu_button menu_button_primary small_button">
                                    <i class="fas fa-plus"></i> 添加
                                </button>
                            </div>
                        </div>
                        <small class="notes">您可以为多个不同的列添加字符数限制规则。</small>
                    </div>

                    <div class="rule-editor-field" style="border: 1px solid #444; padding: 10px; border-radius: 5px;">
                        <label for="rule-row-limit-value" style="font-weight: bold; color: #9e8aff;">表格行数限制 (0为禁用)</label>
                        <input type="number" id="rule-row-limit-value" class="text_pole" min="0" value="${table.rowLimitRule || 0}" style="width: 100px; margin-top: 10px;">
                        <small class="notes">当表格总行数超过设定值时，将在表格底部显示警告。</small>
                    </div>

                    <div class="rule-editor-field" style="border: 1px solid #444; padding: 10px; border-radius: 5px; margin-top: 10px;">
                        <label for="rule-simplify-threshold" style="font-weight: bold; color: #ffcc00;">【实验性】历史内容简化阈值 (0为禁用)</label>
                        <input type="number" id="rule-simplify-threshold" class="text_pole" min="0" value="${table.simplifyRowThreshold || 0}" style="width: 100px; margin-top: 10px;">
                        <small class="notes">设置一个行号 X。在填表时，第 0 行到第 X-1 行的内容将被省略并替换为“已锁定”提示。这可以节省 Token 并防止 AI 修改旧数据。</small>
                    </div>

                    <hr style="border-color: #444; margin: 10px 0;">

                    <div class="rule-editor-field">
                        <label for="rule-note">【说明】:</label>
                        <textarea id="rule-note" class="text_pole" rows="5" style="width: 100%;">${table.note || ''}</textarea>
                    </div>
                    <div class="rule-editor-field">
                        <label for="rule-add">【增加】:</label>
                        <textarea id="rule-add" class="text_pole" rows="3" style="width: 100%;">${table.rule_add || ''}</textarea>
                    </div>
                    <div class="rule-editor-field">
                        <label for="rule-delete">【删除】:</label>
                        <textarea id="rule-delete" class="text_pole" rows="3" style="width: 100%;">${table.rule_delete || ''}</textarea>
                    </div>
                    <div class="rule-editor-field">
                        <label for="rule-update">【修改】:</label>
                        <textarea id="rule-update" class="text_pole" rows="3" style="width: 100%;">${table.rule_update || ''}</textarea>
                    </div>
                </div>
            </div>
            <div class="popup-controls">
                <div class="popup-button-ok menu_button menu_button_primary interactable">保存</div>
                <div class="popup-button-cancel menu_button interactable" style="margin-left: 10px;">取消</div>
            </div>
          </div>
        </dialog>`;

    const dialogElement = $(dialogHtml).appendTo('body');

    const closeDialog = () => {
        dialogElement[0].close();
        dialogElement.remove();
    };

    const refreshRuleUI = () => {
        const currentRules = JSON.parse(dialogElement.find('#current-char-limit-rules').attr('data-rules') || '{}');
        dialogElement.find('#current-char-limit-rules').html(renderCharLimitRules(currentRules));
        dialogElement.find('#new-rule-column-select').html(`<option value="-1">-- 选择要添加规则的列 --</option>${getColumnOptions(currentRules)}`);
    };

    dialogElement.find('#current-char-limit-rules').attr('data-rules', JSON.stringify(charLimitRules));

    dialogElement.on('click', '#add-char-limit-rule-btn', () => {
        const selectedColumn = parseInt(dialogElement.find('#new-rule-column-select').val(), 10);
        const limitValue = parseInt(dialogElement.find('#new-rule-limit-input').val(), 10);

        if (selectedColumn === -1) {
            toastr.warning('请选择一个列。');
            return;
        }

        if (isNaN(limitValue) || limitValue < 0) {
            toastr.warning('请输入一个有效的字数限制（大于等于0）。');
            return;
        }

        const currentRules = JSON.parse(dialogElement.find('#current-char-limit-rules').attr('data-rules') || '{}');

        if (limitValue > 0) {
            currentRules[selectedColumn] = limitValue;
            dialogElement.find('#current-char-limit-rules').attr('data-rules', JSON.stringify(currentRules));
            refreshRuleUI();
        } else {
            toastr.info('字数限制为0表示不设置规则。');
        }
    });

    dialogElement.on('click', '.remove-char-limit-rule-btn', function() {
        const colIndexToRemove = $(this).data('col-index');
        const currentRules = JSON.parse(dialogElement.find('#current-char-limit-rules').attr('data-rules') || '{}');
        delete currentRules[colIndexToRemove];
        dialogElement.find('#current-char-limit-rules').attr('data-rules', JSON.stringify(currentRules));
        refreshRuleUI();
    });

    dialogElement.find('.popup-button-ok').on('click', () => {
        const newCharLimitRules = JSON.parse(dialogElement.find('#current-char-limit-rules').attr('data-rules') || '{}');
        const rowLimitValue = parseInt(dialogElement.find('#rule-row-limit-value').val(), 10);
        const simplifyThresholdValue = parseInt(dialogElement.find('#rule-simplify-threshold').val(), 10);

        const newRules = {
            note: dialogElement.find('#rule-note').val(),
            rule_add: dialogElement.find('#rule-add').val(),
            rule_delete: dialogElement.find('#rule-delete').val(),
            rule_update: dialogElement.find('#rule-update').val(),
            charLimitRules: newCharLimitRules,
            rowLimitRule: rowLimitValue,
            simplifyRowThreshold: simplifyThresholdValue, // 保存新设置
        };
        TableManager.updateTableRules(tableIndex, newRules);
        closeDialog();
    });

    dialogElement.find('.popup-button-cancel').on('click', closeDialog);
    dialogElement[0].showModal();
}


function bindInjectionSettings() {
    const masterSwitchCheckbox = document.getElementById('table-system-master-switch');
    const enabledCheckbox = document.getElementById('table-injection-enabled');
    const optimizationCheckbox = document.getElementById('context-optimization-enabled'); // 【V144.0】
    const positionSelect = document.getElementById('table-injection-position');
    const depthInput = document.getElementById('table-injection-depth');
    const roleRadioGroup = document.querySelectorAll('input[name="table-injection-role"]');

    if (!masterSwitchCheckbox || !enabledCheckbox || !positionSelect || !depthInput || !roleRadioGroup.length) {
        return;
    }

    const getLiveSettings = () => {
        const liveSettings = getLiveExtensionSettings();
        if (!liveSettings.injection) {
            liveSettings.injection = { position: 1, depth: 0, role: 0 };
        }

        return liveSettings;
    };

    const updateInjectionUI = () => {
        const position = positionSelect.value;
        const masterEnabled = masterSwitchCheckbox.checked;
 
        const isChatInjection = position === '1';

        enabledCheckbox.disabled = !masterEnabled;
        positionSelect.disabled = !masterEnabled;
        depthInput.disabled = !masterEnabled || !isChatInjection;
        roleRadioGroup.forEach(radio => radio.disabled = !masterEnabled || !isChatInjection);

        const enabledOpacity = masterEnabled ? '1' : '0.5';
        enabledCheckbox.style.opacity = enabledOpacity;
        if (enabledCheckbox.closest('.control-block-with-switch')) {
            enabledCheckbox.closest('.control-block-with-switch').style.opacity = enabledOpacity;
        }
        
        positionSelect.style.opacity = enabledOpacity;
        if (positionSelect.previousElementSibling) {
            positionSelect.previousElementSibling.style.opacity = enabledOpacity;
        }

        const depthOpacity = masterEnabled && isChatInjection ? '1' : '0.5';
        depthInput.style.opacity = depthOpacity;
        if (depthInput.previousElementSibling) {
            depthInput.previousElementSibling.style.opacity = depthOpacity;
        }

        const roleOpacity = masterEnabled && isChatInjection ? '1' : '0.5';
        const roleGroupContainer = document.getElementById('table-role-system')?.closest('.radio-group');
        if (roleGroupContainer) {
            roleGroupContainer.style.opacity = roleOpacity;
            if (roleGroupContainer.previousElementSibling) {
                roleGroupContainer.previousElementSibling.style.opacity = roleOpacity;
            }
        }

        const fillingModeRadios = document.querySelectorAll('input[name="filling-mode"]');
        fillingModeRadios.forEach(radio => {
            radio.disabled = !masterEnabled;
            const label = radio.closest('label');
            if (label) {
                label.style.opacity = masterEnabled ? '1' : '0.5';
            }
        });

        const fillButton = document.getElementById('fill-table-now-btn');
        if (fillButton) {
            fillButton.disabled = !masterEnabled;
            fillButton.style.opacity = masterEnabled ? '1' : '0.5';
        }
    };

    const settings = getLiveSettings();
    masterSwitchCheckbox.checked = settings.table_system_enabled !== false;
    enabledCheckbox.checked = settings.table_injection_enabled;
    if (optimizationCheckbox) { // 【V144.0】
        optimizationCheckbox.checked = settings.context_optimization_enabled !== false;
    }
    positionSelect.value = settings.injection.position;
    depthInput.value = settings.injection.depth;
    roleRadioGroup.forEach(radio => {
        if (parseInt(radio.value, 10) === settings.injection.role) {
            radio.checked = true;
        }
    });

    updateInjectionUI();

    if (masterSwitchCheckbox.dataset.eventsBound) return;

    masterSwitchCheckbox.addEventListener('change', () => {
        const currentSettings = getLiveSettings();
        currentSettings.table_system_enabled = masterSwitchCheckbox.checked;
        saveSettingsDebounced();
        updateInjectionUI();
        
        const statusText = masterSwitchCheckbox.checked ? '已启用' : '已禁用';
        toastr.info(`表格系统总开关${statusText}。`);
        log(`表格系统总开关${statusText}。`, 'info');
    });

    enabledCheckbox.addEventListener('change', () => {
        const currentSettings = getLiveSettings();
        currentSettings.table_injection_enabled = enabledCheckbox.checked;
        saveSettingsDebounced();
    });

    // 【V144.0】
    if (optimizationCheckbox) {
        optimizationCheckbox.addEventListener('change', () => {
            const currentSettings = getLiveSettings();
            currentSettings.context_optimization_enabled = optimizationCheckbox.checked;
            saveSettingsDebounced();
            toastr.info(`上下文优化（世界书合并）已${optimizationCheckbox.checked ? '启用' : '禁用'}。`);
        });
    }

    positionSelect.addEventListener('change', () => {
        const currentSettings = getLiveSettings();
        currentSettings.injection.position = parseInt(positionSelect.value, 10);
        saveSettingsDebounced();

        updateInjectionUI();
    });

    depthInput.addEventListener('input', () => {
        const currentSettings = getLiveSettings();
        currentSettings.injection.depth = parseInt(depthInput.value, 10);
        saveSettingsDebounced();
    });

    roleRadioGroup.forEach(radio => {
        radio.addEventListener('change', () => {
            if (radio.checked) {
                const currentSettings = getLiveSettings();
                currentSettings.injection.role = parseInt(radio.value, 10);
                saveSettingsDebounced();
            }
        });
    });

    masterSwitchCheckbox.dataset.eventsBound = 'true';
    log('表格注入设置已成功绑定。', 'success');
}


function updateAndSaveTableSetting(key, value) {
    getLiveExtensionSettings()[key] = value;
    saveSettingsDebounced();
}

function bindWorldBookSettings() {
    const settings = getLiveExtensionSettings();

    if (settings.table_worldbook_enabled === undefined) settings.table_worldbook_enabled = false;
    if (settings.table_worldbook_char_limit === undefined) settings.table_worldbook_char_limit = 30000;
    if (settings.table_worldbook_source === undefined) settings.table_worldbook_source = 'character';
    if (settings.table_selected_worldbooks === undefined) settings.table_selected_worldbooks = [];
    if (settings.table_selected_entries === undefined) settings.table_selected_entries = {};

    const enabledCheckbox = document.getElementById('table_worldbook_enabled');
    const limitSlider = document.getElementById('table_worldbook_char_limit');
    const limitValueSpan = document.getElementById('table_worldbook_char_limit_value');
    const sourceRadios = document.querySelectorAll('input[name="table_worldbook_source"]');
    const manualSelectWrapper = document.getElementById('table_worldbook_select_wrapper');
    const refreshButton = document.getElementById('table_refresh_worldbooks');
    const bookListContainer = document.getElementById('table_worldbook_checkbox_list');
    const entryListContainer = document.getElementById('table_worldbook_entry_list');
    const bookSearchInput = document.getElementById('table_worldbook_search');
    const entrySearchInput = document.getElementById('table_entry_search');

    if (!enabledCheckbox || !limitSlider || !limitValueSpan || !sourceRadios.length || !manualSelectWrapper || !refreshButton || !bookListContainer || !entryListContainer) {
        log('无法找到世界书设置的相关UI元素，绑定失败。', 'warn');
        return;
    }

    const saveSelectedEntries = () => {
        const currentSettings = getLiveExtensionSettings();
        const selected = {};
        entryListContainer.querySelectorAll('input[type="checkbox"]:checked').forEach(cb => {
            const book = cb.dataset.book;
            const uid = cb.dataset.uid;
            if (!selected[book]) {
                selected[book] = [];
            }
            selected[book].push(uid);
        });
        currentSettings.table_selected_entries = selected;
        saveSettingsDebounced();
    };

    const renderWorldBookEntries = async () => {
        entryListContainer.innerHTML = '<p>加载条目中...</p>';
        const currentSettings = getLiveExtensionSettings();
        const source = currentSettings.table_worldbook_source || 'character';
        let bookNames = [];

        if (source === 'manual') {
            bookNames = currentSettings.table_selected_worldbooks || [];
        } else {
            if (this_chid !== undefined && this_chid >= 0 && characters[this_chid]) {
                try {
                    const charLorebooks = await safeCharLorebooks({ type: 'all' });
                    if (charLorebooks.primary) bookNames.push(charLorebooks.primary);
                    if (charLorebooks.additional?.length) bookNames.push(...charLorebooks.additional);
                } catch (error) {
                    console.error(`[内存储司] 获取角色世界书失败:`, error);
                    entryListContainer.innerHTML = '<p class="notes" style="color:red;">获取角色世界书失败。</p>';
                    return;
                }
            } else {
                entryListContainer.innerHTML = '<p class="notes">请先加载一个角色。</p>';
                return;
            }
        }

        if (bookNames.length === 0) {
            entryListContainer.innerHTML = '<p class="notes">未选择或绑定世界书。</p>';
            return;
        }

        try {
            const allEntries = [];
            for (const bookName of bookNames) {
                const entries = await safeLorebookEntries(bookName);
                entries.forEach(entry => allEntries.push({ ...entry, bookName }));
            }

            entryListContainer.innerHTML = '';
            if (allEntries.length === 0) {
                entryListContainer.innerHTML = '<p class="notes">所选世界书中没有条目。</p>';
                return;
            }

            allEntries.forEach(entry => {
                const div = document.createElement('div');
                div.className = 'checkbox-item';
                div.title = `世界书: ${entry.bookName}\nUID: ${entry.uid}`;

                const checkbox = document.createElement('input');
                checkbox.type = 'checkbox';
                checkbox.id = `wb-entry-check-${entry.bookName}-${entry.uid}`;
                checkbox.dataset.book = entry.bookName;
                checkbox.dataset.uid = entry.uid;
                
                const isChecked = currentSettings.table_selected_entries[entry.bookName]?.includes(String(entry.uid));
                checkbox.checked = !!isChecked;

                const label = document.createElement('label');
                label.htmlFor = checkbox.id;
                label.textContent = entry.comment || '无标题条目'; // textContent is safe

                div.appendChild(checkbox);
                div.appendChild(label);
                entryListContainer.appendChild(div);
            });
        } catch (error) {
            console.error(`[内存储司] 加载世界书条目失败:`, error);
            entryListContainer.innerHTML = '<p class="notes" style="color:red;">加载条目失败。</p>';
        }
    };

    const renderWorldBookList = () => {
        const worldBooks = world_names.map(name => ({ name: name.replace('.json', ''), file_name: name }));
        bookListContainer.innerHTML = '';
        if (worldBooks && worldBooks.length > 0) {
            worldBooks.forEach(book => {
                const div = document.createElement('div');
                div.className = 'checkbox-item';
                div.title = book.name;

                const checkbox = document.createElement('input');
                checkbox.type = 'checkbox';
                checkbox.id = `wb-check-${book.file_name}`;
                checkbox.value = book.file_name;
                checkbox.checked = getLiveExtensionSettings().table_selected_worldbooks.includes(book.file_name);

                checkbox.addEventListener('change', () => {
                    const currentSettings = getLiveExtensionSettings();
                    if (checkbox.checked) {
                        if (!currentSettings.table_selected_worldbooks.includes(book.file_name)) {
                            currentSettings.table_selected_worldbooks.push(book.file_name);
                        }
                    } else {
                        currentSettings.table_selected_worldbooks = currentSettings.table_selected_worldbooks.filter(name => name !== book.file_name);
                    }
                    saveSettingsDebounced();
                    renderWorldBookEntries();
                });

                const label = document.createElement('label');
                label.htmlFor = `wb-check-${book.file_name}`;
                label.textContent = book.name; // textContent is safe

                div.appendChild(checkbox);
                div.appendChild(label);
                bookListContainer.appendChild(div);
            });
        } else {
            bookListContainer.innerHTML = '<p class="notes">没有找到世界书。</p>';
        }
        renderWorldBookEntries();
    };
    
    const updateManualSelectVisibility = () => {
        const isManual = getLiveExtensionSettings().table_worldbook_source === 'manual';
        manualSelectWrapper.style.display = isManual ? 'block' : 'none';
        renderWorldBookEntries();
        if (isManual) {
            renderWorldBookList();
        }
    };

    enabledCheckbox.checked = settings.table_worldbook_enabled;
    limitSlider.value = settings.table_worldbook_char_limit;
    limitValueSpan.textContent = settings.table_worldbook_char_limit;
    sourceRadios.forEach(radio => {
        radio.checked = radio.value === settings.table_worldbook_source;
    });

    updateManualSelectVisibility();

    if (enabledCheckbox.dataset.eventsBound) return;

    enabledCheckbox.addEventListener('change', () => {
        const currentSettings = getLiveExtensionSettings();
        currentSettings.table_worldbook_enabled = enabledCheckbox.checked;
        saveSettingsDebounced();
    });

    limitSlider.addEventListener('input', () => { limitValueSpan.textContent = limitSlider.value; });
    limitSlider.addEventListener('change', () => {
        const currentSettings = getLiveExtensionSettings();
        currentSettings.table_worldbook_char_limit = parseInt(limitSlider.value, 10);
        saveSettingsDebounced();
    });

    sourceRadios.forEach(radio => {
        radio.addEventListener('change', () => {
            if (radio.checked) {
                const currentSettings = getLiveExtensionSettings();
                currentSettings.table_worldbook_source = radio.value;
                updateManualSelectVisibility();
                saveSettingsDebounced();
            }
        });
    });

    refreshButton.addEventListener('click', renderWorldBookList);
    entryListContainer.addEventListener('change', (event) => {
        if (event.target.type === 'checkbox') {
            saveSelectedEntries();
        }
    });

    if (bookSearchInput) {
        bookSearchInput.addEventListener('input', () => {
            const keyword = bookSearchInput.value.trim().toLowerCase();
            bookListContainer.querySelectorAll('.checkbox-item').forEach(item => {
                const text = item.textContent.toLowerCase();
                item.style.display = text.includes(keyword) ? '' : 'none';
            });
        });
    }

    if (entrySearchInput) {
        entrySearchInput.addEventListener('input', () => {
            const keyword = entrySearchInput.value.trim().toLowerCase();
            entryListContainer.querySelectorAll('.checkbox-item').forEach(item => {
                const text = item.textContent.toLowerCase();
                item.style.display = text.includes(keyword) ? '' : 'none';
            });
        });
    }

    enabledCheckbox.dataset.eventsBound = 'true';
    log('世界书设置已成功绑定。', 'success');
}

export function bindTableEvents(panelElement = null) {
    const panel = panelElement || document.getElementById('amily2_memorisation_forms_panel');
    if (!panel || panel.dataset.eventsBound) {
        return;
    }
    log('开始为表格视图绑定交互事件...', 'info');

    const fillingModeRadios = panel.querySelectorAll('input[name="filling-mode"]');
    const secondaryFillerControls = document.getElementById('secondary-filler-controls');

    const contextSlider = document.getElementById('secondary-filler-context');
    const batchSlider = document.getElementById('secondary-filler-batch');
    const bufferSlider = document.getElementById('secondary-filler-buffer');
    const maxRetriesSlider = document.getElementById('secondary-filler-max-retries');
    const delaySlider = document.getElementById('secondary-filler-delay');
    const batchFillingThresholdInput = document.getElementById('batch-filling-threshold');

    const tableRuleProfileSelect = document.getElementById('table-rule-profile-select');
    
    const updateFillingModeUI = () => {
        const currentMode = extension_settings[extensionName]?.filling_mode || 'main-api';
        fillingModeRadios.forEach(radio => {
            radio.checked = (radio.value === currentMode);
        });

        const isSecondaryMode = currentMode === 'secondary-api';

        if (secondaryFillerControls) {
            secondaryFillerControls.style.display = isSecondaryMode ? 'block' : 'none';
        }

        if (tableRuleProfileSelect) {
            _populateRuleProfileSelect(tableRuleProfileSelect, 'table');
        }
    };

    fillingModeRadios.forEach(radio => {
        radio.addEventListener('change', function() {
            const selectedMode = this.value;
            updateAndSaveTableSetting('filling_mode', selectedMode);
            
            let modeName = '原始填表';
            if (selectedMode === 'secondary-api') modeName = '分步填表';
            if (selectedMode === 'optimized') modeName = '优化中填表';
            
            toastr.info(`填表模式已切换为 ${modeName}。`);
            updateFillingModeUI();
        });
    });

    if (contextSlider) {
        const value = extension_settings[extensionName]?.secondary_filler_context || 2;
        contextSlider.value = value;
        
        contextSlider.addEventListener('change', function() {
            updateAndSaveTableSetting('secondary_filler_context', parseInt(this.value, 10));
            toastr.info(`上下文深度已设置为 ${this.value}。`);
        });
    }

    if (batchSlider) {
        const value = extension_settings[extensionName]?.secondary_filler_batch || 0;
        batchSlider.value = value;
        
        batchSlider.addEventListener('change', function() {
            updateAndSaveTableSetting('secondary_filler_batch', parseInt(this.value, 10));
            toastr.info(`填表批次已设置为 ${this.value}。`);
        });
    }

    if (bufferSlider) {
        const value = extension_settings[extensionName]?.secondary_filler_buffer || 0;
        bufferSlider.value = value;
        
        bufferSlider.addEventListener('change', function() {
            updateAndSaveTableSetting('secondary_filler_buffer', parseInt(this.value, 10));
            toastr.info(`保留楼层已设置为 ${this.value}。`);
        });
    }

    if (maxRetriesSlider) {
        const value = extension_settings[extensionName]?.secondary_filler_max_retries ?? 2;
        maxRetriesSlider.value = value;

        maxRetriesSlider.addEventListener('change', function() {
            updateAndSaveTableSetting('secondary_filler_max_retries', parseInt(this.value, 10));
            toastr.info(`最大重试次数已设置为 ${this.value}。`);
        });
    }

    if (delaySlider) {
        const value = extension_settings[extensionName]?.secondary_filler_delay ?? 0;
        delaySlider.value = value;

        delaySlider.addEventListener('change', function() {
            const parsed = Math.max(0, parseInt(this.value, 10) || 0);
            this.value = parsed;
            updateAndSaveTableSetting('secondary_filler_delay', parsed);
            toastr.info(`触发延迟已设置为 ${parsed} 毫秒。`);
        });
    }

    if (batchFillingThresholdInput) {
        const value = extension_settings[extensionName]?.batch_filling_threshold ?? 30;
        batchFillingThresholdInput.value = value;

        batchFillingThresholdInput.addEventListener('change', function() {
            const parsed = Math.max(1, parseInt(this.value, 10) || 30);
            this.value = parsed;
            updateAndSaveTableSetting('batch_filling_threshold', parsed);
            toastr.info(`批处理阈值已设置为 ${parsed}。`);
        });
    }

    const abortBtn = document.getElementById('amily2-abort-secondary-filler');
    const resetLockBtn = document.getElementById('amily2-reset-secondary-filler-lock');
    const lockStatusSpan = document.getElementById('amily2-secondary-filler-lock-status');
    if ((abortBtn || resetLockBtn) && lockStatusSpan) {
        const refreshLockStatus = () => {
            const running = isSecondaryFillerRunning();
            lockStatusSpan.textContent = running ? '状态：占用中' : '状态：空闲';
            lockStatusSpan.style.color = running ? 'var(--SmartThemeQuoteColor, #d97706)' : '';
        };
        refreshLockStatus();
        if (abortBtn) {
            abortBtn.addEventListener('click', () => {
                const signaled = abortCurrentSecondaryFiller();
                if (signaled) {
                    toastr.warning('已发出中断信号，进行中的请求将立即终止，结果会被丢弃。', 'Amily2');
                    log('用户手动中断了当前分步填表（AbortController.abort）。', 'warn');
                } else {
                    toastr.info('当前没有正在进行的分步填表。', 'Amily2');
                }
                setTimeout(refreshLockStatus, 300);
            });
            abortBtn.addEventListener('mouseenter', refreshLockStatus);
            abortBtn.addEventListener('focus', refreshLockStatus);
        }
        if (resetLockBtn) {
            resetLockBtn.addEventListener('click', () => {
                const wasLocked = resetSecondaryFillerLock();
                refreshLockStatus();
                if (wasLocked) {
                    toastr.success('分步填表锁已手动释放。', 'Amily2');
                    log('用户手动释放了分步填表锁（之前处于占用状态）。', 'warn');
                } else {
                    toastr.info('当前并无锁占用，无需释放。', 'Amily2');
                }
            });
            resetLockBtn.addEventListener('mouseenter', refreshLockStatus);
            resetLockBtn.addEventListener('focus', refreshLockStatus);
        }
    }

    const fcToggle = document.getElementById('table-fill-function-call-enabled');
    if (fcToggle) {
        fcToggle.checked = extension_settings[extensionName]?.tableFillFunctionCall ?? false;
        fcToggle.addEventListener('change', function() {
            updateAndSaveTableSetting('tableFillFunctionCall', this.checked);
            toastr.info(`Function Call 填表已${this.checked ? '启用' : '禁用'}。`);
        });
    }

    updateFillingModeUI();

    if (tableRuleProfileSelect) {
        _populateRuleProfileSelect(tableRuleProfileSelect, 'table');
        tableRuleProfileSelect.addEventListener('change', () => {
            ruleProfileManager.setAssignment('table', tableRuleProfileSelect.value || null);
            const name = tableRuleProfileSelect.selectedOptions[0]?.textContent || '';
            toastr.info(tableRuleProfileSelect.value ? `表格提取规则已切换为「${name}」` : '表格提取规则已取消分配');
        });
        document.addEventListener('amily2:ruleProfilesChanged', (e) => {
            _populateRuleProfileSelect(tableRuleProfileSelect, 'table', e.detail);
        });
    }

    const renderAll = () => {
        renderTables();
        bindInjectionSettings();
        bindTableTemplateEditors({
            TableManager,
            log,
            defaultRuleTemplate: DEFAULT_AI_RULE_TEMPLATE,
            defaultFlowTemplate: DEFAULT_AI_FLOW_TEMPLATE,
        });
    };

    renderAll();
    bindWorldBookSettings();
    bindBatchFillButton(); // 【新增】绑定批量填表按钮
    bindFloorFillButtons(); // 【新增】绑定楼层填表按钮
    bindReorganizeButton(); // 【新增】绑定重新整理按钮
    bindClearRecordsButton(); // 【新增】绑定清除记录按钮
    bindNccsApiSettingsEvents({
        getLiveExtensionSettings,
        saveSettingsDebounced,
        getContext,
        fetchNccsModels,
        testNccsApiConnection,
        configManager,
        log,
    }); // 【新增】绑定Nccs API系统事件
    bindChatTableDisplaySettings({
        getLiveExtensionSettings,
        saveSettingsDebounced,
        log,
    }); // 【新增】绑定聊天内表格显示开关

    const navDeck = document.querySelector('#amily2_memorisation_forms_panel .sinan-navigation-deck');
    if (navDeck) {
        navDeck.addEventListener('click', (event) => {
            const target = event.target.closest('.sinan-nav-item');
            if (!target) return;

            const tabName = target.dataset.tab;
            if (!tabName) return;

            const container = target.closest('.settings-group');
            if (!container) return;

            container.querySelectorAll('.sinan-nav-item').forEach(btn => btn.classList.remove('active'));
            target.classList.add('active');
            container.querySelectorAll('.sinan-tab-pane').forEach(pane => pane.classList.remove('active'));
            const activePane = container.querySelector(`#sinan-${tabName}-tab`);
            if (activePane) {
                activePane.classList.add('active');
            }
        });
    }

    const openGraphBtn = document.getElementById('amily2-open-relationship-graph-btn');
    const exportBtn = document.getElementById('amily2-export-preset-btn');
    const exportFullBtn = document.getElementById('amily2-export-preset-full-btn');
    const importBtn = document.getElementById('amily2-import-preset-btn');
    const importGlobalBtn = document.getElementById('amily2-import-global-preset-btn');
    const clearGlobalBtn = document.getElementById('amily2-clear-global-preset-btn');

    if (openGraphBtn) {
        openGraphBtn.addEventListener('click', () => {
            showGraphVisualization();
        });
    }

    if (exportBtn) {
        exportBtn.addEventListener('click', () => TableManager.exportPreset());
    }
    if (exportFullBtn) {
        exportFullBtn.addEventListener('click', () => TableManager.exportPresetFull());
    }
    if (importBtn) {
        importBtn.addEventListener('click', () => TableManager.importPreset(renderAll));
    }
    if (importGlobalBtn) {
        importGlobalBtn.addEventListener('click', () => {

            const isEmpty = TableManager.isCurrentTablesEmpty();
            TableManager.importGlobalPreset(() => {
                if (isEmpty) {
                    TableManager.loadTables(); 
                    renderAll();
                }
            });
        });
    }
    if (clearGlobalBtn) {
        clearGlobalBtn.addEventListener('click', () => {
            const isEmpty = TableManager.isCurrentTablesEmpty();
            TableManager.clearGlobalPreset();
            if (isEmpty) {
                TableManager.loadTables();
                renderAll();
            }
        });
    }

    const clearAllBtn = document.getElementById('amily2-clear-all-tables-btn');
    if (clearAllBtn) {
        clearAllBtn.addEventListener('click', () => {
            if (confirm('【确认】您确定要清空所有表格的剧情内容吗？此操作将保留表格结构，但会删除所有已填写的行。')) {
                TableManager.clearAllTables();
                renderAll();
            }
        });
    }


    // 【V155.0】移除旧的 addTablePlaceholder 绑定，因为现在它在 renderTables 内部动态生成
    // const addTablePlaceholder = document.getElementById('add-table-placeholder');
    // if (addTablePlaceholder) { ... }


    const allTablesContainer = getAllTablesContainer();
    if (allTablesContainer) {
        allTablesContainer.addEventListener('click', (event) => {
            const th = event.target.closest('th');
            if (th && th.classList.contains('index-col')) {
                toggleHeaderIndexContextMenu(event);
                return;
            }
            if (th && !th.classList.contains('index-col')) {
                toggleColumnContextMenu(event);
                return;
            }

            const td = event.target.closest('td.index-col');
            if (td) {
                toggleRowContextMenu(event);
                return;
            }

            const renameIcon = event.target.closest('.table-rename-icon');
            if (renameIcon) {
                const tableIndex = parseInt(renameIcon.dataset.tableIndex, 10);
                const tables = TableManager.getMemoryState();
                const currentName = tables[tableIndex]?.name || '';
                showTableNameEditor(tableIndex, currentName);
                return;
            }

            const target = event.target.closest('button');
            if (!target) return;

            const tableIndex = parseInt(target.dataset.tableIndex, 10);

            if (target.matches('.add-row-btn')) {
                TableManager.addRow(tableIndex);
                renderAll();
            } else if (target.matches('.add-col-btn')) {
                TableManager.addColumn(tableIndex);
                renderAll();
            } else if (target.matches('.move-table-up-btn') || target.matches('.move-table-down-btn')) {
                const direction = target.classList.contains('move-table-up-btn') ? 'up' : 'down';
                TableManager.moveTable(tableIndex, direction);
                // 【V155.0】移动表格后，activeTableIndex 需要跟随移动
                if (direction === 'up' && activeTableIndex > 0) {
                    activeTableIndex--;
                } else if (direction === 'down' && activeTableIndex < TableManager.getMemoryState().length - 1) {
                    activeTableIndex++;
                }
                renderAll();
            } else if (target.matches('.edit-rules-btn')) {
                openRuleEditor(tableIndex);
            } else if (target.matches('.delete-table-btn')) {
                const tables = TableManager.getMemoryState();
                const tableName = tables[tableIndex]?.name || '未知表格';
                if (confirm(`【最终警告】您确定要永久废黜表格 “[${tableName}]” 吗？此操作不可逆！`)) {
                    TableManager.deleteTable(tableIndex);
                    renderAll();
                }
            }
        });

        if (isTouchDevice()) {
            let lastTap = 0;
            let lastTapTarget = null;
            allTablesContainer.addEventListener('touchstart', (event) => {
                const target = event.target.closest('td');
                if (!target || target.dataset.colIndex === undefined) return;

                const currentTime = new Date().getTime();
                const tapLength = currentTime - lastTap;
                if (tapLength < 300 && tapLength > 0 && lastTapTarget === target) {
                    event.preventDefault();
                    if (target.getAttribute('contenteditable') !== 'true') {
                        target.setAttribute('contenteditable', 'true');
                        setTimeout(() => target.focus(), 0);
                    }
                }
                lastTap = currentTime;
                lastTapTarget = target;
            });
        }

        allTablesContainer.addEventListener('blur', (event) => {
            const target = event.target;
            if (target.tagName !== 'TD' || target.getAttribute('contenteditable') !== 'true') return;

            if (isTouchDevice()) {
                target.setAttribute('contenteditable', 'false');
            }

            const tableElement = target.closest('table');
            if (!tableElement) return;
            
            const tableIndex = parseInt(tableElement.dataset.tableIndex, 10);
            const rowIndex = parseInt(target.closest('tr').dataset.rowIndex, 10);
            const colIndex = parseInt(target.dataset.colIndex, 10);
            const newValue = target.textContent;

            // Correctly save scroll positions before re-rendering
            const tableWrapper = tableElement.closest('.amily2-table-wrapper');
            const hScroll = tableWrapper ? tableWrapper.scrollLeft : 0;
            const vScroll = allTablesContainer.scrollTop;

            TableManager.addHighlight(tableIndex, rowIndex, colIndex);
            const dataToUpdate = { [colIndex]: newValue };
            TableManager.updateRow(tableIndex, rowIndex, dataToUpdate);

            renderAll();

            // Correctly restore scroll positions after re-rendering
            const newTableWrapper = document.getElementById(`amily2-table-${tableIndex}`)?.closest('.amily2-table-wrapper');
            if (newTableWrapper) {
                newTableWrapper.scrollLeft = hScroll;
            }
            allTablesContainer.scrollTop = vScroll;

        }, true);
    }
    
    panel.dataset.eventsBound = 'true';
    log('表格视图交互事件已成功绑定。', 'success');

    eventSource.on(event_types.CHAT_CHANGED, () => {
        console.log(`[${extensionName}] 检测到角色/聊天切换，正在刷新表格系统UI和世界书设置...`);
        renderAll();

        setTimeout(() => {
            const settings = getLiveExtensionSettings();
            if (settings && settings.table_worldbook_enabled) {
                try {
                    bindWorldBookSettings();
                    console.log(`[${extensionName}] 世界书设置已刷新`);
                } catch (error) {
                    console.error(`[${extensionName}] 刷新世界书设置时出错:`, error);
                }
            }
        }, 100);
    });
}

function bindBatchFillButton() {
    const fillButton = document.getElementById('fill-table-now-btn');
    if (fillButton) {
        if (fillButton.dataset.batchEventBound) return;
        
        fillButton.addEventListener('click', (event) => {
            const tableSystemEnabled = isTableSystemEnabled();
            
            if (!tableSystemEnabled) {
                event.preventDefault();
                toastr.warning('表格系统总开关已关闭，请先启用总开关。');
                return;
            }
            
            startBatchFilling();
        });
        
        fillButton.dataset.batchEventBound = 'true';
        log('"立即填表"按钮已成功绑定。', 'success');
    }
}

function bindReorganizeButton() {
    const reorganizeBtn = document.getElementById('reorganize-table-btn');
    
    if (reorganizeBtn) {
        if (reorganizeBtn.dataset.reorganizeEventBound) return;
        
        reorganizeBtn.addEventListener('click', async (event) => {
            const tableSystemEnabled = isTableSystemEnabled();
            
            if (!tableSystemEnabled) {
                event.preventDefault();
                toastr.warning('表格系统总开关已关闭，请先启用总开关。');
                return;
            }

            const tables = TableManager.getMemoryState();
            if (!tables || tables.length === 0) {
                toastr.warning('当前没有表格可供整理。');
                return;
            }

            // 构建表格选择列表 HTML
            const tableListHtml = tables.map((table, index) => `
                <div class="checkbox-item" style="margin-bottom: 8px; display: flex; align-items: center;">
                    <input type="checkbox" id="reorg-table-${index}" value="${index}">
                    <label for="reorg-table-${index}" style="margin-left: 8px; cursor: pointer;">${escapeHTML(table.name)}</label>
                </div>
            `).join('');

            const modalHtml = `
                <div style="display: flex; flex-direction: column; gap: 15px;">
                    <p class="notes" style="color: #ffcc00;">建议：最好一次只选择一个表格，或少数几个相关联的表格进行整理。一次性处理过多表格可能会导致AI混淆或遗漏信息。</p>
                    <p class="notes">请勾选需要AI重新整理和去重的表格：</p>
                    <div style="max-height: 300px; overflow-y: auto; border: 1px solid #444; padding: 10px; border-radius: 5px; background: rgba(0,0,0,0.2);">
                        ${tableListHtml}
                    </div>
                    <div style="display: flex; gap: 10px;">
                        <button id="reorg-select-all" class="menu_button small_button">全选</button>
                        <button id="reorg-deselect-all" class="menu_button small_button">全不选</button>
                    </div>
                </div>
            `;

            showHtmlModal('选择要整理的表格', modalHtml, {
                onOk: async (dialogElement) => {
                    const selectedIndices = [];
                    dialogElement.find('input[type="checkbox"]:checked').each(function() {
                        selectedIndices.push(parseInt($(this).val(), 10));
                    });

                    if (selectedIndices.length === 0) {
                        toastr.warning('请至少选择一个表格。');
                        return false; // 阻止关闭弹窗
                    }

                    try {
                        const { reorganizeTableContent } = await import('../core/table-system/reorganizer.js');
                        await reorganizeTableContent(selectedIndices);
                    } catch (error) {
                        console.error('[内存储司] 重新整理功能导入失败:', error);
                        toastr.error('重新整理功能启动失败，请检查系统状态。');
                    }
                },
                onShow: (dialogElement) => {
                    dialogElement.find('#reorg-select-all').on('click', () => {
                        dialogElement.find('input[type="checkbox"]').prop('checked', true);
                    });
                    dialogElement.find('#reorg-deselect-all').on('click', () => {
                        dialogElement.find('input[type="checkbox"]').prop('checked', false);
                    });
                }
            });
        });
        
        reorganizeBtn.dataset.reorganizeEventBound = 'true';
        log('"重新整理"按钮已成功绑定。', 'success');
    }
}

function bindClearRecordsButton() {
    const clearBtn = document.getElementById('clear-records-btn');
    const floorInput = document.getElementById('clear-records-before-floor');

    if (clearBtn && floorInput) {
        if (clearBtn.dataset.clearEventBound) return;

        clearBtn.addEventListener('click', async () => {
            const floorIndex = parseInt(floorInput.value, 10);
            if (isNaN(floorIndex) || floorIndex < 0) {
                toastr.warning('请输入有效的楼层号。');
                return;
            }

            if (confirm(`【警告】您确定要清除第 ${floorIndex} 楼之前的所有表格记录吗？\n\n此操作将永久删除这些消息中存储的表格快照，无法恢复。当前最新的表格状态不会受影响。`)) {
                try {
                    const { clearTableRecordsBefore } = await import('../core/table-system/cleaner.js');
                    const count = await clearTableRecordsBefore(floorIndex);
                    toastr.success(`已成功清除 ${count} 条消息中的表格记录。`);
                } catch (error) {
                    console.error('[内存储司] 清除记录失败:', error);
                    toastr.error('清除记录失败，请检查控制台日志。');
                }
            }
        });

        clearBtn.dataset.clearEventBound = 'true';
        log('"清除记录"按钮已成功绑定。', 'success');
    }
}


function bindFloorFillButtons() {
    const selectedFloorsBtn = document.getElementById('fill-selected-floors-btn');
    const currentFloorBtn = document.getElementById('fill-current-floor-btn');
    const rollbackBtn = document.getElementById('rollback-and-refill-btn');
    
    if (selectedFloorsBtn) {

        if (selectedFloorsBtn.dataset.floorEventBound) return;
        
        selectedFloorsBtn.addEventListener('click', (event) => {
            const tableSystemEnabled = isTableSystemEnabled();
            
            if (!tableSystemEnabled) {
                event.preventDefault();
                toastr.warning('表格系统总开关已关闭，请先启用总开关。');
                return;
            }
            
            const startFloorInput = document.getElementById('floor-start-input');
            const endFloorInput = document.getElementById('floor-end-input');
            
            const startFloor = parseInt(startFloorInput.value, 10);
            const endFloor = parseInt(endFloorInput.value, 10);
            
            if (!startFloor || !endFloor) {
                toastr.warning('请输入有效的起始楼层和结束楼层。');
                return;
            }
            
            if (startFloor > endFloor) {
                toastr.warning('起始楼层不能大于结束楼层。');
                return;
            }
            
            if (startFloor < 1) {
                toastr.warning('楼层不能小于1。');
                return;
            }

            import('../core/table-system/batch-filler.js').then(module => {
                module.startFloorRangeFilling(startFloor, endFloor);
            });
        });
        
        selectedFloorsBtn.dataset.floorEventBound = 'true';
        log('"选定楼层填表"按钮已成功绑定。', 'success');
    }
    
    if (currentFloorBtn) {
        if (currentFloorBtn.dataset.currentEventBound) return;
        
        currentFloorBtn.addEventListener('click', (event) => {
            const tableSystemEnabled = isTableSystemEnabled();
            
            if (!tableSystemEnabled) {
                event.preventDefault();
                toastr.warning('表格系统总开关已关闭，请先启用总开关。');
                return;
            }

            import('../core/table-system/batch-filler.js').then(module => {
                module.startCurrentFloorFilling();
            });
        });
        
        currentFloorBtn.dataset.currentEventBound = 'true';
        log('"填当前楼层"按钮已成功绑定。', 'success');
    }

    if (rollbackBtn) {
        if (rollbackBtn.dataset.rollbackEventBound) return;

        rollbackBtn.addEventListener('click', async (event) => {
            const tableSystemEnabled = isTableSystemEnabled();
            
            if (!tableSystemEnabled) {
                event.preventDefault();
                toastr.warning('表格系统总开关已关闭，请先启用总开关。');
                return;
            }

            if (confirm('您确定要将表格状态回退到上一楼，并使用最新消息重新填表吗？')) {
                try {
                    await TableManager.rollbackAndRefill();
                } catch (error) {
                    console.error('[内存储司] 回退重填功能失败:', error);
                    toastr.error('回退重填失败，请检查系统状态。');
                }
            }
        });

        rollbackBtn.dataset.rollbackEventBound = 'true';
        log('"回退重填"按钮已成功绑定。', 'success');
    }
}

