import { UrlCheckResult } from '../types';

const CACHE_TTL_MS = 5 * 60 * 1000;
const API_TIMEOUT_MS = 500;
const MAX_CACHE_SIZE = 5000;

export class UrlCache {
  private cache: Map<string, { result: UrlCheckResult; expiresAt: number }> = new Map();

  async get(url: string): Promise<UrlCheckResult | null> {
    const normalized = this.normalizeUrl(url);
    const entry = this.cache.get(normalized);

    if (!entry) return null;

    if (Date.now() > entry.expiresAt) {
      this.cache.delete(normalized);
      return null;
    }

    return { ...entry.result, cached: true };
  }

  async set(url: string, result: UrlCheckResult): Promise<void> {
    const normalized = this.normalizeUrl(url);

    if (this.cache.size >= MAX_CACHE_SIZE) {
      const firstKey = this.cache.keys().next().value;
      if (firstKey) this.cache.delete(firstKey);
    }

    this.cache.set(normalized, {
      result,
      expiresAt: Date.now() + CACHE_TTL_MS,
    });
  }

  async persistToStorage(): Promise<void> {
    const entries: Record<string, { result: UrlCheckResult; expiresAt: number }> = {};
    for (const [key, value] of this.cache.entries()) {
      entries[key] = value;
    }
    await chrome.storage.local.set({ urlCache: entries });
  }

  async loadFromStorage(): Promise<void> {
    const data = await chrome.storage.local.get('urlCache') as { urlCache: Record<string, { result: UrlCheckResult; expiresAt: number }> };
    if (data.urlCache) {
      const now = Date.now();
      for (const [key, entry] of Object.entries(data.urlCache)) {
        if (now <= entry.expiresAt) {
          this.cache.set(key, entry);
        }
      }
    }
  }

  getStats(): { size: number; max: number } {
    return { size: this.cache.size, max: MAX_CACHE_SIZE };
  }

  clear(): void {
    this.cache.clear();
  }

  private normalizeUrl(url: string): string {
    try {
      const u = new URL(url);
      u.hash = '';
      u.search = '';
      return u.toString();
    } catch {
      return url.toLowerCase();
    }
  }
}

export const urlCache = new UrlCache();
export const CACHE_TTL = CACHE_TTL_MS;
export const API_TIMEOUT = API_TIMEOUT_MS;
