// MNote 主壳文件树选择运行时外置模块。
// 当前只承接 selection 状态同步和选择算法；事件监听、DND 执行和命令分发仍留在主壳。

function cssEscapeValue(value) {
  if (window.CSS && typeof window.CSS.escape === 'function') return window.CSS.escape(value);
  return String(value).replace(/["\\]/g, '\\$&');
}

function visibleFileTreeRows(deps) {
  if (deps && typeof deps.visibleFileTreeRows === 'function') {
    return deps.visibleFileTreeRows();
  }
  return Array.from(document.querySelectorAll('#sidebar-file-tree-root .tree-row[data-shell-mode="filetree"]'))
    .filter(function(row) {
      if (!(row instanceof HTMLElement)) return false;
      if (row.closest('.tree-children--collapsed')) return false;
      return row.offsetParent !== null || row.getClientRects().length > 0;
    });
}

function selectedRowIdSet(selection) {
  var selected = selection && selection.selectedRowIds;
  if (selected instanceof Set) return new Set(selected);
  if (Array.isArray(selected)) return new Set(selected);
  return new Set();
}

function syncSidebarFileTreeSelection(selection, deps) {
  var state = selection || {};
  var selected = selectedRowIdSet(state);
  var focusedRowId = String(state.focusedRowId || '');
  visibleFileTreeRows(deps).forEach(function(row) {
    var rowId = row.getAttribute('data-row-id') || '';
    row.setAttribute('data-selected', String(Boolean(rowId && selected.has(rowId))));
    row.setAttribute('data-focused', String(rowId === focusedRowId));
  });
  var detail = {
    selectedRowIds: Array.from(selected),
    anchorRowId: state.anchorRowId || null,
    focusedRowId: state.focusedRowId || null
  };
  window.dispatchEvent(new CustomEvent('tree.filetree.selection.changed', { detail: detail }));
  return detail;
}

function selectSidebarFileTreeRow(row, selection, modifiers, deps) {
  if (!(row instanceof HTMLElement)) return [];
  var rowId = row.getAttribute('data-row-id') || '';
  if (!rowId) return [];
  var state = selection || {};
  var rows = visibleFileTreeRows(deps);
  var visibleRowIds = rows.map(function(item) { return item.getAttribute('data-row-id') || ''; }).filter(Boolean);
  var selected = selectedRowIdSet(state);
  var shiftKey = Boolean(modifiers && modifiers.shiftKey);
  var ctrlKey = Boolean(modifiers && (modifiers.ctrlKey || modifiers.metaKey));
  if (shiftKey && state.anchorRowId) {
    var anchorIndex = visibleRowIds.indexOf(state.anchorRowId);
    var targetIndex = visibleRowIds.indexOf(rowId);
    if (anchorIndex >= 0 && targetIndex >= 0) {
      selected = new Set(visibleRowIds.slice(Math.min(anchorIndex, targetIndex), Math.max(anchorIndex, targetIndex) + 1));
    } else {
      selected = new Set([rowId]);
      state.anchorRowId = rowId;
    }
  } else if (ctrlKey) {
    if (selected.has(rowId) && selected.size > 1) selected.delete(rowId);
    else selected.add(rowId);
    state.anchorRowId = rowId;
  } else {
    selected = new Set([rowId]);
    state.anchorRowId = rowId;
  }
  state.selectedRowIds = selected;
  state.focusedRowId = rowId;
  syncSidebarFileTreeSelection(state, deps);
  return Array.from(selected);
}

function selectedSidebarFileTreeRowIdsForDrag(row, selection) {
  var rowId = row instanceof HTMLElement ? row.getAttribute('data-row-id') || '' : '';
  var selected = selectedRowIdSet(selection || {});
  if (rowId && selected.has(rowId)) return Array.from(selected);
  return rowId ? [rowId] : [];
}

function selectedSidebarFileTreeRows(selection, deps) {
  var state = selection || {};
  var selectedIds = selectedRowIdSet(state);
  var rows = visibleFileTreeRows(deps).filter(function(row) {
    var rowId = row.getAttribute('data-row-id') || '';
    return rowId && selectedIds.has(rowId);
  });
  if (rows.length > 0) return rows;
  if (state.focusedRowId) {
    var escape = deps && typeof deps.cssEscape === 'function' ? deps.cssEscape : cssEscapeValue;
    var focused = document.querySelector(
      '#sidebar-file-tree-root .tree-row[data-shell-mode="filetree"][data-row-id="' + escape(state.focusedRowId) + '"]'
    );
    if (focused instanceof HTMLElement) return [focused];
  }
  return [];
}

window.__mnoteFileTreeSelectionRuntime = {
  visibleFileTreeRows: visibleFileTreeRows,
  syncSidebarFileTreeSelection: syncSidebarFileTreeSelection,
  selectSidebarFileTreeRow: selectSidebarFileTreeRow,
  selectedSidebarFileTreeRowIdsForDrag: selectedSidebarFileTreeRowIdsForDrag,
  selectedSidebarFileTreeRows: selectedSidebarFileTreeRows
};
