# typed: strict
class Domain::UserPostFav::FaUserPostFav < Domain::UserPostFav
  scope :with_explicit_time_and_id,
        -> { where.not(explicit_time: nil).where.not(fav_id: nil) }

  scope :with_inferred_time_and_id,
        -> { where.not(inferred_time: nil).where.not(fav_id: nil) }

  scope :with_fav_id, -> { where.not(fav_id: nil) }

  attr_json :fav_id, :integer
  attr_json :inferred_time, ActiveModelUtcTimeIntValue.new
  attr_json :explicit_time, ActiveModelUtcTimeIntValue.new

  validates :fav_id, uniqueness: true, if: :fav_id?

  belongs_to_with_counter_cache :user,
                                class_name: "Domain::User::FaUser",
                                inverse_of: :user_post_favs,
                                counter_cache: :user_post_favs_count

  sig(:final) { override.returns(T.nilable(FavedAt)) }
  def faved_at
    if explicit_time.present?
      return FavedAt.new(time: explicit_time, type: FavedAtType::Explicit)
    end

    if inferred_time.present?
      return(FavedAt.new(time: inferred_time, type: FavedAtType::Inferred))
    end

    regression_model =
      TrainedRegressionModel.find_by(
        name: "fa_fav_id_and_date",
        model_type: "square_root",
      )
    if regression_model.nil? || fav_id.nil?
      return(
        FavedAt.new(time: post&.posted_at&.to_time, type: FavedAtType::PostedAt)
      )
    end

    date_i = regression_model.predict(fav_id.to_f).to_i
    FavedAt.new(time: Time.at(date_i), type: FavedAtType::InferredNow)
  end
end
