import { CLIENT_ID_STORAGE_KEY } from './clientIdentity';
import { NOTIFICATION_DEVICE_ID_STORAGE_KEY } from './notificationIdentity';
import { TOKEN_ACCESS_STORAGE_KEY } from './tokenAccess';
import { APP_CONFIG_STORAGE_KEY } from './appConfig';

const PRESERVED_LOCAL_STORAGE_KEYS = new Set([
  APP_CONFIG_STORAGE_KEY,
  TOKEN_ACCESS_STORAGE_KEY,
  CLIENT_ID_STORAGE_KEY,
  NOTIFICATION_DEVICE_ID_STORAGE_KEY,
]);

const APP_LOCAL_STORAGE_PREFIXES = [
  'work-',
  'main-chat-panel:',
  'gps-layer:',
  'ai-code-app:',
  'codex-live-share-',
  'chat-share-page:',
] as const;
const APP_SESSION_STORAGE_PREFIXES = [
  'work-',
  'main-chat-panel:',
  'gps-layer:',
  'ai-code-app.',
  'codex-live-share-',
  'chat-share-page:',
] as const;

export type ClientResetSummary = {
  removedLocalStorageKeys: string[];
  removedSessionStorageKeys: string[];
  removedCacheKeys: string[];
  unregisteredServiceWorkerCount: number;
};

function collectMatchingStorageKeys(storage: Storage, prefixes: readonly string[], preservedKeys: ReadonlySet<string> = new Set()) {
  const keys: string[] = [];

  for (let index = 0; index < storage.length; index += 1) {
    const key = storage.key(index);

    if (!key || preservedKeys.has(key)) {
      continue;
    }

    if (prefixes.some((prefix) => key.startsWith(prefix))) {
      keys.push(key);
    }
  }

  return keys;
}

async function clearBrowserCaches() {
  if (typeof window === 'undefined' || !('caches' in window)) {
    return [] as string[];
  }

  try {
    const cacheKeys = await caches.keys();
    await Promise.all(cacheKeys.map((cacheKey) => caches.delete(cacheKey).catch(() => false)));
    return cacheKeys;
  } catch {
    return [] as string[];
  }
}

export async function resetNonAuthClientState() {
  if (typeof window === 'undefined') {
    return {
      removedLocalStorageKeys: [],
      removedSessionStorageKeys: [],
      removedCacheKeys: [],
      unregisteredServiceWorkerCount: 0,
    } satisfies ClientResetSummary;
  }

  const removedLocalStorageKeys = collectMatchingStorageKeys(
    window.localStorage,
    APP_LOCAL_STORAGE_PREFIXES,
    PRESERVED_LOCAL_STORAGE_KEYS,
  );
  const removedSessionStorageKeys = collectMatchingStorageKeys(window.sessionStorage, APP_SESSION_STORAGE_PREFIXES);

  removedLocalStorageKeys.forEach((key) => {
    window.localStorage.removeItem(key);
  });
  removedSessionStorageKeys.forEach((key) => {
    window.sessionStorage.removeItem(key);
  });

  const removedCacheKeys = await clearBrowserCaches();

  return {
    removedLocalStorageKeys,
    removedSessionStorageKeys,
    removedCacheKeys,
    unregisteredServiceWorkerCount: 0,
  } satisfies ClientResetSummary;
}
