import {
  createCacheKey,
  createSourceFingerprint,
  openDerivedCache,
  type DerivedCache,
  type DerivedCacheKind,
} from '../storage';

let cachePromise: Promise<DerivedCache> | undefined;

export function getDerivedCache(): Promise<DerivedCache> {
  cachePromise ??= openDerivedCache();
  return cachePromise;
}

function derivativeCacheKey(
  file: File,
  operation: string,
  settings: Readonly<Record<string, unknown>>
): string {
  return createCacheKey({
    sourceFingerprint: createSourceFingerprint(file),
    operation,
    settings,
    version: 1,
  });
}

export async function readCachedDerivative(
  file: File,
  operation: string,
  settings: Readonly<Record<string, unknown>>
): Promise<Blob | undefined> {
  const cache = await getDerivedCache();
  return (await cache.get(derivativeCacheKey(file, operation, settings)))?.data;
}

export async function cacheDerivative(
  file: File,
  operation: string,
  kind: DerivedCacheKind,
  projectId: string,
  blob: Blob,
  settings: Readonly<Record<string, unknown>>
): Promise<void> {
  const cache = await getDerivedCache();
  const key = derivativeCacheKey(file, operation, settings);
  const expiresAt = new Date(
    Date.now() + 7 * 24 * 60 * 60 * 1_000
  ).toISOString();
  await cache.put(
    {
      key,
      kind,
      projectId,
      mediaType: blob.type || 'application/octet-stream',
      expiresAt,
    },
    blob
  );
}
