import type { AppPageDescriptor } from '../../store/appStore/types';
import { isPreviewRuntime } from './previewRuntime';

export const CLIENT_ID_STORAGE_KEY = 'work-app.visitor.client-id';

function readStorageValue(storage: Storage | null | undefined, key: string) {
  try {
    return storage?.getItem(key)?.trim() ?? '';
  } catch {
    return '';
  }
}

function writeStorageValue(storage: Storage | null | undefined, key: string, value: string) {
  try {
    if (value) {
      storage?.setItem(key, value);
    } else {
      storage?.removeItem(key);
    }
  } catch {
    // Ignore storage failures in restricted preview runtimes.
  }
}

function removeStorageValue(storage: Storage | null | undefined, key: string) {
  try {
    storage?.removeItem(key);
  } catch {
    // Ignore storage failures in restricted preview runtimes.
  }
}

function getClientStorage() {
  if (typeof window === 'undefined') {
    return null;
  }

  if (isPreviewRuntime()) {
    return {
      key: CLIENT_ID_STORAGE_KEY,
      primaryStorage: window.localStorage,
      legacyStorage: window.sessionStorage,
    };
  }

  return {
    key: CLIENT_ID_STORAGE_KEY,
    primaryStorage: window.localStorage,
    legacyStorage: null,
  };
}

function generateFallbackClientId() {
  return `client-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
}

function generateClientId() {
  if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
    return crypto.randomUUID();
  }

  return generateFallbackClientId();
}

export function getClientId() {
  const storageConfig = getClientStorage();

  if (!storageConfig) {
    return '';
  }

  const savedClientId = readStorageValue(storageConfig.primaryStorage, storageConfig.key);

  if (savedClientId) {
    return savedClientId;
  }

  const legacyClientId = readStorageValue(storageConfig.legacyStorage, storageConfig.key);

  if (legacyClientId) {
    writeStorageValue(storageConfig.primaryStorage, storageConfig.key, legacyClientId);
    removeStorageValue(storageConfig.legacyStorage, storageConfig.key);
    return legacyClientId;
  }

  return '';
}

export function clearClientId() {
  const storageConfig = getClientStorage();

  if (!storageConfig) {
    return;
  }

  removeStorageValue(storageConfig.primaryStorage, storageConfig.key);
  removeStorageValue(storageConfig.legacyStorage, storageConfig.key);
}

export function getOrCreateClientId() {
  const existingClientId = getClientId();

  if (existingClientId) {
    return existingClientId;
  }

  const storageConfig = getClientStorage();

  if (!storageConfig) {
    return '';
  }

  const nextClientId = generateClientId();
  writeStorageValue(storageConfig.primaryStorage, storageConfig.key, nextClientId);
  removeStorageValue(storageConfig.legacyStorage, storageConfig.key);
  return nextClientId;
}

export function appendClientIdHeader(headersInit?: HeadersInit) {
  const headers = new Headers(headersInit);
  const clientId = getOrCreateClientId();

  if (clientId && !headers.has('X-Client-Id')) {
    headers.set('X-Client-Id', clientId);
  }

  if (typeof window !== 'undefined') {
    const { origin, hostname } = window.location;

    if (origin && !headers.has('X-App-Origin')) {
      headers.set('X-App-Origin', origin);
    }

    if (hostname && !headers.has('X-App-Domain')) {
      headers.set('X-App-Domain', hostname);
    }
  }

  return headers;
}

export function buildTrackedPageUrl(page: AppPageDescriptor) {
  if (typeof window === 'undefined') {
    return '';
  }

  const url = new URL(window.location.href);

  if (page.topMenu === 'plans') {
    url.searchParams.set('topMenu', 'plans');
    url.searchParams.set('planFilter', page.section);
    url.searchParams.delete('planSection');
  } else {
    url.searchParams.set('topMenu', page.topMenu);
    url.searchParams.delete('planSection');
    url.searchParams.delete('planFilter');
  }

  if (page.topMenu === 'docs') {
    url.searchParams.set('docsSection', page.section);
  } else {
    url.searchParams.delete('docsSection');
  }

  if (page.topMenu === 'apis') {
    url.searchParams.set('apiSection', page.section);
  } else {
    url.searchParams.delete('apiSection');
  }

  if (page.topMenu === 'chat') {
    url.searchParams.set('chatSection', page.section);
  } else {
    url.searchParams.delete('chatSection');
  }

  if (page.topMenu === 'play') {
    url.searchParams.set('playSection', page.section);
  } else {
    url.searchParams.delete('playSection');
  }

  return url.toString();
}
