import { Container as g } from "unstated";
import { Platform as h } from "@accelbyte/sdk-platform";
import { Buildinfo as m, AvailablePlatform as I } from "@accelbyte/sdk-buildinfo";
import { Ctx as p } from "./accelbyte-widgets33.mjs";
const B = "NO_BUILDINFO", E = "NO_BUILDINFO_FOR_THIS_DEVICE", d = {
  gameEntitlementsRecord: null,
  isFetchingGameEntitlements: !1,
  errorGameEntitlements: null,
  buildManifestRecord: null,
  isFetchingBuildManifest: !1,
  updatedBuildManifestRecord: null,
  isFetchingUpdatedBuildManifest: !1,
  gameInfoRecord: null,
  isFetchingGameInfo: !1,
  diffCache: null,
  isFetchingDiffCache: !1,
  errorDiffCache: null,
  activeGameId: null,
  activeGameItemLocale: null,
  isFetchingActiveGameItemLocale: !1,
  gameSizes: {}
};
class A extends g {
  constructor(n, r) {
    super(), this.sdk = n, this.persistStorage = r, this.setGameBuildManifestError = (t, i) => {
      this.cache.gameBuildManifestErrorRecord[t] = i;
    }, this.setUpdatedGameBuildManifestError = (t, i) => {
      this.cache.updatedGameBuildManifestErrorRecord[t] = i;
    }, this.setGameInfoError = (t, i) => {
      this.cache.gameInfoErrorRecord[t] = i;
    }, this.getGameInfoError = (t) => this.cache.gameInfoErrorRecord[t], this.getGameBuildManifestError = (t) => this.cache.gameBuildManifestErrorRecord[t], this.getUpdatedGameBuildManifestError = (t) => this.cache.updatedGameBuildManifestErrorRecord[t], this.fetchBuildManifest = async (t, i) => {
      var e, a;
      if (!this.state.isFetchingBuildManifest)
        try {
          this.setState({ isFetchingBuildManifest: !0 });
          const s = await this.fetchBuildManifestByGameId(t, i), o = {
            ...this.state.buildManifestRecord,
            [t]: s
          };
          return this.setState({ buildManifestRecord: o }), this.setUpdatedBuildManifest(t, s), (a = this.persistStorage) == null || a.set("buildManifestRecord", {
            ...(e = this.persistStorage) == null ? void 0 : e.get("buildManifestRecord"),
            ...o
          }), this.setGameBuildManifestError(t, null), this.updateGameSize(s), s;
        } catch (s) {
          throw console.error(s), this.setGameBuildManifestError(t, s), s;
        } finally {
          this.setState({ isFetchingBuildManifest: !1 });
        }
    }, this.fetchBuildManifestByGameId = async (t, i) => {
      var f;
      const e = m.DownloaderApi(this.sdk);
      let a;
      try {
        a = await e.getAvailablebuild_ByAppId(t);
      } catch {
        throw new Error(B);
      }
      const s = await this.getMatchPlatform({
        buildsAvailability: a,
        userPlatform: i
      });
      if (!s)
        throw new Error(E);
      const o = (f = this.persistStorage) == null ? void 0 : f.get("buildManifestRecord"), c = o && o[t], l = a.find((u) => u.platformId === s);
      return c && c.buildId === (l == null ? void 0 : l.buildId) && c.launchArguments === (l == null ? void 0 : l.launchArguments) ? c : await e.getUpdategame_ByAppId_ByPlatformId(t, s);
    }, this.getMatchPlatform = ({
      buildsAvailability: t,
      userPlatform: i
    }) => {
      const e = /* @__PURE__ */ new Set();
      for (const s of t)
        s.platformId && e.add(s.platformId);
      const a = this.getCurrentPlatform(i);
      if (a) {
        for (const s in a.targetPlatform)
          if (e.has(a.targetPlatform[s]))
            return a.targetPlatform[s];
      }
      return null;
    }, this.getCurrentPlatform = (t) => {
      const i = t.platform, e = t.arch;
      return I.find(
        (s) => s.platform === i && s.arch.includes(e)
      );
    }, this.fetchUpdatedBuildManifest = async (t, i) => {
      if (!this.state.isFetchingUpdatedBuildManifest)
        try {
          this.setState({ isFetchingUpdatedBuildManifest: !0 });
          const e = await this.fetchBuildManifestByGameId(t, i);
          return this.setUpdatedBuildManifest(t, e), this.setUpdatedGameBuildManifestError(t, null), e;
        } catch (e) {
          throw console.error(e), this.setUpdatedGameBuildManifestError(t, e), e;
        } finally {
          this.setState({ isFetchingUpdatedBuildManifest: !1 });
        }
    }, this.setUpdatedBuildManifest = (t, i) => {
      const e = this.state.updatedBuildManifestRecord || {}, a = {
        [t]: i
      };
      this.setState({
        updatedBuildManifestRecord: {
          ...e,
          ...a
        }
      });
    }, this.fetchGamesInfo = async (t) => {
      var i;
      if (!this.state.isFetchingGameInfo)
        try {
          this.setState({ isFetchingGameInfo: !this.state.gameInfoRecord });
          for (const s of t)
            this.setGameInfoError(s, null);
          const e = await Promise.allSettled(
            t.map(async (s) => await h.ItemApi(this.sdk).getItemsByAppId({ appId: s }))
          ), a = { ...this.state.gameInfoRecord };
          for (let s = 0; s < e.length; s++) {
            const o = e[s], c = t[s];
            o.status === "fulfilled" ? a[c] = o.value : this.setGameInfoError(t[s], o.reason);
          }
          return this.setState({ gameInfoRecord: a }), (i = this.persistStorage) == null || i.set("gameInfoRecord", a), a;
        } catch (e) {
          throw console.error(e), e;
        } finally {
          this.setState({ isFetchingGameInfo: !1 });
        }
    }, this.getDiffCache = async ({ oldBuildId: t, newBuildId: i }) => {
      if (!this.state.isFetchingDiffCache)
        try {
          this.setState({ isFetchingDiffCache: !0 });
          const e = await m.CachingApi(this.sdk).getDestCacheDiff_BySourceBuildId_ByDestinationBuildId(t, i);
          return this.setState({ diffCache: e, errorDiffCache: null, isFetchingDiffCache: !1 }), e;
        } catch (e) {
          throw console.error(e), this.setState({ diffCache: null, errorDiffCache: e, isFetchingDiffCache: !1 }), e;
        }
    }, this.setActiveGame = (t) => {
      var i;
      return (i = this.persistStorage) == null || i.set("activeGameId", t), this.setState({
        activeGameId: t
      });
    }, this.updateGameSize = (t) => {
      const i = t.appId, e = this.state.gameSizes[i];
      (e == null ? void 0 : e.buildId) === t.buildId || (this.setState((s) => ({
        ...s,
        gameSizes: {
          ...s.gameSizes,
          [i]: { size: 0, buildId: t.buildId, status: "processing" }
        }
      })), this.getAppSize(t).then(
        (s) => this.setState({
          gameSizes: {
            ...this.state.gameSizes,
            [i]: {
              ...this.state.gameSizes[i],
              status: "processed",
              size: s
            }
          }
        })
      ).catch(console.error));
    }, this.getAppSize = async (t) => {
      let i = 0;
      if (!(t != null && t.files))
        return i;
      for (const e of t.files)
        i += e.filesize || 0;
      return i;
    }, this.state = {
      ...d,
      gameEntitlementsRecord: (r == null ? void 0 : r.get("gameEntitlementsRecord")) || null,
      gameInfoRecord: (r == null ? void 0 : r.get("gameInfoRecord")) || null,
      activeGameId: (r == null ? void 0 : r.get("activeGameId")) || null
    }, this.cache = {
      gameBuildManifestErrorRecord: {},
      updatedGameBuildManifestErrorRecord: {},
      gameInfoErrorRecord: {}
    };
  }
  async fetchGameEntitlements(n) {
    var t;
    const r = await h.EntitlementApi(this.sdk);
    if (!this.state.isFetchingGameEntitlements)
      try {
        this.setState({ isFetchingGameEntitlements: !0, errorGameEntitlements: null });
        const e = (await r.getEntitlements_ByUserId(n, { entitlementClazz: "APP" })).data;
        if (!e)
          return;
        const a = {};
        for (const s of e)
          s.appId && (a[s.appId] = s);
        return this.setState({ gameEntitlementsRecord: a || null }), (t = this.persistStorage) == null || t.set("gameEntitlementsRecord", a), e;
      } catch (i) {
        throw this.setState({ errorGameEntitlements: i }), i;
      } finally {
        this.setState({ isFetchingGameEntitlements: !1 });
      }
  }
  async fetchActiveGameLocale(n, r) {
    var i;
    if (!n)
      return null;
    const t = (i = p.getUserManager().state.user) == null ? void 0 : i.country;
    try {
      this.setState({ isFetchingActiveGameItemLocale: !0 });
      const e = await h.ItemApi(this.sdk).getLocale_ByItemId(n, {
        region: t,
        language: r
      });
      return this.setState({ activeGameItemLocale: e }), e;
    } catch (e) {
      return console.error(e), null;
    } finally {
      this.setState({ isFetchingActiveGameItemLocale: !1 });
    }
  }
  clear() {
    var n, r, t, i;
    delete d.gameInfoRecord, delete d.activeGameId, this.setState(d), (n = this.persistStorage) == null || n.delete("buildManifestRecord"), (r = this.persistStorage) == null || r.delete("gameEntitlementsRecord"), (t = this.persistStorage) == null || t.delete("gameInfoRecord"), (i = this.persistStorage) == null || i.delete("activeGameId");
  }
}
export {
  A as GameAppManager,
  B as NO_BUILDINFO,
  E as NO_BUILDINFO_FOR_THIS_DEVICE
};
