import { OutputFormat } from '../value-objects/output-format.enum';

export class ReportFile {
  private _id: bigint | null = null;
  private readonly _snapshotId: bigint;
  private readonly _fileName: string;
  private readonly _filePath: string;
  private _fileUrl: string | null;
  private readonly _fileSize: bigint;
  private readonly _fileFormat: OutputFormat;
  private readonly _mimeType: string;
  private _downloadCount: number;
  private _lastDownloadAt: Date | null;
  private readonly _createdAt: Date;
  private _expiresAt: Date | null;

  private constructor(
    snapshotId: bigint,
    fileName: string,
    filePath: string,
    fileUrl: string | null,
    fileSize: bigint,
    fileFormat: OutputFormat,
    mimeType: string,
    downloadCount: number,
    lastDownloadAt: Date | null,
    createdAt: Date,
    expiresAt: Date | null,
  ) {
    this._snapshotId = snapshotId;
    this._fileName = fileName;
    this._filePath = filePath;
    this._fileUrl = fileUrl;
    this._fileSize = fileSize;
    this._fileFormat = fileFormat;
    this._mimeType = mimeType;
    this._downloadCount = downloadCount;
    this._lastDownloadAt = lastDownloadAt;
    this._createdAt = createdAt;
    this._expiresAt = expiresAt;
  }

  static create(params: {
    snapshotId: bigint;
    fileName: string;
    filePath: string;
    fileUrl?: string;
    fileSize: bigint;
    fileFormat: OutputFormat;
    mimeType: string;
    expiresAt?: Date;
  }): ReportFile {
    return new ReportFile(
      params.snapshotId,
      params.fileName,
      params.filePath,
      params.fileUrl || null,
      params.fileSize,
      params.fileFormat,
      params.mimeType,
      0,
      null,
      new Date(),
      params.expiresAt || null,
    );
  }

  static reconstitute(params: {
    id: bigint;
    snapshotId: bigint;
    fileName: string;
    filePath: string;
    fileUrl: string | null;
    fileSize: bigint;
    fileFormat: OutputFormat;
    mimeType: string;
    downloadCount: number;
    lastDownloadAt: Date | null;
    createdAt: Date;
    expiresAt: Date | null;
  }): ReportFile {
    const file = new ReportFile(
      params.snapshotId,
      params.fileName,
      params.filePath,
      params.fileUrl,
      params.fileSize,
      params.fileFormat,
      params.mimeType,
      params.downloadCount,
      params.lastDownloadAt,
      params.createdAt,
      params.expiresAt,
    );
    file._id = params.id;
    return file;
  }

  // Getters
  get id(): bigint | null {
    return this._id;
  }

  get snapshotId(): bigint {
    return this._snapshotId;
  }

  get fileName(): string {
    return this._fileName;
  }

  get filePath(): string {
    return this._filePath;
  }

  get fileUrl(): string | null {
    return this._fileUrl;
  }

  get fileSize(): bigint {
    return this._fileSize;
  }

  get fileFormat(): OutputFormat {
    return this._fileFormat;
  }

  get mimeType(): string {
    return this._mimeType;
  }

  get downloadCount(): number {
    return this._downloadCount;
  }

  get lastDownloadAt(): Date | null {
    return this._lastDownloadAt;
  }

  get createdAt(): Date {
    return this._createdAt;
  }

  get expiresAt(): Date | null {
    return this._expiresAt;
  }

  // Commands
  recordDownload(): void {
    this._downloadCount++;
    this._lastDownloadAt = new Date();
  }

  setFileUrl(url: string): void {
    this._fileUrl = url;
  }

  setExpiration(expiresAt: Date): void {
    this._expiresAt = expiresAt;
  }

  isExpired(): boolean {
    if (!this._expiresAt) {
      return false;
    }
    return new Date() > this._expiresAt;
  }
}
