import { useContext as P, useState as j, useRef as y, useEffect as N } from "react";
import { I18nContext as E, ReportNamespaces as v } from "./context.mjs";
import { warnOnce as b, hasLoadedNamespace as z, loadLanguages as R, loadNamespaces as T } from "./utils.mjs";
import { getDefaults as A } from "./defaults.mjs";
import { getI18n as L } from "./i18nInstance.mjs";
const M = (m, n) => {
  const u = y();
  return N(() => {
    u.current = n ? u.current : m;
  }, [m, n]), u.current;
};
function B(m) {
  let n = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
  const {
    i18n: u
  } = n, {
    i18n: C,
    defaultNS: F
  } = P(E) || {}, e = u || C || L();
  if (e && !e.reportNamespaces && (e.reportNamespaces = new v()), !e) {
    b("You will need to pass in an i18next instance by using initReactI18next");
    const r = (i, s) => typeof s == "string" ? s : s && typeof s == "object" && typeof s.defaultValue == "string" ? s.defaultValue : Array.isArray(i) ? i[i.length - 1] : i, o = [r, {}, !1];
    return o.t = r, o.i18n = {}, o.ready = !1, o;
  }
  e.options.react && e.options.react.wait !== void 0 && b("It seems you are still using the old wait option, you may migrate to the new useSuspense behaviour.");
  const g = {
    ...A(),
    ...e.options.react,
    ...n
  }, {
    useSuspense: S,
    keyPrefix: h
  } = g;
  let t = m || F || e.options && e.options.defaultNS;
  t = typeof t == "string" ? [t] : t || ["translation"], e.reportNamespaces.addUsedNamespaces && e.reportNamespaces.addUsedNamespaces(t);
  const c = (e.isInitialized || e.initializedStoreOnce) && t.every((r) => z(r, e, g));
  function f() {
    return e.getFixedT(n.lng || null, g.nsMode === "fallback" ? t : t[0], h);
  }
  const [x, d] = j(f);
  let p = t.join();
  n.lng && (p = `${n.lng}${p}`);
  const w = M(p), a = y(!0);
  N(() => {
    const {
      bindI18n: r,
      bindI18nStore: o
    } = g;
    a.current = !0, !c && !S && (n.lng ? R(e, n.lng, t, () => {
      a.current && d(f);
    }) : T(e, t, () => {
      a.current && d(f);
    })), c && w && w !== p && a.current && d(f);
    function i() {
      a.current && d(f);
    }
    return r && e && e.on(r, i), o && e && e.store.on(o, i), () => {
      a.current = !1, r && e && r.split(" ").forEach((s) => e.off(s, i)), o && e && o.split(" ").forEach((s) => e.store.off(s, i));
    };
  }, [e, p]);
  const I = y(!0);
  N(() => {
    a.current && !I.current && d(f), I.current = !1;
  }, [e, h]);
  const l = [x, e, c];
  if (l.t = x, l.i18n = e, l.ready = c, c || !c && !S)
    return l;
  throw new Promise((r) => {
    n.lng ? R(e, n.lng, t, () => r()) : T(e, t, () => r());
  });
}
export {
  B as useTranslation
};
