class Voter
  def initialize(user, project)
    @user = user
    @project = project
  end

  def vote(value)
    # get the current vote
    current_vote = @project.user_vote @user

    value = get_value(value)

    # if user voted and the value is the same skip
    return true if current_vote && current_vote.value == value

    result = current_vote ? update_vote(current_vote, value) : new_vote(value)

    return false unless result

    update_project
  end

  private

  def get_value(value)
    if %w(up down).include?(value)
      value == 'up' ? 1 : -1
    elsif [1, -1].include?(value)
      value
    else
      0
    end
  end

  def update_vote(vote, value)
    vote.update_attribute :value, value
  end

  def new_vote(value)
    @user.project_votes.create :value => value, :project_id => @project.id
  end

  def update_project
    @project.update_attribute :votes, @project.project_votes.sum(:value)
    ScoreService.update(@project)
  end
end
