/**
 * Tab Root Generation
 *
 * Generates unique session roots for browser tabs to prevent message collisions.
 * Each tab gets a unique root like: s-kbt1yv-a1b2c3d4
 *
 * Session root format per ARCHITECTURE-PLATFORM-PROTOCOL.md section 4:
 *   s-<durableShort>-<sid8>
 * where durableShort = hash-derived 6-char suffix from the root.
 *
 * With DNS hierarchical addressing, roots contain dots (e.g., 'com.nimbletec.richard.santomauro').
 * Tab isolation moves to mount-path namespacing under the shared root.
 */

/**
 * Extract a 6-char short suffix for session root generation.
 * Uses a simple hash of the full root to produce a stable 6-char identifier.
 *
 * @param baseRoot - The base/durable root or DNS root (e.g., "com.nimbletec.richard.santomauro")
 * @returns 6-char short suffix
 */
function extractDurableShort(baseRoot: string): string {
  // Simple hash: sum char codes, convert to base36
  let hash = 0;
  for (let i = 0; i < baseRoot.length; i++) {
    hash = ((hash << 5) - hash + baseRoot.charCodeAt(i)) | 0;
  }
  const result = Math.abs(hash).toString(36).slice(0, 6);
  return result.padEnd(6, '0');
}

/**
 * Generate a unique session root for a browser tab.
 *
 * @param baseRoot - The base/durable root name (e.g., "richard-santomauro-kbt1yv")
 * @returns Session root (e.g., "s-kbt1yv-a1b2c3d4")
 */
export function generateTabRoot(baseRoot: string): string {
  let suffix: string;
  if (typeof crypto !== 'undefined' && crypto.randomUUID) {
    suffix = crypto.randomUUID().replace(/-/g, '').slice(0, 8);
  } else {
    suffix = Math.random().toString(36).slice(2, 10);
  }
  const short = extractDurableShort(baseRoot);
  return `s-${short}-${suffix}`;
}

/** @deprecated Use generateTabRoot instead */
export const generateTabRealm = generateTabRoot;

/**
 * Get or create a tab root, persisted in sessionStorage.
 *
 * On first call, generates a new root and stores it.
 * On subsequent calls (same tab), returns the stored root.
 * Different tabs get different roots.
 *
 * Migrates legacy dotted roots (flowpad.tab-xxx) to new format on access.
 *
 * @param baseRoot - The base root name (e.g., "flowpad")
 * @returns Consistent tab root for this browser tab
 */
export function getOrCreateTabRoot(baseRoot: string): string {
  const key = `matrix-tab-root-${baseRoot}`;
  // Also check legacy key for migration
  const legacyKey = `matrix-tab-realm-${baseRoot}`;

  // Check sessionStorage (survives page reload, unique per tab)
  if (typeof sessionStorage !== 'undefined') {
    const stored = sessionStorage.getItem(key) ?? sessionStorage.getItem(legacyKey);
    // Migrate legacy roots: dotted roots or pre-DNS-migration format (not s-xxx-xxx)
    if (stored && (stored.includes('.') || !stored.startsWith('s-'))) {
      sessionStorage.removeItem(key);
      sessionStorage.removeItem(legacyKey);
    } else if (stored) {
      // Ensure stored under new key
      if (!sessionStorage.getItem(key)) {
        sessionStorage.setItem(key, stored);
      }
      return stored;
    }
    const root = generateTabRoot(baseRoot);
    sessionStorage.setItem(key, root);
    return root;
  }

  // Fallback for non-browser environments
  return generateTabRoot(baseRoot);
}

/** @deprecated Use getOrCreateTabRoot instead */
export const getOrCreateTabRealm = getOrCreateTabRoot;

/**
 * Generate an identity-derived tab root from an address root.
 *
 * Format: {ADDRESS_ROOT}.{APP}.SESSION-{8-CHAR-HEX}
 * Example: COM.NIMBLETEC.RICHARD.CHAT.SESSION-A1B2C3D4
 *
 * @param addressRoot - DNS-hierarchical address root (e.g., "COM.NIMBLETEC.RICHARD")
 * @param appName - Application name (e.g., "CHAT", "FLOWPAD")
 * @returns Identity-scoped tab root
 */
export function generateIdentityTabRoot(addressRoot: string, appName: string): string {
  let sessionId: string;
  if (typeof crypto !== 'undefined' && crypto.randomUUID) {
    sessionId = crypto.randomUUID().replace(/-/g, '').slice(0, 8).toUpperCase();
  } else {
    sessionId = Math.random().toString(36).slice(2, 10).toUpperCase();
  }
  return `${addressRoot}.${appName.toUpperCase()}.SESSION-${sessionId}`;
}

/**
 * Get or create an identity-derived tab root, persisted in sessionStorage.
 *
 * Generates a DNS-hierarchical tab root for a specific app under an address root.
 *
 * @param appName - Webapp name (e.g., "director", "chat", "flowpad")
 * @param addressRoot - Identity-derived address root (e.g., "HIVECAST.AI.ALICE")
 * @returns Consistent tab root for this browser tab
 */
export function getOrCreateIdentityTabRoot(appName: string, addressRoot: string): string {
  const key = `matrix-tab-root-identity-${addressRoot}-${appName}`;
  if (typeof sessionStorage !== 'undefined') {
    const stored = sessionStorage.getItem(key);
    if (stored) return stored;
    const root = generateIdentityTabRoot(addressRoot, appName.toUpperCase().replace(/\./g, '-'));
    sessionStorage.setItem(key, root);
    return root;
  }
  return generateIdentityTabRoot(addressRoot, appName.toUpperCase().replace(/\./g, '-'));
}

/**
 * Validate that a root string is valid.
 *
 * With DNS hierarchical addressing, roots may contain dots.
 * Accepts both lowercase (legacy) and uppercase (DNS-hierarchical) formats.
 * Must not start or end with hyphen or dot.
 *
 * @param root - Root string to validate
 * @returns true if valid
 */
export function isValidRoot(root: string): boolean {
  if (!root || root.length === 0 || root.length > 253) {
    return false;
  }
  // Must not start or end with hyphen or dot
  if (root.startsWith('-') || root.endsWith('-')) {
    return false;
  }
  if (root.startsWith('.') || root.endsWith('.')) {
    return false;
  }
  // Alphanumeric (upper + lower), hyphens, and dots (DNS hierarchy)
  return /^[a-zA-Z0-9._-]+$/.test(root);
}

/** @deprecated Use isValidRoot instead */
export const isValidRealm = isValidRoot;
