/* COPYRIGHT Esri - https://js.arcgis.com/5.0/LICENSE.txt */
import { s as O, d as D, e as g, b as I } from "./cardsHelpers.js";
import * as l from "@esri/solution-common";
import { N, y as B, O as T, Q as E, R as y, U as M, B as J } from "./interfaces.js";
class x {
  /**
   * Constructor
   *
   * @param orgUrl URL of organization, e.g., "http://myOrg.maps.arcgis.com"
   * @param portalUrl URL of portal, e.g., "https://www.arcgis.com"
   * @param userSession Authentication
   */
  constructor(r, t, s) {
    this.cMissingImageDataURI = "https://static.arcgis.com/images/solution.png", this.cardCache = [], this.cardCacheParams = {
      q: "",
      categoriesAsStr: "[]",
      sortField: "title",
      sortOrder: "asc"
    }, this.locale = r, this.orgUrl = t, this.portalUrl = s, this.anonAgolSession = new l.UserSession({}), this.agolPortalUrl = N(s);
  }
  /**
   * Adds a card to the cache to keep cache fresh between full refreshes.
   *
   * @param card Card to add
   */
  addToCache(r) {
    this.cardCache.push(r);
  }
  /**
   * Returns the current cache.
   *
   * @returns Cards in the cache
   */
  getCache() {
    return this.cardCache;
  }
  /**
   * Removes a card to the cache to keep cache fresh between full refreshes.
   *
   * @param id Id of card to remove
   */
  removeFromCache(r) {
    this.cardCache = this.cardCache.filter((t) => t.id !== r);
  }
  /**
   * Fetches cards for availale Solutions from the server.
   *
   * @param query AGO query terms and options
   * @param primarySolutionsGroupId Id of a group that's the primary source of Solutions for AGO or Enterprise
   * @param agoBasedEnterpriseSolutionsGroupId Id of an AGO-based set of Enterprise Solutions
   * @param userSession Authentication for thumbnailUrl
   * @param isEnterprise When true we are working with an enterprise portal
   * @param signal AbortController signal
   * @param pagingParams Parameters for how the request is to be batched
   * @param acceptableIds A set of item ids that the results must be a part of; if not defined, then there's no restriction
   * @returns A promise resolving to a collection of available Solutions as cards as well as paging information about
   * where those cards came from in the fetcher cache; in case of failure, the promise resolves to an error message
   */
  requestAvailableSolutionCards(r, t, s, e, i, c, a, o) {
    const C = a?.start ? a.start : 1, f = a?.num ? a.num : 24, p = this.portalUrl + "/sharing/rest", u = this.agolPortalUrl + "/sharing/rest", P = this.anonAgolSession, F = JSON.stringify(r.categories);
    if (this.cardCacheParams.q !== r.q || this.cardCacheParams.categoriesAsStr !== F || r.sortField === "relevance" ? (this.cardCache = [], this.cardCacheParams = {
      q: r.q,
      categoriesAsStr: F,
      sortField: r.sortField,
      sortOrder: r.sortOrder
    }) : (this.cardCacheParams.sortField !== r.sortField || this.cardCacheParams.sortOrder !== r.sortOrder) && (this.cardCacheParams.sortField = r.sortField, this.cardCacheParams.sortOrder = r.sortOrder, this.cardCache = O(
      this.cardCache,
      this.cardCacheParams.sortField,
      this.cardCacheParams.sortOrder
    )), this.cardCache.length > 0) {
      let n;
      if (o && o.size > 0) {
        const d = D(this.cardCache, o);
        n = g(d, C, f);
      } else
        n = g(this.cardCache, C, f);
      return Promise.resolve(n);
    }
    const w = {
      filter: r.filter,
      sortField: r.sortField,
      sortOrder: r.sortOrder,
      categories: r?.categories ? this.convertSearchCategories(r.categories) : "",
      signal: c
    }, S = [];
    if (t && !i) {
      const n = e || new l.UserSession({});
      S.push(
        l.searchGroupAllContents(
          t,
          r.q,
          n,
          w,
          p
        )
      );
    }
    return s && i && S.push(
      l.searchGroupAllContents(
        s,
        r.q,
        P,
        w,
        u
      )
    ), Promise.allSettled(S).then((n) => {
      const d = [];
      n.forEach((m) => {
        if (m.status === "fulfilled") {
          const A = m.value;
          let v = "", R = !1;
          v = this.agolPortalUrl, R = !0, A.results.forEach((b) => {
            b.sourcePortalUrl = v, b.knownToBePublicSource = R;
          }), d.push(A);
        } else if (m.status === "rejected")
          throw new Error(
            m.reason.message ? m.reason.message : "cannotAccessAGO"
            // (isPrimary
            // // A failed fetch of the primary group in enterprise or AGO
            // ? result.reason.message
            // // We're in enterprise and configured to search AGO (because agoBasedEnterpriseSolutionsGroupId
            // // is defined), but appear not to be able to reach the internet
            // : "enterpriseCannotAccessAGO"
            // ) as string
          );
      }), d.length === 0 ? this.cardCache = [] : d.length === 1 ? this.cardCache = this.getCardsFromResponse(d[0]) : this.cardCache = O(
        this.getCardsFromResponse(this.mergeResponses(d)),
        this.cardCacheParams.sortField,
        this.cardCacheParams.sortOrder
      );
      let U;
      if (o && o.size > 0) {
        const m = D(this.cardCache, o);
        U = g(m, C, f);
      } else
        U = g(this.cardCache, C, f);
      return Promise.resolve(U);
    }).catch((n) => Promise.reject(new Error(n.message)));
  }
  /**
   * Fetches cards for deployed Solutions from the server.
   *
   * @param query AGO query terms and options
   * @param userSession Authentication for thumbnailUrl
   * @returns A collection of deployed Solutions as cards; the paging information shows that all of the cards
   * are returned
   */
  requestDeployedSolutionCards(r, t, s = "", e) {
    const i = this.portalUrl + "/sharing/rest";
    if (e.aborted)
      return Promise.resolve([]);
    if (this.cardCacheParams.q !== r.q || this.cardCacheParams.categoriesAsStr !== JSON.stringify(r.q) || r.sortField === "relevance" ? (this.cardCache = [], this.cardCacheParams = {
      q: r.q,
      categoriesAsStr: "[]",
      sortField: r.sortField,
      sortOrder: r.sortOrder
    }) : (this.cardCacheParams.sortField !== r.sortField || this.cardCacheParams.sortOrder !== r.sortOrder) && (this.cardCacheParams.sortField = r.sortField, this.cardCacheParams.sortOrder = r.sortOrder, this.cardCache = O(
      this.cardCache,
      this.cardCacheParams.sortField,
      this.cardCacheParams.sortOrder
    )), e.aborted)
      return Promise.resolve([]);
    if (this.cardCache.length > 0) {
      const a = g(this.cardCache, 1, this.cardCache.length);
      return Promise.resolve(a);
    }
    const c = {
      q: r.q,
      filter: r.filter,
      sortField: r.sortField,
      sortOrder: r.sortOrder,
      authentication: t,
      portal: i,
      categories: r?.categories ? JSON.stringify(r.categories) : "",
      num: r.num,
      signal: e
    };
    return s ? l.getItemBase(s, t).then((a) => {
      if (e.aborted)
        return Promise.resolve([]);
      this.cardCache = this.getCardsFromResponse({ results: [a] });
      const o = g(this.cardCache, 1, this.cardCache.length);
      return Promise.resolve(o);
    }).catch((a) => Promise.reject(new Error(a))) : l.searchAllItems(c).then((a) => {
      this.cardCache = this.getCardsFromResponse(a);
      const o = g(this.cardCache, 1, this.cardCache.length);
      return Promise.resolve(o);
    }).catch((a) => Promise.reject(new Error(a)));
  }
  // ---------------------------------------------------------------------------------------------------------------- //
  /**
   * Stringifies categories for search.
   *
   * @param categories AGO item categories, e.g., "/Categories/Conservation"
   * or ["/Categories/Conservation", "/Categories/Pipeline"]
   * @returns Categories where each element is a stringified array of categories
   */
  convertSearchCategories(r) {
    return r && (Array.isArray(r) ? r = r.map(
      (t) => JSON.stringify(Array.isArray(t) ? t : [t])
      // force to an array to allow categories with commas
    ) : r = JSON.stringify([r])), r;
  }
  /**
   * Constructs Solution cards from a Solution-query response.
   *
   * @param response Response from a query
   * @returns Solution information as cards
   */
  getCardsFromResponse(r) {
    return r.results.length > 0 ? l.sanitizeJSON(r.results).map(
      (e) => {
        const i = e.sourcePortalUrl ? e.sourcePortalUrl : this.portalUrl, c = e.sourcePortalUrl ? e.sourcePortalUrl : this.orgUrl, a = {
          id: e.id,
          title: e.title,
          snippet: e.snippet || "",
          description: e.description || "",
          url: e.url || "",
          itemUrl: `${c}/home/item.html` + M([{ k: "id", v: e.id }]) || "",
          thumbnailFilename: e.thumbnail,
          thumbnailUrl: y(
            e.id,
            e.thumbnail,
            this.cMissingImageDataURI,
            i
          ),
          tryitUrl: e.url || "",
          typeKeywords: e.typeKeywords,
          learnMoreUrl: e.properties?.learnMoreUrl || "",
          createdMs: e.created,
          created: E(e.created, this.locale),
          modified: E(e.modified, this.locale),
          numViews: e.numViews,
          tags: e.tags,
          categories: e.groupCategories && e.groupCategories.length > 0 ? e.groupCategories : e.categories || [],
          licenseInfo: T(e.licenseInfo),
          deployCommonId: B(e.typeKeywords || [], "solutionid-"),
          deployVersion: B(e.typeKeywords || [], "solutionversion-"),
          canDelete: e.created > 16183314e5,
          // Only solutions deployed after April 13, 2021 at 9:30PM can be deleted (9.1 release)
          preview: this.preparePreviewImageUrls(e.id, e.properties?.preview, i),
          sourcePortalUrl: e.sourcePortalUrl || "",
          knownToBePublicSource: e.knownToBePublicSource || !1,
          waitId: "",
          relatedSolutions: l.getProp(e, "properties.relatedSolutions") || [],
          owner: e.owner
        };
        return a.deployCommonId !== "" && a.deployVersion !== "" ? a : null;
      }
    ).filter((e) => e != null) : [];
  }
  /**
   * Merge a set of search responses into a single response item.
   *
   * @param responseSet Array of search results
   * @returns A response item that takes its query from the first item in the set and sets the other properties
   * as if all of the responses are the result of one, large query that's independent of AGO's 100-item limit.
   */
  mergeResponses(r) {
    let t = 0;
    r.forEach((e) => t += e.total);
    let s = [];
    return r.forEach((e) => s = s.concat(e.results)), {
      query: r[0].query,
      start: 1,
      num: t,
      nextStart: -1,
      total: t,
      results: s
    };
  }
  /**
   * Converts image preview information into a URL pointing to that image; returns non-image previews unchanged.
   *
   * @param id Item id to insert into URL
   * @param preview List of previews to modify
   * @returns Copy of previews with iamge previews modified
   */
  preparePreviewImageUrls(r, t, s) {
    return t ? t.map(
      (e) => (e.format === "image" && (e.name = s + "/sharing/rest/content/items/" + r + "/resources/" + e.name), e)
    ) : [];
  }
}
async function z(h, r, t, s, e = J, i = "created", c = "desc", a = !1, o = [], C = [], f, p, u) {
  if (!h?.IsSignedIn)
    return;
  const P = {
    q: e,
    filter: "type:Solution",
    sortField: i,
    sortOrder: c,
    delay: a,
    categories: o,
    num: 100
  };
  return P.q += k(h, p), await K(
    r,
    P,
    s,
    C,
    u,
    f
  );
}
function k(h, r) {
  let t = "";
  const s = h.PortalUserOrg, e = h.PortalUserName;
  return s && (t += " orgid:" + s), r !== "My organization's solutions" && e && (t += " owner:" + e), t;
}
async function K(h, r, t, s, e = "", i) {
  const c = await t.requestDeployedSolutionCards(r, h, e, i), a = I(c.cards, s);
  return {
    cards: c.cards,
    relatedSolutions: a
  };
}
export {
  x as C,
  z as g
};
