/**
 * Push approval repository — in-memory store with TTL expiry.
 * Push approvals are ephemeral (5-minute TTL) so no Cosmos container needed.
 */

import type { PushApprovalDoc } from './types.js';
import { randomUUID } from 'node:crypto';

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

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

/** Expire old entries on access. */
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(
  params: Omit<PushApprovalDoc, 'id' | 'status' | 'createdAt' | 'expiresAt'>
): PushApprovalDoc {
  sweep();
  const now = new Date();
  const doc: PushApprovalDoc = {
    id: `pushappr_${randomUUID().slice(0, 8)}`,
    ...params,
    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): PushApprovalDoc | undefined {
  sweep();
  return store.get(id);
}

export function getPendingByUserId(userId: string): PushApprovalDoc[] {
  sweep();
  const results: PushApprovalDoc[] = [];
  for (const doc of store.values()) {
    if (doc.userId === userId && doc.status === 'pending') {
      results.push(doc);
    }
  }
  return results.sort((a, b) => b.createdAt.localeCompare(a.createdAt));
}

export function respond(id: string, action: 'approved' | 'denied'): PushApprovalDoc | undefined {
  sweep();
  const doc = store.get(id);
  if (!doc || doc.status !== 'pending') return undefined;
  doc.status = action;
  doc.respondedAt = new Date().toISOString();
  return doc;
}

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

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