/**
 * Backup Model
 *
 * Stores metadata for each backup operation — both manual and automatic.
 * The actual ZIP file is stored on disk at `filePath`; this document tracks
 * the backup lifecycle (queued → preparing → exporting → compressing → completed).
 */

import mongoose, { Schema, Document, Types } from 'mongoose';

export interface IBackup extends Document {
  name: string;
  companyId: string;
  scope: 'everything' | 'custom';
  categories: string[];
  companySelection: 'workspace' | 'specific';
  targetCompanyId?: string;          // If companySelection === 'specific', which company
  type: 'manual' | 'automatic';
  status: 'scheduled' | 'queued' | 'preparing' | 'exporting' | 'compressing' | 'completed' | 'failed';
  progress: number;                  // 0–100
  size: number;                      // Compressed size in bytes
  uncompressedSize: number;          // Raw data size in bytes
  filePath: string;                  // Path to the ZIP file on disk
  checksum: string;                  // SHA-256 checksum of the ZIP
  version: string;                   // Backup format version (e.g., "1.0")
  encrypted: boolean;
  createdBy: string;                  // User ID who triggered it
  duration: number;                   // Duration in milliseconds
  errorMessage?: string;
  downloadToken?: string;           // One-time token for authenticated download
  downloadTokenExpires?: Date;      // Expiry for the download token
  stats: {
    files: number;
    images: number;
    videos: number;
    documents: number;
    csvs: number;
    dbRecords: number;
  };
  createdAt: Date;
  updatedAt: Date;
}

const BackupSchema = new Schema<IBackup>({
  name: {
    type: String,
    required: [true, 'Backup name is required'],
    trim: true,
    maxlength: [200, 'Backup name cannot exceed 200 characters'],
  },
  companyId: {
    type: String,
    required: true,
    index: true,
  },
  scope: {
    type: String,
    enum: ['everything', 'custom'],
    default: 'everything',
  },
  categories: [{
    type: String,
    trim: true,
  }],
  companySelection: {
    type: String,
    enum: ['workspace', 'specific'],
    default: 'workspace',
  },
  targetCompanyId: {
    type: String,
  },
  type: {
    type: String,
    enum: ['manual', 'automatic'],
    default: 'manual',
  },
  status: {
    type: String,
    enum: ['scheduled', 'queued', 'preparing', 'exporting', 'compressing', 'completed', 'failed'],
    default: 'queued',
  },
  progress: {
    type: Number,
    default: 0,
    min: 0,
    max: 100,
  },
  size: {
    type: Number,
    default: 0,
  },
  uncompressedSize: {
    type: Number,
    default: 0,
  },
  filePath: {
    type: String,
    default: '',
  },
  checksum: {
    type: String,
    default: '',
  },
  version: {
    type: String,
    default: '1.0',
  },
  encrypted: {
    type: Boolean,
    default: false,
  },
  createdBy: {
    type: String,
    required: true,
  },
  duration: {
    type: Number,
    default: 0,
  },
  errorMessage: {
    type: String,
  },
  downloadToken: {
    type: String,
    default: '',
  },
  downloadTokenExpires: {
    type: Date,
    default: null,
  },
  stats: {
    files: { type: Number, default: 0 },
    images: { type: Number, default: 0 },
    videos: { type: Number, default: 0 },
    documents: { type: Number, default: 0 },
    csvs: { type: Number, default: 0 },
    dbRecords: { type: Number, default: 0 },
  },
}, {
  timestamps: true,
  toJSON: { virtuals: true },
  toObject: { virtuals: true },
});

// Indexes
BackupSchema.index({ companyId: 1, createdAt: -1 });
BackupSchema.index({ status: 1 });
BackupSchema.index({ type: 1 });
BackupSchema.index({ companyId: 1, type: 1 });

export const Backup = mongoose.models.Backup || mongoose.model<IBackup>('Backup', BackupSchema);