import { useCallback, useMemo } from 'react';
import { request } from '@atlaskit/linking-common';
import { fg } from '@atlaskit/platform-feature-flags';
import { getCurrentSiteCloudId } from '../use-current-site-cloud-id';
import { queryIncomingOutgoingLinks as queryIncomingOutgoingAris } from './query';
/**
 * @param baseUriWithNoTrailingSlash base url which will then be appended with /gateway/api/graphql to make requests to AGG
 */
const useIncomingOutgoingAri = (baseUriWithNoTrailingSlash = '') => {
  const aggRequestCall = useCallback(async (body, headers) => request('post', baseUriWithNoTrailingSlash + '/gateway/api/graphql', body, headers, [200]), [baseUriWithNoTrailingSlash]);
  const getCurrentSiteId = useCallback(async () => {
    try {
      const response = await request('get', baseUriWithNoTrailingSlash + '/_edge/tenant_info');
      return response === null || response === void 0 ? void 0 : response.cloudId;
    } catch {
      return undefined;
    }
  }, [baseUriWithNoTrailingSlash]);
  const getSiteId = useCallback(async resourceAri => {
    // ARI pattern that matches both formats:
    // - New format: ari:cloud:<resource_owner>::<resource_type>/<resource_id>
    // - Legacy format: ari:cloud:<resource_owner>:<cloud_id>:<resource_type>/<resource_id>
    //
    // Capture groups:
    // 1: resource_owner - [a-z][a-z.-]+
    // 2: cloud_id (siteId) - [a-zA-Z0-9_.-]+ (empty for new format, but since we need to return the siteId, we only use legacy one)
    // 3: resource_type - [a-z][a-zA-Z.-]
    // 4: resource_id
    //
    // See https://developer.atlassian.com/platform/atlassian-resource-identifier/spec/ari-latest/#syntax for more details
    const ariPattern = /^ari:cloud:([a-z][a-z.-]+):([a-zA-Z0-9_.-]+):([a-z][a-zA-Z.-]+)\/(.+)$/;
    const match = resourceAri.match(ariPattern);
    if (match && match[2]) {
      return match[2]; // Return the cloud_id (siteId)
    }
    return fg('platform_sl_3p_preauth_soc_proof_inline_killswitch') ? await getCurrentSiteCloudId(baseUriWithNoTrailingSlash) : await getCurrentSiteId();
  }, [getCurrentSiteId, baseUriWithNoTrailingSlash]);
  const getIncomingOutgoingAris = useCallback(
  /**
   * Returning aris linking to (outgoing) and from (incoming) a given ari from AGS using
   * https://developer.atlassian.com/cloud/ari-graph-store/relationships/content-referenced-entity/#query
   * @param ari the ari for which the incoming outgoing aris are to be retrieved
   * @param firstIncoming The maximum count of incoming relationships to fetch. Must not exceed 1000. This max limit is handled by AGG itself. Default is 50 (ORS batch max limit)
   * @param firstOutgoing The maximum count of outgoing relationships to fetch. Must not exceed 1000. This max limit is handled by AGG itself. Default is 50 (ORS batch max limit)
   *
   */
  async (ari, firstIncoming = 50, firstOutgoing = 50) => {
    var _response$data$graphS, _response$data, _response$data$graphS2, _response$data$graphS3, _response$data$graphS4, _response$data$graphS5, _response$data$graphS6, _response$data2, _response$data2$graph, _response$data2$graph2, _response$data2$graph3, _response$data2$graph4;
    const siteId = await getSiteId(ari);
    if (!siteId) {
      return {
        incomingAris: [],
        outgoingAris: []
      };
    }
    const headers = {
      'X-Query-Context': `ari:cloud:platform::site/${siteId}`
    };
    const response = await aggRequestCall({
      variables: {
        id: ari,
        firstIncoming,
        firstOutgoing
      },
      query: queryIncomingOutgoingAris
    }, headers);
    const incomingAris = (_response$data$graphS = response === null || response === void 0 ? void 0 : (_response$data = response.data) === null || _response$data === void 0 ? void 0 : (_response$data$graphS2 = _response$data.graphStore) === null || _response$data$graphS2 === void 0 ? void 0 : (_response$data$graphS3 = _response$data$graphS2.incoming) === null || _response$data$graphS3 === void 0 ? void 0 : (_response$data$graphS4 = _response$data$graphS3.aris) === null || _response$data$graphS4 === void 0 ? void 0 : (_response$data$graphS5 = _response$data$graphS4.map(node => node === null || node === void 0 ? void 0 : node.id)) === null || _response$data$graphS5 === void 0 ? void 0 : _response$data$graphS5.filter(id => !!id)) !== null && _response$data$graphS !== void 0 ? _response$data$graphS : [];
    const outgoingAris = (_response$data$graphS6 = response === null || response === void 0 ? void 0 : (_response$data2 = response.data) === null || _response$data2 === void 0 ? void 0 : (_response$data2$graph = _response$data2.graphStore) === null || _response$data2$graph === void 0 ? void 0 : (_response$data2$graph2 = _response$data2$graph.outgoing) === null || _response$data2$graph2 === void 0 ? void 0 : (_response$data2$graph3 = _response$data2$graph2.aris) === null || _response$data2$graph3 === void 0 ? void 0 : (_response$data2$graph4 = _response$data2$graph3.map(node => node === null || node === void 0 ? void 0 : node.id)) === null || _response$data2$graph4 === void 0 ? void 0 : _response$data2$graph4.filter(id => !!id)) !== null && _response$data$graphS6 !== void 0 ? _response$data$graphS6 : [];
    return {
      incomingAris,
      outgoingAris
    };
  }, [aggRequestCall, getSiteId]);
  return useMemo(() => ({
    getIncomingOutgoingAris
  }), [getIncomingOutgoingAris]);
};
export default useIncomingOutgoingAri;