function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
import { useCallback, useEffect, useRef, useState } from 'react';
import { ALL_TAB_KEY } from "../types";

/**
 * useProviderSearch
 *
 * 职责：
 * 1. 按当前 keyword + activeTab 触发对应 Provider 的 search；
 *    - All 模式：并发触发所有 enabled provider，每条结果独立写入状态（先到先显示）；
 *    - 单 Tab 模式：仅触发对应 provider；
 * 2. 用 AbortController 取消上一轮 in-flight 请求；
 *    - 每个 provider 一个 controller，避免互相影响；
 * 3. 切换 keyword / activeTab / providers 时自动重新调度；
 * 4. 暴露 refresh() 主动重跑当前调度。
 */

var emptyState = {
  loading: false,
  list: [],
  total: 0
};
export function useProviderSearch(options) {
  var keyword = options.keyword,
    activeTab = options.activeTab,
    providers = options.providers,
    allModePageSize = options.allModePageSize,
    singleModePageSize = options.singleModePageSize,
    mode = options.mode,
    onRealtimePatchItems = options.onRealtimePatchItems;
  var _useState = useState(function () {
      return initStateMap(providers);
    }),
    _useState2 = _slicedToArray(_useState, 2),
    stateMap = _useState2[0],
    setStateMap = _useState2[1];

  // 每个 provider 一个 AbortController（最新一次请求）
  var controllersRef = useRef(new Map());
  var realtimeCleanupRef = useRef(new Map());

  // 用 ref 暂存最新依赖，避免 useCallback 频繁重建
  var latestRef = useRef({
    keyword: keyword,
    activeTab: activeTab,
    providers: providers,
    allModePageSize: allModePageSize,
    singleModePageSize: singleModePageSize,
    mode: mode,
    onRealtimePatchItems: onRealtimePatchItems
  });
  latestRef.current = {
    keyword: keyword,
    activeTab: activeTab,
    providers: providers,
    allModePageSize: allModePageSize,
    singleModePageSize: singleModePageSize,
    mode: mode,
    onRealtimePatchItems: onRealtimePatchItems
  };
  var updateProviderState = useCallback(function (key, patch) {
    setStateMap(function (prev) {
      var _prev$key;
      return _objectSpread(_objectSpread({}, prev), {}, _defineProperty({}, key, _objectSpread(_objectSpread({}, (_prev$key = prev[key]) !== null && _prev$key !== void 0 ? _prev$key : emptyState), patch)));
    });
  }, []);

  /**
   * 将实时 delta patch 到当前 provider 已加载列表，仅替换已有项。
   *
   * @example
   * patchProviderRealtimeItems('order', [{ order_id: 1001, status: 'paid' }]);
   */
  var patchProviderRealtimeItems = useCallback(function (key, deltaItems) {
    if (!Array.isArray(deltaItems) || deltaItems.length === 0) return;
    setStateMap(function (prev) {
      var _prev$key2, _state$list;
      var state = (_prev$key2 = prev[key]) !== null && _prev$key2 !== void 0 ? _prev$key2 : emptyState;
      var deltaMap = new Map();
      deltaItems.forEach(function (item) {
        var itemKey = getRealtimeItemKey(item);
        if (itemKey) deltaMap.set(itemKey, item);
      });
      if (deltaMap.size === 0) return prev;
      var changed = false;
      var nextList = ((_state$list = state.list) !== null && _state$list !== void 0 ? _state$list : []).map(function (item) {
        var itemKey = getRealtimeItemKey(item);
        if (!itemKey) return item;
        var nextItem = deltaMap.get(itemKey);
        if (!nextItem) return item;
        changed = true;
        // 实时推送可能只带「变更字段」的精简对象，整体替换会清空其它字段导致内容闪烁；
        // 用浅合并仅覆盖推送带来的字段，保留已加载的完整字段。
        return _objectSpread(_objectSpread({}, item), nextItem);
      });
      if (!changed) return prev;
      return _objectSpread(_objectSpread({}, prev), {}, _defineProperty({}, key, _objectSpread(_objectSpread({}, state), {}, {
        list: nextList
      })));
    });
  }, []);
  var runOne = useCallback(function (provider, pageSize, keywordSnapshot, modeSnapshot, scopeSnapshot) {
    var _controllersRef$curre, _realtimeCleanupRef$c;
    // 取消上一轮
    (_controllersRef$curre = controllersRef.current.get(provider.key)) === null || _controllersRef$curre === void 0 || _controllersRef$curre.abort();
    (_realtimeCleanupRef$c = realtimeCleanupRef.current.get(provider.key)) === null || _realtimeCleanupRef$c === void 0 || _realtimeCleanupRef$c();
    realtimeCleanupRef.current.delete(provider.key);
    var controller = new AbortController();
    controllersRef.current.set(provider.key, controller);
    var realtimeSubscriberId = "global-search-".concat(String(provider.key), "-").concat(scopeSnapshot);
    updateProviderState(provider.key, {
      loading: true,
      error: undefined
    });
    provider.search({
      keyword: keywordSnapshot,
      pageSize: pageSize,
      signal: controller.signal,
      mode: modeSnapshot,
      scope: scopeSnapshot,
      onRealtimePatch: function onRealtimePatch(items) {
        var _latestRef$current$on, _latestRef$current;
        patchProviderRealtimeItems(provider.key, items);
        (_latestRef$current$on = (_latestRef$current = latestRef.current).onRealtimePatchItems) === null || _latestRef$current$on === void 0 || _latestRef$current$on.call(_latestRef$current, provider.key, items);
      },
      realtimeSubscriberId: realtimeSubscriberId,
      onRealtimeCleanup: function onRealtimeCleanup(cleanup) {
        realtimeCleanupRef.current.set(provider.key, cleanup);
      }
    }).then(function (result) {
      var _result$list, _result$total;
      if (controller.signal.aborted) return;
      updateProviderState(provider.key, {
        loading: false,
        list: (_result$list = result.list) !== null && _result$list !== void 0 ? _result$list : [],
        total: (_result$total = result.total) !== null && _result$total !== void 0 ? _result$total : 0,
        resolvedKeyword: keywordSnapshot,
        error: undefined
      });
    }).catch(function (err) {
      if (controller.signal.aborted) return;
      // AbortError 也忽略（fetch 在 abort 后 reject）
      if (err instanceof Error && err.name === 'AbortError') return;
      updateProviderState(provider.key, {
        loading: false,
        error: err instanceof Error ? err : new Error(String(err))
      });
    });
  }, [patchProviderRealtimeItems, updateProviderState]);
  var schedule = useCallback(function () {
    var _latestRef$current2 = latestRef.current,
      k = _latestRef$current2.keyword,
      tab = _latestRef$current2.activeTab,
      ps = _latestRef$current2.providers,
      allSize = _latestRef$current2.allModePageSize,
      singleSize = _latestRef$current2.singleModePageSize,
      m = _latestRef$current2.mode;
    if (tab === ALL_TAB_KEY) {
      ps.forEach(function (p) {
        return runOne(p, allSize, k, m, 'all');
      });
    } else {
      var provider = ps.find(function (p) {
        return p.key === tab;
      });
      if (provider) {
        runOne(provider, singleSize, k, m, 'single');
      }
    }
  }, [runOne]);

  // 调度变化时重新跑
  useEffect(function () {
    schedule();
    // providers 数组身份变化时也重新跑；调用方应该用 useMemo 稳定它
    // mode 变化等同于一次重新搜索（视角变了，结果可能不同）
  }, [keyword, activeTab, providers, mode, schedule]);

  // providers 变更时，补齐 stateMap 的 key
  useEffect(function () {
    setStateMap(function (prev) {
      var next = _objectSpread({}, prev);
      providers.forEach(function (p) {
        if (!next[p.key]) next[p.key] = _objectSpread({}, emptyState);
      });
      return next;
    });
  }, [providers]);

  // 卸载时取消所有
  useEffect(function () {
    var controllers = controllersRef.current;
    var realtimeCleanups = realtimeCleanupRef.current;
    return function () {
      controllers.forEach(function (c) {
        return c.abort();
      });
      controllers.clear();
      realtimeCleanups.forEach(function (cleanup) {
        return cleanup();
      });
      realtimeCleanups.clear();
    };
  }, []);
  return {
    stateMap: stateMap,
    refresh: schedule
  };
}
function initStateMap(providers) {
  var map = {};
  providers.forEach(function (p) {
    map[p.key] = _objectSpread({}, emptyState);
  });
  return map;
}

/**
 * 提取实时 patch 的行主键。
 *
 * @example
 * const key = getRealtimeItemKey({ order_id: 1001 });
 */
function getRealtimeItemKey(item) {
  var _ref, _obj$order_id;
  if (!item || _typeof(item) !== 'object') return null;
  var obj = item;
  var raw = (_ref = (_obj$order_id = obj.order_id) !== null && _obj$order_id !== void 0 ? _obj$order_id : obj.id) !== null && _ref !== void 0 ? _ref : obj.key;
  if (raw === undefined || raw === null || raw === '') return null;
  return String(raw);
}