export enum FileType {
  IMAGE = 'image',
  DOCUMENT = 'document',
  AUDIO = 'audio',
  VIDEO = 'video',
  OTHER = 'other',
}

export enum FileStatus {
  UPLOADING = 'uploading',
  PROCESSING = 'processing',
  READY = 'ready',
  FAILED = 'failed',
  DELETED = 'deleted',
}

/**
 * File Domain Entity
 */
export class FileEntity {
  readonly id: string;
  readonly tenantId: string;
  readonly userId: string;
  conversationId: string | null;
  originalName: string;
  storagePath: string;
  mimeType: string;
  type: FileType;
  size: number;
  status: FileStatus;
  thumbnailPath: string | null;
  metadata: Record<string, unknown> | null;
  extractedText: string | null;
  errorMessage: string | null;
  readonly createdAt: Date;
  updatedAt: Date;
  deletedAt: Date | null;

  private constructor(props: {
    id: string;
    tenantId: string;
    userId: string;
    conversationId: string | null;
    originalName: string;
    storagePath: string;
    mimeType: string;
    type: FileType;
    size: number;
    status: FileStatus;
    thumbnailPath: string | null;
    metadata: Record<string, unknown> | null;
    extractedText: string | null;
    errorMessage: string | null;
    createdAt: Date;
    updatedAt: Date;
    deletedAt: Date | null;
  }) {
    Object.assign(this, props);
  }

  static create(props: {
    id: string;
    tenantId?: string;
    userId: string;
    conversationId?: string;
    originalName: string;
    storagePath: string;
    mimeType: string;
    type: FileType;
    size?: number;
    status?: FileStatus;
  }): FileEntity {
    const now = new Date();
    return new FileEntity({
      id: props.id,
      tenantId: props.tenantId || '',
      userId: props.userId,
      conversationId: props.conversationId || null,
      originalName: props.originalName,
      storagePath: props.storagePath,
      mimeType: props.mimeType,
      type: props.type,
      size: props.size || 0,
      status: props.status || FileStatus.UPLOADING,
      thumbnailPath: null,
      metadata: null,
      extractedText: null,
      errorMessage: null,
      createdAt: now,
      updatedAt: now,
      deletedAt: null,
    });
  }

  static fromPersistence(props: {
    id: string;
    tenantId: string;
    userId: string;
    conversationId: string | null;
    originalName: string;
    storagePath: string;
    mimeType: string;
    type: string;
    size: number;
    status: string;
    thumbnailPath: string | null;
    metadata: Record<string, unknown> | null;
    extractedText: string | null;
    errorMessage: string | null;
    createdAt: Date;
    updatedAt: Date;
    deletedAt: Date | null;
  }): FileEntity {
    return new FileEntity({
      ...props,
      type: props.type as FileType,
      status: props.status as FileStatus,
    });
  }

  confirmUpload(fileSize: number): void {
    this.size = fileSize;
    this.status = FileStatus.READY;
    this.updatedAt = new Date();
  }

  markAsFailed(errorMessage: string): void {
    this.status = FileStatus.FAILED;
    this.errorMessage = errorMessage;
    this.updatedAt = new Date();
  }

  softDelete(): void {
    this.status = FileStatus.DELETED;
    this.deletedAt = new Date();
    this.updatedAt = new Date();
  }

  isUploading(): boolean {
    return this.status === FileStatus.UPLOADING;
  }

  isReady(): boolean {
    return this.status === FileStatus.READY;
  }
}
