master
 1class UserRecommendation
 2  attr_reader :user, :exercise, :program
 3
 4  def initialize(user, exercise, program)
 5    @user = user
 6    @exercise = exercise
 7    @program = program
 8  end
 9
10  def prepare_sets
11    target_weight = next_weight
12    work_sets = recommended_sets.times.map do
13      work_set(target_weight)
14    end
15    (WarmUp.new(exercise, target_weight).sets + work_sets).compact
16  end
17
18  def repetitions
19    recommendation.repetitions
20  end
21
22  private
23
24  def work_set(target_weight)
25    WorkSet.new(
26      exercise: exercise,
27      target_repetitions: recommendation.duration.present? ? 1 : repetitions,
28      target_weight: recommendation.duration.present? ? 0.lbs : target_weight,
29      target_duration: recommendation.duration,
30    )
31  end
32
33  def recommended_sets
34    recommended_sets = user.history_for(exercise).last_target_sets
35    recommended_sets > 0 ? recommended_sets : recommendation.sets
36  end
37
38  def next_weight
39    history = user.history_for(exercise)
40    if history.deload?
41      deload(history.last_weight)
42    else
43      increase_weight(history.last_weight(successfull_only: true))
44    end
45  end
46
47  def recommendation
48    @recommendation ||= program.recommendations.find_by(exercise: exercise)
49  end
50
51  def increase_weight(last_weight)
52    if last_weight.present? && last_weight > 0
53      5.lbs + last_weight
54    else
55      45.lbs
56    end
57  end
58
59  def deload(last_weight, percentage: 0.10)
60    ten_percent_decrease = (last_weight * percentage).to(:lbs).amount
61    weight_to_deduct = if (ten_percent_decrease % 5) > 0
62                         ten_percent_decrease - (ten_percent_decrease % 5) + 5
63                       else
64                         ten_percent_decrease - (ten_percent_decrease % 5)
65                       end
66    last_weight - weight_to_deduct.lbs
67  end
68end