"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.resolveInitBeforeLoadUser = exports.default = exports.applyResolvedUserToStore = void 0;
var _apiClient = _interopRequireWildcard(require("../networking/apiClient"));
var _auth = require("../networking/api-requests/auth.api");
var _user = require("../networking/api-requests/user.api");
var _roomStore = require("../roomStore");
var _chatSettingsSlice = require("../roomStore/chatSettingsSlice");
var _walletUsername = require("./walletUsername");
var _useLocalStorage = require("../hooks/useLocalStorage");
var _LOCAL_STORAGE = require("./constants/LOCAL_STORAGE");
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
const getStatusCode = error => {
  const status = error?.response?.status;
  return typeof status === 'number' ? status : null;
};
const isAuthError = error => {
  const code = getStatusCode(error);
  return code === 401 || code === 403;
};
const isAbortError = error => {
  const message = error?.message || '';
  return typeof message === 'string' && message.toLowerCase().includes('abort');
};
const hasXmppCredentials = user => Boolean(user?.xmppPassword && (user?.xmppUsername || user?.defaultWallet?.walletAddress));
const normalizeUserForXmpp = user => {
  if (!user) {
    return null;
  }
  const normalizedXmppUsername = user.xmppUsername || (0, _walletUsername.walletToUsername)(user?.defaultWallet?.walletAddress || '');
  return {
    ...user,
    xmppUsername: normalizedXmppUsername
  };
};
const refreshWithToken = async refreshToken => {
  const response = await _apiClient.default.post('/users/login/refresh', {}, {
    headers: {
      Authorization: refreshToken
    }
  });
  return {
    token: response?.data?.token || '',
    refreshToken: response?.data?.refreshToken || refreshToken
  };
};
const mergeUsers = (base, patch) => {
  if (!base && !patch) {
    return null;
  }
  return {
    ...(base || {}),
    ...(patch || {}),
    defaultWallet: {
      walletAddress: patch?.defaultWallet?.walletAddress || base?.defaultWallet?.walletAddress || ''
    }
  };
};
const tryHydrateViaMy = async (candidate, myEndpoint, signal) => {
  if (signal?.aborted) {
    return null;
  }
  const mergedCandidate = normalizeUserForXmpp(candidate);
  if (!candidate?.token && !candidate?.refreshToken) {
    return mergedCandidate;
  }
  let workingToken = candidate?.token || '';
  let workingRefresh = candidate?.refreshToken || '';
  const candidateWithCurrentTokens = () => ({
    ...candidate,
    token: workingToken || candidate.token,
    refreshToken: workingRefresh || candidate.refreshToken
  });
  const fallbackWithCreds = () => {
    const normalized = normalizeUserForXmpp(candidateWithCurrentTokens());
    if (normalized && hasXmppCredentials(normalized)) {
      return normalized;
    }
    return null;
  };
  if (workingToken) {
    try {
      const myUser = await (0, _user.getMyUser)({
        token: workingToken,
        endpoint: myEndpoint
      });
      const merged = normalizeUserForXmpp(mergeUsers(candidate, myUser));
      if (merged) {
        merged.token = workingToken || merged.token;
        merged.refreshToken = workingRefresh || merged.refreshToken;
      }
      return merged;
    } catch (error) {
      if (signal?.aborted || isAbortError(error)) {
        return null;
      }
      if (isAuthError(error)) {
        if (!workingRefresh) {
          return fallbackWithCreds();
        }
        // fall through to refresh path
      } else {
        const fallback = fallbackWithCreds();
        return fallback || null;
      }
    }
  }
  if (!workingRefresh) {
    return mergedCandidate;
  }
  try {
    const refreshed = await refreshWithToken(workingRefresh);
    workingToken = refreshed.token;
    workingRefresh = refreshed.refreshToken;
    try {
      const myUser = await (0, _user.getMyUser)({
        token: workingToken,
        endpoint: myEndpoint
      });
      const merged = normalizeUserForXmpp(mergeUsers(candidateWithCurrentTokens(), myUser));
      if (merged) {
        merged.token = workingToken || merged.token;
        merged.refreshToken = workingRefresh || merged.refreshToken;
      }
      return merged;
    } catch (myError) {
      if (signal?.aborted || isAbortError(myError)) {
        return null;
      }
      const fallback = fallbackWithCreds();
      if (fallback) {
        return fallback;
      }
      if (isAuthError(myError)) {
        return null;
      }
      throw myError;
    }
  } catch (error) {
    if (signal?.aborted || isAbortError(error)) {
      return null;
    }
    if (isAuthError(error)) {
      return null;
    }
    throw error;
  }
};
const resolveInitBeforeLoadUser = async options => {
  const {
    config,
    signal
  } = options || {};
  if (signal?.aborted) {
    return null;
  }
  if (config?.baseUrl) {
    (0, _apiClient.setBaseURL)(config.baseUrl, config.customAppToken);
  }
  const myEndpoint = config?.initBeforeLoadAuth?.myEndpoint || '/users/my';

  // Priority 1: explicit userLogin
  const explicitUser = config?.userLogin?.enabled ? config?.userLogin?.user : null;
  if (explicitUser) {
    const candidate = normalizeUserForXmpp(explicitUser);
    if (candidate && hasXmppCredentials(candidate)) {
      return candidate;
    }
    const hydrated = await tryHydrateViaMy(explicitUser, myEndpoint, signal).catch(() => null);
    if (hydrated && hasXmppCredentials(hydrated)) {
      return hydrated;
    }
    return null;
  }

  // Priority 2: customLogin function
  if (config?.customLogin?.enabled && config?.customLogin?.loginFunction) {
    try {
      const customUser = await config.customLogin.loginFunction();
      if (customUser) {
        const candidate = normalizeUserForXmpp(customUser);
        if (candidate && hasXmppCredentials(candidate)) {
          return candidate;
        }
        const hydrated = await tryHydrateViaMy(customUser, myEndpoint, signal).catch(() => null);
        if (hydrated && hasXmppCredentials(hydrated)) {
          return hydrated;
        }
      }
    } catch (error) {
      if (signal?.aborted || isAbortError(error) || isAuthError(error)) {
        return null;
      }
    }
  }

  // Priority 3: jwtLogin (legacy)
  if (config?.jwtLogin?.enabled && config?.jwtLogin?.token) {
    try {
      const jwtUser = await (0, _auth.loginViaJwt)(config.jwtLogin.token);
      const normalized = normalizeUserForXmpp(jwtUser);
      if (normalized && hasXmppCredentials(normalized)) {
        return normalized;
      }
    } catch (error) {
      if (signal?.aborted || isAbortError(error) || isAuthError(error)) {
        return null;
      }
      throw error;
    }
  }

  // Priority 4: redux store user (in-memory hot path)
  const currentUser = _roomStore.store.getState().chatSettingStore.user;
  if (currentUser?.token || currentUser?.refreshToken || currentUser?.xmppPassword) {
    const hydrated = await tryHydrateViaMy(currentUser, myEndpoint, signal).catch(() => null);
    if (hydrated && hasXmppCredentials(hydrated)) {
      return hydrated;
    }
  }

  // Priority 5: persisted user in AsyncStorage
  try {
    const storedUser = await (0, _useLocalStorage.asyncLocalStorage)(_LOCAL_STORAGE.localStorageConstants.ETHORA_USER).get();
    if (storedUser && (storedUser.token || storedUser.refreshToken || storedUser.xmppPassword)) {
      const hydrated = await tryHydrateViaMy(storedUser, myEndpoint, signal).catch(() => null);
      if (hydrated && hasXmppCredentials(hydrated)) {
        return hydrated;
      }
      await (0, _useLocalStorage.asyncLocalStorage)(_LOCAL_STORAGE.localStorageConstants.ETHORA_USER).remove();
    }
  } catch {
    // ignore storage errors
  }
  return null;
};
exports.resolveInitBeforeLoadUser = resolveInitBeforeLoadUser;
const applyResolvedUserToStore = user => {
  if (!user) {
    return;
  }
  _roomStore.store.dispatch((0, _chatSettingsSlice.setUser)(user));
};
exports.applyResolvedUserToStore = applyResolvedUserToStore;
var _default = exports.default = resolveInitBeforeLoadUser;
//# sourceMappingURL=resolveInitBeforeLoadUser.js.map