import { getCollection } from '../../lib/datastore.js';
import type { SessionDoc } from './types.js';

function collection() {
  return getCollection<SessionDoc>('sessions', '/userId');
}

export async function createSession(doc: SessionDoc): Promise<SessionDoc> {
  return collection().create(doc);
}

export async function getSession(id: string, userId: string): Promise<SessionDoc | null> {
  try {
    return await collection().findById(id, userId);
  } catch {
    return null;
  }
}

export async function listUserSessions(userId: string): Promise<SessionDoc[]> {
  return collection().findMany({
    filter: { userId, revokedAt: { $exists: false } },
    sort: { lastActiveAt: -1 },
  });
}

export async function listAllUserSessions(userId: string): Promise<SessionDoc[]> {
  return collection().findMany({
    filter: { userId },
    sort: { createdAt: -1 },
  });
}

export async function revokeSession(id: string, userId: string): Promise<boolean> {
  const session = await getSession(id, userId);
  if (!session || session.revokedAt) return false;

  await collection().update(id, userId, {
    revokedAt: new Date().toISOString(),
  } as Partial<SessionDoc>);
  return true;
}

export async function revokeAllUserSessions(userId: string): Promise<number> {
  const sessions = await listUserSessions(userId);
  const now = new Date().toISOString();
  let revoked = 0;

  for (const session of sessions) {
    try {
      await collection().update(session.id, userId, {
        revokedAt: now,
      } as Partial<SessionDoc>);
      revoked++;
    } catch {
      // best-effort
    }
  }

  return revoked;
}

export async function touchSession(id: string, userId: string): Promise<void> {
  const session = await getSession(id, userId);
  if (!session || session.revokedAt) return;

  await collection().update(id, userId, {
    lastActiveAt: new Date().toISOString(),
  } as Partial<SessionDoc>);
}

export async function isSessionRevoked(id: string, userId: string): Promise<boolean> {
  const session = await getSession(id, userId);
  if (!session) return true;
  if (session.revokedAt) return true;
  if (new Date(session.expiresAt) < new Date()) return true;
  return false;
}
