/**
 * Device trust repository — CRUD for auth_devices container.
 */

import { getCollection } from '../../../lib/datastore.js';
import type { DeviceDoc, DeviceTrustLevel } from './types.js';

function devicesCollection() {
  return getCollection<DeviceDoc>('auth_devices', '/userId');
}

export async function getByFingerprint(
  userId: string,
  fingerprint: string
): Promise<DeviceDoc | null> {
  try {
    return await devicesCollection().findById(`dev_${fingerprint}`, userId);
  } catch {
    return null;
  }
}

export async function upsert(doc: DeviceDoc): Promise<DeviceDoc> {
  const existing = await getByFingerprint(doc.userId, doc.fingerprint);
  if (existing) {
    return (await devicesCollection().update(doc.id, doc.userId, {
      trustLevel: doc.trustLevel,
      trustExpiresAt: doc.trustExpiresAt,
      lastIp: doc.lastIp,
      lastLocation: doc.lastLocation,
      lastSeenAt: new Date().toISOString(),
      deviceInfo: doc.deviceInfo,
    } as Partial<DeviceDoc>)) as DeviceDoc;
  }
  return devicesCollection().create(doc);
}

export async function listByUser(userId: string): Promise<DeviceDoc[]> {
  return devicesCollection().findMany({ filter: { userId } });
}

export async function updateLastSeen(
  userId: string,
  fingerprint: string,
  ip?: string
): Promise<void> {
  try {
    await devicesCollection().update(`dev_${fingerprint}`, userId, {
      lastSeenAt: new Date().toISOString(),
      lastIp: ip,
    } as Partial<DeviceDoc>);
  } catch {
    // best-effort
  }
}

export async function revokeTrust(userId: string, fingerprint: string): Promise<boolean> {
  try {
    await devicesCollection().update(`dev_${fingerprint}`, userId, {
      trustLevel: 'unknown' as DeviceTrustLevel,
      trustExpiresAt: new Date().toISOString(),
    } as Partial<DeviceDoc>);
    return true;
  } catch {
    return false;
  }
}

export async function revokeAllTrust(userId: string): Promise<number> {
  const devices = await listByUser(userId);
  let revoked = 0;
  for (const device of devices) {
    if (device.trustLevel !== 'unknown') {
      await revokeTrust(userId, device.fingerprint);
      revoked++;
    }
  }
  return revoked;
}

export async function remove(userId: string, fingerprint: string): Promise<boolean> {
  try {
    await devicesCollection().delete(`dev_${fingerprint}`, userId);
    return true;
  } catch {
    return false;
  }
}

/**
 * Check if a device is trusted and trust hasn't expired.
 */
export function isDeviceTrusted(device: DeviceDoc | null): boolean {
  if (!device) return false;
  if (device.trustLevel === 'unknown') return false;
  return new Date(device.trustExpiresAt) > new Date();
}
