import type { DemoSubmissionResult } from './schema';

interface StoredOperation {
  expiresAt: number;
  result: Promise<DemoSubmissionResult>;
}

const globalStore = globalThis as typeof globalThis & {
  __rdgDemoIdempotencyStore?: Map<string, StoredOperation>;
};

const store = globalStore.__rdgDemoIdempotencyStore ?? new Map<string, StoredOperation>();
globalStore.__rdgDemoIdempotencyStore = store;

function purgeExpired(now: number) {
  for (const [key, operation] of store) {
    if (operation.expiresAt <= now) store.delete(key);
  }
}

export async function executeIdempotent(
  key: string,
  ttlSeconds: number,
  operation: () => Promise<DemoSubmissionResult>,
): Promise<DemoSubmissionResult> {
  const now = Date.now();
  purgeExpired(now);
  const existing = store.get(key);
  if (existing) return existing.result;

  const result = operation();
  store.set(key, { expiresAt: now + ttlSeconds * 1_000, result });

  try {
    const settled = await result;
    if (!settled.ok && settled.retryable) store.delete(key);
    return settled;
  } catch (error) {
    store.delete(key);
    throw error;
  }
}

export function clearIdempotencyStoreForTests() {
  store.clear();
}
