import _defineProperty from "@babel/runtime/helpers/defineProperty";
import { StorageClient } from '@atlaskit/frontend-utilities/storage-client';
import { getCurrentSiteCloudId, getCurrentSiteCloudIdSync } from '../current-site-cloud-id';
const BASE_URL = '/gateway/api/tap-delivery/api/v3/personalization';
export const PERSONALIZATION_STORAGE_SCOPE = 'smart-card-social-proof';
export const PERSONALIZATION_STORAGE_ITEM_KEY_PREFIX = 'pct-map:v1:';
export const PERSONALIZATION_PROVIDER_PCT_TTL_MS = 24 * 60 * 60 * 1000;
export const SOCIAL_PROOF_TRAIT_NAME = 'sl_3p_connected_providers_site_pct';
const smartCardStorage = new StorageClient(PERSONALIZATION_STORAGE_SCOPE);

/** Keys written by this service in localStorage when using {@link smartCardStorage}. */
const LOCAL_STORAGE_ROW_KEY_PREFIX = `${PERSONALIZATION_STORAGE_SCOPE}_${PERSONALIZATION_STORAGE_ITEM_KEY_PREFIX}`;
function scopedCacheKey(cloudId, traitName) {
  return `${cloudId}:${traitName}`;
}
function pctMapStorageItemKey(cloudId, traitName) {
  return `${PERSONALIZATION_STORAGE_ITEM_KEY_PREFIX}${encodeURIComponent(cloudId)}:${encodeURIComponent(traitName)}`;
}
async function fetchSiteTraits(cloudId) {
  var _data$attributes;
  const response = await fetch(`${BASE_URL}/site/${cloudId}`, {
    method: 'GET',
    credentials: 'include',
    headers: {
      'Content-Type': 'application/json'
    }
  });
  if (!response.ok) {
    return [];
  }
  const data = await response.json();
  return (_data$attributes = data === null || data === void 0 ? void 0 : data.attributes) !== null && _data$attributes !== void 0 ? _data$attributes : [];
}

/**
 * Service for fetching site-level traits from the TAP Delivery personalization API.
 */
export class PersonalizationService {
  constructor() {
    _defineProperty(this, "cache", new Map());
  }
  /** Pure synchronous read for an explicit cloud id / trait pair. */
  getProviderPctMapSync(cloudId, traitName) {
    if (!cloudId) {
      return null;
    }
    return this.readStoredProviderPctMap(cloudId, traitName);
  }
  async getProviderPctMap(cloudId, traitName) {
    if (!cloudId) {
      return undefined;
    }
    const cacheKey = scopedCacheKey(cloudId, traitName);
    const cachedPromise = this.cache.get(cacheKey);
    if (cachedPromise) {
      return cachedPromise;
    }
    const promise = (async () => {
      try {
        const traits = await fetchSiteTraits(cloudId);
        const trait = traits.find(t => t.name === traitName);
        const mapped = this.parseTraitValue(trait === null || trait === void 0 ? void 0 : trait.value);
        if (mapped !== undefined) {
          this.writeStoredProviderPctMap(cloudId, traitName, mapped);
        }
        return mapped;
      } catch {
        return undefined;
      }
    })();
    const retryablePromise = promise.finally(() => {
      this.cache.delete(cacheKey);
    });
    this.cache.set(cacheKey, retryablePromise);
    return retryablePromise;
  }
  readStoredProviderPctMap(cloudId, traitName) {
    try {
      const stored = smartCardStorage.getItem(pctMapStorageItemKey(cloudId, traitName));
      if (stored === undefined || stored === null) {
        return null;
      }
      return this.normalizeProviderPctMap(stored);
    } catch {
      return null;
    }
  }
  writeStoredProviderPctMap(cloudId, traitName, map) {
    try {
      smartCardStorage.setItemWithExpiry(pctMapStorageItemKey(cloudId, traitName), map, PERSONALIZATION_PROVIDER_PCT_TTL_MS);
    } catch {
      // Quota, private-mode, etc.
    }
  }
  normalizeProviderPctMap(value) {
    if (typeof value !== 'object' || value === null || Array.isArray(value)) {
      return null;
    }
    const map = {};
    const entries = Object.entries(value);
    for (const [providerKey, percentageRaw] of entries) {
      if (typeof percentageRaw !== 'number' || !Number.isFinite(percentageRaw)) {
        return null;
      }
      map[providerKey] = percentageRaw;
    }
    return map;
  }
  parseTraitValue(raw) {
    if (typeof raw !== 'string') {
      return undefined;
    }
    try {
      const parsed = JSON.parse(raw);
      const normalized = this.normalizeProviderPctMap(parsed);
      return normalized === null ? undefined : normalized;
    } catch {
      return undefined;
    }
  }
  clearCache() {
    this.cache.clear();
    this.clearStoredProviderPctMaps();
  }
  clearStoredProviderPctMaps() {
    // eslint-disable-next-line @atlaskit/platform/no-direct-web-storage-usage -- existing usage
    if (typeof globalThis.localStorage === 'undefined' || globalThis.localStorage === null) {
      return;
    }
    const keysToRemove = [];
    // eslint-disable-next-line @atlaskit/platform/no-direct-web-storage-usage -- existing usage
    for (let index = 0; index < globalThis.localStorage.length; index += 1) {
      // eslint-disable-next-line @atlaskit/platform/no-direct-web-storage-usage -- existing usage
      const key = globalThis.localStorage.key(index);
      if (key !== null && key.startsWith(LOCAL_STORAGE_ROW_KEY_PREFIX)) {
        keysToRemove.push(key);
      }
    }
    for (const key of keysToRemove) {
      try {
        // eslint-disable-next-line @atlaskit/platform/no-direct-web-storage-usage -- existing usage
        globalThis.localStorage.removeItem(key);
      } catch {
        /* ignore */
      }
    }
  }
}
export const personalizationService = new PersonalizationService();
export const getProviderPctMap = (cloudId, traitName) => personalizationService.getProviderPctMap(cloudId, traitName);
export function getProviderPctMapSync(cloudId, traitName) {
  return personalizationService.getProviderPctMapSync(cloudId, traitName);
}

/**
 * Backwards-compatible cache-first helper for inline-card social proof callers.
 *
 * Reads the persisted provider percentage map synchronously using the current site cloud id, then
 * starts a background refresh for subsequent mounts. The async result intentionally does not affect
 * the current call site, matching the warm-cache-only rendering contract.
 */
export function getCachedProviderPctMapAndRefresh(traitName) {
  const cloudId = getCurrentSiteCloudIdSync();
  const providerPctMap = getProviderPctMapSync(cloudId, traitName);
  void getCurrentSiteCloudId().then(resolvedCloudId => {
    void getProviderPctMap(resolvedCloudId, traitName);
  });
  return providerPctMap;
}