const { v4: uuidv4 } = require('uuid');

const VALID_SOURCE_TYPES = new Set(['memo', 'recording', 'photo', 'cloud']);
const VALID_STATUSES = new Set(['ready', 'distributed', 'recoverable', 'damaged', 'restored']);

class BackupIndex {
  constructor(payload = {}) {
    this.id = payload.id || uuidv4();
    this.userId = payload.userId || null;
    this.userIdHash = payload.userIdHash || null;
    this.backupId = payload.backupId || this.id;
    this.sourceType = VALID_SOURCE_TYPES.has(payload.sourceType) ? payload.sourceType : 'cloud';
    this.sourceId = payload.sourceId || null;
    this.originalFileName = payload.originalFileName || null;
    this.originalSize = Number(payload.originalSize || 0);
    this.originalHash = payload.originalHash || null;
    this.encryptedHash = payload.encryptedHash || null;
    this.totalChunks = Number(payload.totalChunks || 0);
    this.requiredChunks = Number(payload.requiredChunks || payload.totalChunks || 0);
    this.merkleRoot = payload.merkleRoot || null;
    this.status = VALID_STATUSES.has(payload.status) ? payload.status : 'ready';
    this.createdAt = payload.createdAt || new Date().toISOString();
    this.updatedAt = payload.updatedAt || this.createdAt;
    this.metadata = payload.metadata || {};
  }

  update(payload = {}) {
    if (VALID_STATUSES.has(payload.status)) this.status = payload.status;
    if (payload.totalChunks !== undefined) this.totalChunks = Number(payload.totalChunks || 0);
    if (payload.requiredChunks !== undefined) this.requiredChunks = Number(payload.requiredChunks || 0);
    if (payload.merkleRoot !== undefined) this.merkleRoot = payload.merkleRoot;
    if (payload.encryptedHash !== undefined) this.encryptedHash = payload.encryptedHash;
    if (payload.originalHash !== undefined) this.originalHash = payload.originalHash;
    if (payload.metadata && typeof payload.metadata === 'object') {
      this.metadata = { ...this.metadata, ...payload.metadata };
    }
    this.updatedAt = new Date().toISOString();
    return this;
  }
}

module.exports = BackupIndex;
