import { SmartDataDbDoc, index, svDb } from './classes.doc.js';

/**
 * Common TTL values in milliseconds for cache-like documents.
 */
export const smartdataTtlValues = {
  HOURS_1: 1 * 60 * 60 * 1000,
  HOURS_24: 24 * 60 * 60 * 1000,
  DAYS_7: 7 * 24 * 60 * 60 * 1000,
  DAYS_30: 30 * 24 * 60 * 60 * 1000,
  DAYS_90: 90 * 24 * 60 * 60 * 1000,
} as const;

/**
 * Base class for SmartData documents that should expire after an absolute date.
 */
export abstract class SmartdataCachedDocument<
  T extends SmartdataCachedDocument<T>,
> extends SmartDataDbDoc<T, T> {
  @svDb()
  public createdAt: Date = new Date();

  @index({ expireAfterSeconds: 0 })
  public expiresAt?: Date;

  @svDb()
  public lastAccessedAt: Date = new Date();

  public setTTL(ttlMs: number): void {
    this.expiresAt = new Date(Date.now() + ttlMs);
  }

  public setTTLDays(days: number): void {
    this.setTTL(days * 24 * 60 * 60 * 1000);
  }

  public setTTLHours(hours: number): void {
    this.setTTL(hours * 60 * 60 * 1000);
  }

  public isExpired(): boolean {
    if (!this.expiresAt) {
      return false;
    }
    return Date.now() > this.expiresAt.getTime();
  }

  public touch(): void {
    this.lastAccessedAt = new Date();
  }

  public getRemainingTTL(): number {
    if (!this.expiresAt) {
      return -1;
    }
    const remaining = this.expiresAt.getTime() - Date.now();
    return remaining > 0 ? remaining : 0;
  }

  public extendTTL(ttlMs: number): void {
    this.expiresAt = new Date(Date.now() + ttlMs);
  }

  public setNeverExpires(): void {
    this.expiresAt = new Date(Date.now() + 100 * 365 * 24 * 60 * 60 * 1000);
  }
}
