export const createSidebarFileTreeUploadRuntime = (dependencies = {}) => {
  const {
    cssEscape,
    currentDocumentId,
    fileTreeRuntimeDeps,
    fileTreeRuntimeFunction,
    recordFileTreeAction,
    recordFileTreeActionStatus,
    resolveWorkspaceId,
    rowTitle,
    selectedSidebarFileTreeSelection,
  } = dependencies;
  const sidebarFileTreeSelection = selectedSidebarFileTreeSelection;

  function fileTreeRowsForUploadPreflight() {
    var runtimeFn = fileTreeRuntimeFunction('fileTreeRowsForUploadPreflight');
    if (runtimeFn) return runtimeFn(fileTreeRuntimeDeps());
    return Array.from(document.querySelectorAll('.tree-row[data-shell-mode="filetree"]')).map(function(row) {
      return {
        rowId: row.getAttribute('data-row-id') || '',
        rowKind: row.getAttribute('data-row-kind') || '',
        documentId: row.getAttribute('data-document-id') || row.getAttribute('data-doc-id') || null,
        assetId: row.getAttribute('data-asset-id') || null,
        assetDocumentId: row.getAttribute('data-document-id') || row.getAttribute('data-doc-id') || null,
        assetType: row.querySelector('.tree-kind-badge') ? row.querySelector('.tree-kind-badge').getAttribute('data-kind') : null,
        storagePath: null
      };
    }).filter(function(row) {
      return row.rowId || row.documentId || row.assetId;
    });
  }

  function fileTreeRowCapabilities(row) {
    if (!(row instanceof HTMLElement)) return [];
    try {
      var parsed = JSON.parse(row.getAttribute('data-capabilities') || '[]');
      return Array.isArray(parsed) ? parsed.map(function(item) { return String(item || '').trim(); }).filter(Boolean) : [];
    } catch (_) {
      return [];
    }
  }

  function fileTreeRowIsReadonly(row) {
    return fileTreeRowCapabilities(row).some(function(capability) {
      return ['readonly', 'readOnly', 'permissionDenied'].indexOf(capability) >= 0;
    });
  }

  function blockReadonlyFileTreeAction(action, detail, message) {
    var normalizedAction = String(action || 'drop').trim() || 'drop';
    var text = String(message || '目标位置是只读，不能拖放到这里').trim();
    var targetRowId = String(detail && (detail.targetRowId || detail.rowId) || '').trim();
    var documentId = String(detail && detail.documentId || '').trim();
    var assetId = String(detail && detail.assetId || '').trim();
    recordFileTreeAction(normalizedAction, {
      rowId: targetRowId,
      documentId: documentId,
      assetId: assetId,
      readonly: true
    });
    recordFileTreeActionStatus('blocked', {
      rowId: targetRowId,
      documentId: documentId,
      assetId: assetId,
      readonly: true,
      fallback: 'alert'
    });
    document.documentElement.setAttribute('data-mnote-filetree-readonly-blocked', normalizedAction);
    document.documentElement.setAttribute('data-mnote-filetree-readonly-message', text);
    if (targetRowId) {
      document.documentElement.setAttribute('data-mnote-filetree-readonly-target-row-id', targetRowId);
      var row = document.querySelector('#sidebar-file-tree-root .tree-row[data-shell-mode="filetree"][data-row-id="' + cssEscape(targetRowId) + '"]');
      if (row instanceof HTMLElement) {
        row.setAttribute('data-readonly-blocked', normalizedAction);
        row.setAttribute('data-readonly-message', text);
      }
    }
    window.alert(text);
    return false;
  }

  function fileTreeDocumentParentsForPreflight() {
    var runtimeFn = fileTreeRuntimeFunction('fileTreeDocumentParentsForPreflight');
    if (runtimeFn) return runtimeFn(fileTreeRuntimeDeps());
    return Array.from(document.querySelectorAll('#sidebar-file-tree-root .tree-row[data-shell-mode="filetree"]')).map(function(row) {
      var documentId = row.getAttribute('data-document-id') || row.getAttribute('data-doc-id') || '';
      if (!documentId) return null;
      var parentRowId = row.getAttribute('data-parent-id') || '';
      var parentDocumentId = parentRowId.indexOf('doc:') === 0 ? parentRowId.slice(4) : parentRowId || null;
      return { documentId: documentId, parentId: parentDocumentId };
    }).filter(Boolean);
  }

  function fileTreeTargetChildrenForPreflight(targetRow) {
    var runtimeFn = fileTreeRuntimeFunction('fileTreeTargetChildrenForPreflight');
    if (runtimeFn) return runtimeFn(targetRow, fileTreeRuntimeDeps());
    var node = targetRow instanceof HTMLElement ? targetRow.closest('.tree-node') : null;
    if (!node) return [];
    return Array.from(node.querySelectorAll(':scope > .tree-children > .tree-node > .tree-row[data-shell-mode="filetree"]')).map(function(row) {
      return {
        rowKind: row.getAttribute('data-row-kind') || '',
        documentId: row.getAttribute('data-document-id') || row.getAttribute('data-doc-id') || null,
        assetId: row.getAttribute('data-asset-id') || null,
        title: rowTitle(row)
      };
    });
  }

  function fileTreeDropPreflightRows() {
    var runtimeFn = fileTreeRuntimeFunction('fileTreeDropPreflightRows');
    if (runtimeFn) return runtimeFn(Object.assign({}, fileTreeRuntimeDeps(), {
      fileTreeRowsForUploadPreflight: fileTreeRowsForUploadPreflight
    }));
    return fileTreeRowsForUploadPreflight().map(function(row) {
      var domRow = document.querySelector('#sidebar-file-tree-root .tree-row[data-shell-mode="filetree"][data-row-id="' + cssEscape(row.rowId) + '"]');
      row.title = rowTitle(domRow);
      return row;
    });
  }

  async function ensureFileTreeWritableTarget(action, targetRow, rowIds, copy) {
    var normalizedAction = String(action || 'drop').trim() || 'drop';
    if (!(targetRow instanceof HTMLElement)) return true;
    var detail = {
      targetRowId: targetRow.getAttribute('data-row-id') || '',
      rowId: targetRow.getAttribute('data-row-id') || '',
      documentId: targetRow.getAttribute('data-document-id') || targetRow.getAttribute('data-doc-id') || '',
      assetId: targetRow.getAttribute('data-asset-id') || ''
    };
    if (fileTreeRowIsReadonly(targetRow)) {
      return blockReadonlyFileTreeAction(normalizedAction, detail, '目标位置是只读，不能拖放到这里');
    }
    try {
      var response = await fetch('/api/tree/filetree/drop-preflight', {
        method: 'POST',
        credentials: 'include',
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify({
          workspaceId: resolveWorkspaceId(targetRow),
          copy: Boolean(copy),
          sourceCapabilities: ['read', 'write', 'move'],
          targetCapabilities: fileTreeRowCapabilities(targetRow),
          targetDocumentId: detail.documentId || null,
          targetRowId: detail.targetRowId || null,
          focusedRowId: sidebarFileTreeSelection.focusedRowId || null,
          activeDocumentId: currentDocumentId() || null,
          rowIds: Array.isArray(rowIds) ? rowIds : [],
          rows: fileTreeDropPreflightRows(),
          targetChildren: fileTreeTargetChildrenForPreflight(targetRow),
          documentParents: fileTreeDocumentParentsForPreflight()
        })
      });
      if (response.ok) return true;
      var payload = await response.json().catch(function() { return null; });
      var message = payload && (payload.error || payload.message) ? String(payload.error || payload.message) : '目标位置是只读，不能拖放到这里';
      if (message.indexOf('只读') >= 0 || message.toLowerCase().indexOf('readonly') >= 0) {
        return blockReadonlyFileTreeAction(normalizedAction, detail, message);
      }
      return true;
    } catch (_) {
      return true;
    }
  }

  function fileTreeDocumentWorkspacesForUploadPreflight(workspaceId) {
    var runtimeFn = fileTreeRuntimeFunction('fileTreeDocumentWorkspacesForUploadPreflight');
    if (runtimeFn) {
      return runtimeFn(workspaceId, Object.assign({}, fileTreeRuntimeDeps(), {
        fileTreeRowsForUploadPreflight: fileTreeRowsForUploadPreflight
      }));
    }
    var seen = new Set();
    return fileTreeRowsForUploadPreflight().filter(function(row) {
      if (!row.documentId || seen.has(row.documentId)) return false;
      seen.add(row.documentId);
      return true;
    }).map(function(row) {
      return { documentId: row.documentId, workspaceId: workspaceId || null };
    });
  }

  async function preflightFileTreeUploadTarget(detail) {
    var bodyRuntime = fileTreeRuntimeFunction('fileTreeUploadTargetPreflightBody');
    var body = bodyRuntime ? bodyRuntime(detail || {}, Object.assign({}, fileTreeRuntimeDeps(), {
      focusedRowId: sidebarFileTreeSelection.focusedRowId || null,
      fileTreeRowsForUploadPreflight: fileTreeRowsForUploadPreflight,
      currentDocumentId: currentDocumentId,
      resolveWorkspaceId: resolveWorkspaceId
    })) : (function() {
      var workspaceId = String(detail && detail.workspaceId || resolveWorkspaceId(document.body) || '').trim();
      return {
        workspaceId: workspaceId || null,
        targetDocumentId: detail && detail.documentId ? String(detail.documentId) : null,
        targetRowId: detail && detail.targetRowId ? String(detail.targetRowId) : null,
        focusedRowId: sidebarFileTreeSelection.focusedRowId || null,
        activeDocumentId: currentDocumentId() || null,
        rows: fileTreeRowsForUploadPreflight(),
        documentWorkspaces: fileTreeDocumentWorkspacesForUploadPreflight(workspaceId)
      };
    })();
    var response = await fetch('/api/tree/filetree/upload-target-preflight', {
      method: 'POST',
      credentials: 'include',
      headers: { 'content-type': 'application/json' },
      body: JSON.stringify(body)
    });
    var payload = await response.json().catch(function() { return null; });
    if (!response.ok || !payload || !payload.plan) {
      throw new Error(payload && payload.error ? payload.error : '文件树上传目标预检失败');
    }
    return payload.plan;
  }

  function fallbackFileTreeUploadTarget(detail) {
    var runtimeFn = fileTreeRuntimeFunction('fileTreeUploadTargetFallback');
    if (runtimeFn) {
      return runtimeFn(detail || {}, {
        resolveWorkspaceId: resolveWorkspaceId,
        currentDocumentId: currentDocumentId
      });
    }
    var workspaceId = String(detail && detail.workspaceId || resolveWorkspaceId(document.body) || '').trim();
    var documentId = String(detail && detail.documentId || currentDocumentId() || '').trim();
    if (detail && Object.prototype.hasOwnProperty.call(detail, 'targetRelativePath')) {
      return {
        workspaceId: workspaceId,
        targetDocumentId: documentId,
        targetMindmapId: null,
        targetSubPath: null,
        targetRelativePath: String(detail.targetRelativePath || ''),
        uploadIntent: String(detail.uploadIntent || 'filetree.folder.drop')
      };
    }
    if (!workspaceId || !documentId) {
      throw new Error('请选择一个目标页面后再拖入文件');
    }
    return {
      workspaceId: workspaceId,
      targetDocumentId: documentId,
      targetMindmapId: null,
      targetSubPath: null,
      uploadIntent: String(detail && detail.uploadIntent || 'editor.markdown.attach')
    };
  }

  async function resolveFileTreeUploadTarget(detail) {
    if (detail && Object.prototype.hasOwnProperty.call(detail, 'targetRelativePath')) {
      return fallbackFileTreeUploadTarget(detail || {});
    }
    try {
      var plan = await preflightFileTreeUploadTarget(detail || {});
      var normalizePlanRuntime = fileTreeRuntimeFunction('normalizeFileTreeUploadTargetPlan');
      if (normalizePlanRuntime) {
        return normalizePlanRuntime(detail || {}, plan);
      }
      if (detail && Object.prototype.hasOwnProperty.call(detail, 'targetRelativePath')) {
        plan.targetRelativePath = String(detail.targetRelativePath || '');
      }
      if (detail && detail.uploadIntent) {
        plan.uploadIntent = String(detail.uploadIntent);
      } else if (detail && Object.prototype.hasOwnProperty.call(detail, 'targetRelativePath')) {
        plan.uploadIntent = 'filetree.folder.drop';
      } else if (!plan.uploadIntent) {
        plan.uploadIntent = 'editor.markdown.attach';
      }
      return plan;
    } catch (error) {
      console.warn('[mnote upload] upload target preflight fallback', error);
      return fallbackFileTreeUploadTarget(detail || {});
    }
  }


  return {
    fileTreeRowsForUploadPreflight,
    fileTreeRowCapabilities,
    fileTreeRowIsReadonly,
    blockReadonlyFileTreeAction,
    fileTreeDocumentParentsForPreflight,
    fileTreeTargetChildrenForPreflight,
    fileTreeDropPreflightRows,
    ensureFileTreeWritableTarget,
    fileTreeDocumentWorkspacesForUploadPreflight,
    preflightFileTreeUploadTarget,
    fallbackFileTreeUploadTarget,
    resolveFileTreeUploadTarget,
  };
};
