class SummaryDocument < ApplicationRecord
  LOCK_TIMEOUT = 3.minutes

  belongs_to :respondent_category
  belongs_to :last_edited_by, class_name: "User", optional: true
  belongs_to :locked_by, class_name: "User", optional: true

  validates :name, presence: true

  def locked?
    locked_by_id.present? && locked_at.present? && locked_at > LOCK_TIMEOUT.ago
  end

  def locked_by_other?(user)
    locked? && locked_by_id != user.id
  end

  # we use `update_columns` to bypass updating the `lock_version` column (rails' built-in optimistic-locking column)
  def acquire_lock!(user)
    return false if locked_by_other?(user)

    update_columns(locked_by_id: user.id, locked_at: Time.current) # rubocop:disable Rails/SkipsModelValidations
    true
  end

  def heartbeat!(user)
    return false unless locked_by_id == user.id

    update_column(:locked_at, Time.current) # skip validations/callbacks, this fires every ~60s # rubocop:disable Rails/SkipsModelValidations
  end

  def release_lock!(user)
    return true unless locked_by_id == user.id

    update_columns(locked_by_id: nil, locked_at: nil) # rubocop:disable Rails/SkipsModelValidations
    true
  end

  def force_release_lock!
    update_columns(locked_by_id: nil, locked_at: nil) # rubocop:disable Rails/SkipsModelValidations
  end
end
