/**
 * QR auth repository — in-memory store with TTL expiry.
 * QR challenges are ephemeral (3-minute TTL) so no Cosmos container needed.
 */

import type { QrChallengeDoc } from './types.js';
import { randomUUID, randomBytes } from 'node:crypto';

const store = new Map<string, QrChallengeDoc>();

const EXPIRY_MS = 3 * 60 * 1000; // 3 minutes

function sweep(): void {
  const now = Date.now();
  for (const [, doc] of store) {
    if (new Date(doc.expiresAt).getTime() <= now && doc.status === 'pending') {
      doc.status = 'expired';
    }
  }
}

export function create(productId: string, platform: string): QrChallengeDoc {
  sweep();
  const now = new Date();
  const doc: QrChallengeDoc = {
    id: `qr_${randomUUID().slice(0, 8)}`,
    challengeToken: randomBytes(32).toString('base64url'),
    productId,
    platform,
    status: 'pending',
    createdAt: now.toISOString(),
    expiresAt: new Date(now.getTime() + EXPIRY_MS).toISOString(),
  };
  store.set(doc.id, doc);
  return doc;
}

export function getById(id: string): QrChallengeDoc | undefined {
  sweep();
  return store.get(id);
}

export function getByChallenge(challengeToken: string): QrChallengeDoc | undefined {
  sweep();
  for (const doc of store.values()) {
    if (doc.challengeToken === challengeToken) return doc;
  }
  return undefined;
}

export function confirm(challengeToken: string, userId: string): QrChallengeDoc | undefined {
  sweep();
  const doc = getByChallenge(challengeToken);
  if (!doc || doc.status !== 'pending') return undefined;
  doc.status = 'confirmed';
  doc.userId = userId;
  doc.confirmedAt = new Date().toISOString();
  return doc;
}

/** Clear all — for testing. */
export function _clear(): void {
  store.clear();
}
