import type { MessageSearchHit, SearchMode } from '@/types';

const CACHE_PREFIX = 'mac-sync:search:v2:';
const INDEX_KEY = `${CACHE_PREFIX}__index__`;
const MAX_ENTRIES = 150;
export const CACHE_DAYS = 30;

export interface CacheEntry {
  query: string;
  mode: SearchMode;
  hits: MessageSearchHit[];
  total: number;
  searchDate: string;
}

function entryKey(query: string, mode: SearchMode): string {
  return `${CACHE_PREFIX}${mode}:${query}`;
}

function readIndex(): string[] {
  try {
    const raw = localStorage.getItem(INDEX_KEY);
    return raw ? (JSON.parse(raw) as string[]) : [];
  } catch {
    return [];
  }
}

function writeIndex(keys: string[]): void {
  try {
    localStorage.setItem(INDEX_KEY, JSON.stringify(keys));
  } catch {
    // Storage unavailable or full — best effort
  }
}

function searchDateDaysAgo(searchDate: string): number {
  return (Date.now() - new Date(searchDate).getTime()) / (1000 * 60 * 60 * 24);
}

export function getFromCache(query: string, mode: SearchMode): CacheEntry | null {
  try {
    const raw = localStorage.getItem(entryKey(query, mode));
    if (!raw) return null;
    const entry = JSON.parse(raw) as CacheEntry;
    if (searchDateDaysAgo(entry.searchDate) >= CACHE_DAYS) {
      localStorage.removeItem(entryKey(query, mode));
      return null;
    }
    return entry;
  } catch {
    return null;
  }
}

export function saveToCache(query: string, mode: SearchMode, entry: CacheEntry): void {
  try {
    const key = entryKey(query, mode);
    const index = readIndex().filter((k) => k !== key);

    while (index.length >= MAX_ENTRIES) {
      const oldest = index.shift();
      if (oldest) localStorage.removeItem(oldest);
    }

    index.push(key);
    writeIndex(index);
    localStorage.setItem(key, JSON.stringify(entry));
  } catch {
    // Best effort — never throw from cache writes
  }
}
