# frozen_string_literal: true

class CommentPolicy < ApplicationPolicy
  def create?
    unbanned?
  end

  def update?
    unbanned? && (user.is_moderator? || (record.creator == user && (!record.is_deleted? || record.is_deleted_change == [false, true])))
  end

  def reportable?
    unbanned? && record.creator_id != user.id && !record.creator.is_moderator? && !record.is_deleted? && record.created_at.after?(1.year.ago)
  end

  def can_sticky_comment?
    user.is_moderator?
  end

  def can_see_deleted?
    user.is_moderator?
  end

  def can_see_updater_notice?
    user.is_moderator?
  end

  def can_see_creator?
    !record.is_deleted? || can_see_deleted? || record.creator_id == user.id
  end

  def reply?
    !record.is_deleted?
  end

  def rate_limit_for_create(**_options)
    if record.invalid?
      { action: "comments:create:invalid", rate: 1.0 / 1.second, burst: 1 }
    elsif user.comments.exists?(created_at: ..24.hours.ago)
      { rate: 1.0 / 1.minute, burst: 3 }
    else
      { rate: 1.0 / 2.minutes, burst: 2 }
    end
  end

  def permitted_attributes_for_create
    [:body, :post_id, :do_not_bump_post, (:is_sticky if can_sticky_comment?)].compact
  end

  def permitted_attributes_for_update
    [:body, :is_deleted, (:is_sticky if can_sticky_comment?)].compact
  end

  def api_attributes
    attributes = super
    attributes -= [:creator_id] unless can_see_creator?
    attributes -= [:updater_id, :body, :score, :do_not_bump_post, :is_sticky] if record.is_deleted? && !can_see_deleted?
    attributes
  end

  def visible_for_search(comments, attribute)
    case attribute
    in :creator | :creator_id if !can_see_deleted?
      comments.where(creator: user, is_deleted: true).or(comments.undeleted)
    in :updater | :updater_id | :body | :score | :do_not_bump_post | :is_sticky if !can_see_deleted?
      comments.undeleted
    else
      comments
    end
  end

  alias_method :undelete?, :update?
end
