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

const VALID_STATUSES = new Set(['assigned', 'stored', 'verified', 'missing', 'corrupt', 'failed']);

class DistributedChunk {
  constructor(payload = {}) {
    this.id = payload.id || uuidv4();
    this.ownerUserId = payload.ownerUserId || null;
    this.ownerUserIdHash = payload.ownerUserIdHash || null;
    this.fileId = payload.fileId || null;
    this.backupId = payload.backupId || null;
    this.chunkId = payload.chunkId || this.id;
    this.chunkIndex = Number(payload.chunkIndex || 0);
    this.totalChunks = Number(payload.totalChunks || 0);
    this.requiredChunks = Number(payload.requiredChunks || payload.totalChunks || 0);
    this.chunkHash = payload.chunkHash || null;
    this.encryptedSize = Number(payload.encryptedSize || payload.size || 0);
    this.nodeId = payload.nodeId || null;
    this.storagePath = payload.storagePath || null;
    this.status = VALID_STATUSES.has(payload.status) ? payload.status : 'assigned';
    const now = new Date().toISOString();
    this.storedAt = payload.storedAt || (this.status === 'stored' || this.status === 'verified' ? now : null);
    this.lastVerifiedAt = payload.lastVerifiedAt || (this.status === 'verified' ? now : null);
    this.verifyFailCount = Number(payload.verifyFailCount || 0);
    this.createdAt = payload.createdAt || new Date().toISOString();
    this.updatedAt = payload.updatedAt || this.createdAt;
    this.lastError = payload.lastError || null;
  }

  update(payload = {}) {
    if (payload.status && VALID_STATUSES.has(payload.status)) this.status = payload.status;
    if (payload.chunkHash !== undefined) this.chunkHash = payload.chunkHash;
    if (payload.encryptedSize !== undefined || payload.size !== undefined) {
      this.encryptedSize = Number(payload.encryptedSize || payload.size || 0);
    }
    if (payload.nodeId !== undefined) this.nodeId = payload.nodeId;
    if (payload.storagePath !== undefined) this.storagePath = payload.storagePath;
    if (payload.lastError !== undefined) this.lastError = payload.lastError;

    if ((this.status === 'stored' || this.status === 'verified') && !this.storedAt) this.storedAt = new Date().toISOString();
    if (this.status === 'verified') this.lastVerifiedAt = new Date().toISOString();
    if (this.status === 'missing' || this.status === 'corrupt' || this.status === 'failed') {
      this.verifyFailCount += 1;
    }

    this.updatedAt = new Date().toISOString();
    return this;
  }
}

module.exports = DistributedChunk;


