# Grouping logic for the visualization of participant mood and emotion data.
class MoodAndEmotionVisualizationService
  def initialize(participant)
    @participant = participant
  end

  def mood_rating_daily_averages
    averaged_ratings = []
    daily_ratings = @participant
                    .moods
                    .group_by { |x| x.created_at.strftime("%Y-%m-%d") }
    # rubocop:disable all
    daily_ratings.each do |day, moods_array|
      # rubocop:enable all
      ratings = moods_array.collect do |mood|
        [mood.rating, mood.created_at].compact
      end
      if ratings.size > 0
        averaged_ratings << { day: day,
                              intensity: average_rating(ratings),
                              is_positive: true,
                              drill_down: ratings,
                              data_type: "Mood"
        }
      end
    end
    averaged_ratings
  end

  def emotional_rating_daily_averages
    averaged_ratings = []

    daily_ratings = @participant.emotional_ratings
                    .group_by { |x| x.created_at.strftime("%Y-%m-%d") }
    # rubocop:disable all
    daily_ratings.each do |day, emotion_array|
      # rubocop:enable all
      positive_ratings = @participant.positive_emotions(emotion_array)
      if positive_ratings.size > 0
        daily_positive = { day: day,
                           intensity: average_rating(positive_ratings),
                           is_positive: true,
                           drill_down: positive_ratings,
                           data_type: "Emotion"
        }
        averaged_ratings << daily_positive
      end
      negative_ratings = @participant.negative_emotions(emotion_array)
      if negative_ratings.size > 0
        daily_negative = {  day: day,
                            intensity: average_rating(negative_ratings),
                            is_positive: false,
                            drill_down: negative_ratings, data_type: "Emotion"
        }
        averaged_ratings << daily_negative
      end
    end
    averaged_ratings
  end

  private

  def average_rating(array)
    array.reduce(0) { |a, e| a.to_f + e[0] } / array.size
  end
end