module UserRewards
  class HypeTrain < Service::Base
    include Code::Justin::Tv::Commerce::Percy
    include Google::Protobuf

    self.service_endpoint = Settings.percy.endpoint

    attributes :id, :channel_id, :config, :level_progress, :started_at, :ended_at
    attr_accessor :participated_at, :time_zone

    def self.twirp_client
      @twirp_client ||= PercyClient.new(connection)
      @twirp_client
    end

    def self.grant_rewards(channel_id, user_id, participated_at)
      resp = twirp_client.admin_grant_hype_train_rewards(
        AdminGrantHypeTrainRewardsReq.new(
          channel_id: channel_id,
          user_id: user_id,
          participated_at: Timestamp.new(seconds: participated_at.to_i)
        )
      )

      raise resp.error.msg if resp.error
      return nil, [] unless resp.data.hype_train

      hype_train = HypeTrain.from_twirp_object(resp.data.hype_train)
      config = HypeTrainConfig.from_twirp_object(resp.data.hype_train.config)
      difficulty_settings = resp.data.hype_train.config.difficulty_settings.map { |twirp_setting| HypeTrainDifficultySetting.from_twirp_object(twirp_setting) }
      difficulty_settings.each_with_index do |setting, i|
        setting.level_settings = resp.data.hype_train.config.difficulty_settings[i].level_settings.map do |twirp_level_setting|

          level_setting = HypeTrainLevelSetting.from_twirp_object(twirp_level_setting)
          level_setting.rewards = twirp_level_setting.rewards.map { |twirp_reward| HypeTrainReward.from_twirp_object(twirp_reward) }
          level_setting
        end
      end

      config.difficulty_settings = difficulty_settings
      hype_train.config = config

      rewards = resp.data.granted_rewards.map { |twirp_reward| HypeTrainReward.from_twirp_object(twirp_reward) }
      user_owned_rewards = resp.data.user_owned_rewards.map { |twirp_reward| HypeTrainReward.from_twirp_object(twirp_reward) }

      participation_totals = resp.data.participation_totals.map { |twirp_participation| HypeTrainParticipation.from_twirp_object(twirp_participation)}

      return hype_train, rewards, user_owned_rewards, participation_totals
    end
  end

  class HypeTrainConfig < Service::Base
    include Code::Justin::Tv::Commerce::Percy

    attributes :difficulty, :difficulty_settings
  end

  class HypeTrainDifficultySetting < Service::Base
    include Code::Justin::Tv::Commerce::Percy

    attributes :difficulty, :level_settings
  end

  class HypeTrainLevelSetting < Service::Base
    include Code::Justin::Tv::Commerce::Percy

    attributes :level, :rewards
  end

  class HypeTrainReward < Service::Base
    include Code::Justin::Tv::Commerce::Percy

    attributes :id, :type, :owned
  end

  class HypeTrainParticipation < Service::Base
    include Code::Justin::Tv::Commerce::Percy

    attributes :source, :action, :quantity
  end
end
