import crypto from 'node:crypto';
import type { GeneratorSpec } from '@bmm/types';
import { getRedis } from './redis.js';

// 24h: previews are LLM-priced; a long TTL eliminates the cache-miss path on
// the build worker (each miss = another LLM call). Specs are tiny JSON (~5KB),
// Redis-memory impact is negligible.
const TTL_SECONDS = 24 * 60 * 60;

function key(previewId: string): string {
  return `preview:${previewId}`;
}

export async function cacheSpec(spec: GeneratorSpec): Promise<string> {
  const previewId = crypto.randomBytes(12).toString('base64url');
  await getRedis().set(key(previewId), JSON.stringify(spec), 'EX', TTL_SECONDS);
  return previewId;
}

export async function loadSpec(previewId: string): Promise<GeneratorSpec | null> {
  const raw = await getRedis().get(key(previewId));
  if (!raw) return null;
  try {
    return JSON.parse(raw) as GeneratorSpec;
  } catch {
    return null;
  }
}

export async function overwriteSpec(previewId: string, spec: GeneratorSpec): Promise<void> {
  await getRedis().set(key(previewId), JSON.stringify(spec), 'EX', TTL_SECONDS);
}

function codeKey(previewId: string): string {
  return `prebuilt:${previewId}`;
}

export async function cachePrebuiltCode(previewId: string, code: string): Promise<void> {
  await getRedis().set(codeKey(previewId), code, 'EX', TTL_SECONDS);
}

export async function loadPrebuiltCode(previewId: string): Promise<string | null> {
  return (await getRedis().get(codeKey(previewId))) ?? null;
}
