class MaterialVersionRecorder < VersionRecorder
  EVENT_TYPES = ['create', 'update', 'discard', 'restore'].freeze

  def self.record! material:, event_type:, created_by_user:, file_snapshot: nil
    new(material:, event_type:, created_by_user:, file_snapshot:).record!
  end

  def initialize material:, event_type:, created_by_user:, file_snapshot: nil
    @file_snapshot = file_snapshot

    super(record: material, event_type:, created_by_user:)
  end

  def self.ensure_snapshot! material, created_by_user:
    return if material.material_versions.exists?

    record!(material:, event_type: :create,
            created_by_user: material.created_by_user || created_by_user)
  end

  private

  def version_class = MaterialVersion
  def version_association = :material_versions
  def record_key = :material

  def snapshot_attributes
    blob = @record.file.attached? ? @record.file.blob : nil
    file_snapshot = build_file_snapshot(blob)

    { url: @record.url,
      parent: @record.parent,
      tag: @record.tag,
      tag_name: @record.tag&.name,
      tag_category: @record.tag&.category,
      source_kind: @record.source_kind,
      source_uri: @record.source_uri,
      source_path: @record.source_path,
      source_file_id: @record.source_file_id,
      normalized_source_key: @record.normalized_source_key,
      export_paths_json: @record.snapshot_export_paths,
      discarded_at: @record.discarded_at,
      file_blob_id: file_snapshot[:file_blob_id],
      file_filename: file_snapshot[:file_filename],
      file_content_type: file_snapshot[:file_content_type],
      file_byte_size: file_snapshot[:file_byte_size],
      file_checksum: file_snapshot[:file_checksum],
      file_sha256: file_snapshot[:file_sha256] }
  end

  def build_file_snapshot blob
    return @file_snapshot if @file_snapshot
    return empty_file_snapshot unless blob

    { file_blob_id: blob.id,
      file_filename: blob.filename.to_s,
      file_content_type: blob.content_type,
      file_byte_size: blob.byte_size,
      file_checksum: blob.checksum,
      file_sha256: MaterialFileSha256.metadata_sha256(blob) }
  end

  def empty_file_snapshot
    { file_blob_id: nil,
      file_filename: nil,
      file_content_type: nil,
      file_byte_size: nil,
      file_checksum: nil,
      file_sha256: nil }
  end

  def event_types = self.class::EVENT_TYPES
end
