class Answer < ApplicationRecord
  extend Answer::TimelineMethods

  attr_accessor :has_reacted, :is_subscribed

  belongs_to :user, counter_cache: :answered_count
  belongs_to :question, counter_cache: :answer_count
  has_many :comments, dependent: :destroy
  has_many :smiles, class_name: "Reaction", foreign_key: :parent_id, dependent: :destroy
  has_many :subscriptions, dependent: :destroy
  has_many :comment_smiles, through: :comments, source: :smiles

  # rubocop:disable Rails/UniqueValidationWithoutIndex
  # This cop is disabled here because there already are questions with
  # multiple answers. Adding an index would break things database-side
  validates :question_id, uniqueness: { scope: :user_id }
  # rubocop:enable Rails/UniqueValidationWithoutIndex

  scope :pinned, -> { where.not(pinned_at: nil) }
  scope :for_user, lambda { |current_user|
    next select("answers.*", "false as is_subscribed", "false as has_reacted") if current_user.nil?

    select("answers.*",
           "EXISTS(SELECT 1
              FROM subscriptions
              WHERE answer_id = answers.id
                AND user_id = #{current_user.id}) as is_subscribed",
           "EXISTS(SELECT 1
              FROM reactions
              WHERE parent_id = answers.id
                AND parent_type = 'Answer'
                AND user_id = #{current_user.id}) as has_reacted",
           )
  }

  SHORT_ANSWER_MAX_LENGTH = 640

  after_create do
    InboxEntry.where(user: self.user, question: self.question).destroy_all
    user.touch :inbox_updated_at # rubocop:disable Rails/SkipsModelValidations

    Notification.notify self.question.user, self unless self.question.user == self.user or self.question.user.nil?
    Subscription.subscribe self.user, self
    Subscription.subscribe self.question.user, self unless self.question.author_is_anonymous
  end

  before_destroy do
    # mark a report as deleted if it exists
    rep = Report.where(target_id: self.id, type: 'Reports::Answer')
    rep.each do |r|
      unless r.nil?
        r.deleted = true
        r.save
      end
    end

    self.smiles.each do |smile|
      Notification.denotify self.user, smile
    end
    self.comments.each do |comment|
      Subscription.denotify comment, self
    end
    Notification.denotify question&.user, self
    Subscription.destruct self
  end

  def notification_type(*_args)
    Notification::QuestionAnswered
  end

  def long? = content.length > SHORT_ANSWER_MAX_LENGTH

  def pinned? = pinned_at.present?

  def has_reacted = self.attributes["has_reacted"] || false

  def is_subscribed = self.attributes["is_subscribed"] || false
end