/**
 * Infralytiqs Client SDK — Entry Point
 *
 * Usage:
 *
 * 1. Include the built script in the page <head>:
 *      <script src="https://cdn.example.com/infralytiqs.min.js"></script>
 *
 * 2. Bootstrap in the <body> with a <script> block:
 *      <script>
 *        Infralytiqs.init({
 *          serverUrl:  'https://api.example.com',
 *          tenantId:   'my-tenant',
 *          siteId:     'my-site',
 *          debug:      true,
 *          evarMap: {
 *            product_id: '[data-product-id]',
 *            button_label: function(el) { return el.textContent.trim(); }
 *          },
 *          propMap: {
 *            price: function(el) { return parseFloat(el.getAttribute('data-price') || '0'); }
 *          }
 *        });
 *      </script>
 *
 * 3. Track custom events anywhere:
 *      <script>
 *        Infralytiqs.track('search', { search_term: 'blue widget' });
 *        Infralytiqs.track('login',  { method: 'google' });
 *        Infralytiqs.identify('user-123');
 *      </script>
 */

import { InfralytiqsTracker } from './tracker';
import type { InfralytiqsConfig } from './types';
import { loadClientBootstrap } from './bootstrapLoader';
import { syncToken, getStoredToken } from './token';

export { LICENSE_MODULE_ID } from './licenseModuleId';
export { TOKEN_STORAGE_KEY } from './token';
export type { InfralytiqsConfig };

const tracker = new InfralytiqsTracker();

const Infralytiqs = {
  /**
   * Initialize the tracker. Call once per page load.
   */
  init(config: InfralytiqsConfig): void {
    tracker.init(config);
  },

  /**
   * Track a custom event.
   *
   * @param eventType        - e.g. 'login', 'search', 'purchase', 'share'
   * @param customDimensions - key/value string pairs (eVars)
   * @param customMetrics    - key/value numeric pairs (props)
   * @param eventSubtype     - optional subcategory
   */
  track(
    eventType: string,
    customDimensions?: Record<string, string>,
    customMetrics?: Record<string, number>,
    eventSubtype?: string,
  ): void {
    tracker.track(eventType, customDimensions, customMetrics, eventSubtype);
  },

  /**
   * Identify the current user (e.g. after login).
   * All subsequent events will carry this user_id.
   */
  identify(userId: string): void {
    tracker.identify(userId);
  },

  /**
   * Force-flush the event queue immediately.
   */
  flush(): Promise<void> {
    return tracker.flush();
  },

  /**
   * Tear down listeners and stop the flush timer.
   */
  destroy(): void {
    tracker.destroy();
  },

  /**
   * Re-read `window.IL_TOKEN` and sync it into sessionStorage. Runs once
   * automatically on SDK load; can be called again after the host page
   * refreshes the token global.
   *
   * @returns the token now held in sessionStorage, or `null` if none.
   */
  syncToken(): string | null {
    return syncToken();
  },

  /**
   * @returns the Infralytiqs token id currently held in sessionStorage.
   */
  getToken(): string | null {
    return getStoredToken();
  },
};

export default Infralytiqs;

// ─── Sync the Infralytiqs token into sessionStorage ─────────────────────
// The host page renders the tenant's current token id as `window.IL_TOKEN`
// (see AEM Infralytiqs.html). Copy it into sessionStorage on load so any
// embedded report widget can pick it up, updating the stored value whenever
// the markup token changes.
try {
  syncToken();
} catch {
  /* never throw out of SDK script-tag evaluation */
}

// ─── Auto-load the client-specific bootstrap ────────────────────────────
// When the SDK script tag executes, look for `window.IL_CLIENT_BOOTSTRAP_LIB`
// declared by the host page (e.g. by the AEM Infralytiqs.html Sightly
// fragment) and inject a <script> tag for it. The bootstrap is then
// responsible for calling `Infralytiqs.init({...})` and wiring up any
// site-specific event hooks. Resolution against the SDK's own CDN origin
// is handled inside the loader, so host pages can use absolute-path
// shortcuts like "/cl/publicis/ps/infralytiqs-bootstrap.min.js".
try {
  loadClientBootstrap();
} catch {
  /* never throw out of SDK script-tag evaluation */
}

