module Bits
  class UsersController < Bits::BaseController
    before_action :set_user, only: [:index, :show, :add_bits, :add_bits_for_campaign, :remove_bits, :set_ban_status, :set_opt_out_status, :moderate_cheermote, :download_cheermotes]

    def index
      authorize User

      if params[:id].present? || params[:user_id].present? || params[:search_query].present?
        return redirect_to(bits_user_path(@user)) if @user.present? && @user.persisted?
        flash.now[:error] = 'Error loading bits user'
      end
    end

    def show
      authorize User

      @campaigns = nil
      resp = Campaign.all

      unless resp.success? && resp.status == 200
        flash[:error] = 'Error loading campaigns'
        return
      end

      @campaigns = resp.body['bulk_grant_campaigns']
    end

    def add_bits
      authorize User

      unless params[:reason].present? and params[:bits_amount].present?
        flash[:error] = 'Bits amount and reason are required'
        return redirect_back
      end

      if params[:notify_user].present? and !params[:origin].present?
        flash[:error] = 'Origin is required if notifying user'
        return redirect_back
      end

      response = @user.add_bits(params[:bits_amount].to_i, params[:reason], current_user.ldap_login, params[:notify_user], params[:origin])
      if response.success?
        flash[:success] = "Successfully gave #{params[:bits_amount]} bits to #{@twitch_user.login}"
      else
        handle_error 'Failed to give user bits', response
      end

      redirect_back
    end

    def add_bits_for_campaign
      authorize User

      unless params[:campaign_id].present?
        flash[:error] = 'Bulk grant campaign required'
        return redirect_back
      end

      response = @user.add_bits_for_campaign(params[:campaign_id], current_user.ldap_login)
      if response.success?
        flash[:success] = "Successfully gave bits to #{@twitch_user.login}"
      else
        handle_error 'Failed to give user bits', response
      end

      redirect_back
    end

    def remove_bits
      authorize User

      unless params[:reason].present? and params[:bits_amount].present?
        flash[:error] = 'Bits amount and reason are required'
        return redirect_back
      end

      response = @user.remove_bits(params[:bits_amount].to_i, params[:reason], current_user.ldap_login)
      if response.success?
        flash[:success] = "Successfully removed #{params[:bits_amount]} bits from #{@twitch_user.login}"
      else
        handle_error 'Failed to remove bits from user', response
      end

      redirect_back
    end

    def set_ban_status
      authorize User

      unless params[:reason].present?
        flash[:error] = 'Reason is required'
        return redirect_back
      end

      target_ban_status = false
      case params[:ban_action]
      when 'ban'
        target_ban_status = true
      when 'unban'
        target_ban_status = false
      else
        flash[:error] = 'Received invalid ban action'
        return redirect_back
      end

      response = @user.set_ban_status(target_ban_status, params[:reason], current_user.ldap_login)
      if response.success?
        flash[:success] = "Successfully #{(target_ban_status ? 'banned' : 'unbanned')} #{@twitch_user.login} from using bits"
      else
        flash[:error] = 'Failed to set ban status of user'
      end
      redirect_back
    end

    def set_opt_out_status
      authorize User

      unless params[:reason].present?
        flash[:error] = 'Reason is required'
        return redirect_back
      end

      target_opt_out_status = false
      case params[:opt_out_action]
      when 'opt-out'
        target_opt_out_status = true
      when 'opt-in'
        target_opt_out_status = false
      else
        flash[:error] = 'Received invalid opt out action'
        return redirect_back
      end

      response = @user.set_opt_out_status(target_opt_out_status, params[:reason])
      if response.success?
        flash[:success] = "Successfully #{(target_opt_out_status ? 'opted-out' : 'opted-in')} #{@twitch_user.login}'s channel for receiving bits"
      else
        flash[:error] = 'Failed to set opt-out status of channel'
      end
      redirect_back
    end

    def moderate_cheermote
      authorize User

      response = @user.moderate_cheermote
      if response.success?
        flash[:success] = "Successfully moderated cheermote in #{@twitch_user.login}'s channel'"
      else
        flash[:error] = 'Failed to moderate cheermote'
      end
      redirect_back
    end

    def download_cheermotes
      authorize User

      response = @user.download_cheermotes
      send_data response.body,
                :filename => "custom_cheermotes.zip",
                :type => "application/zip"
    end

    protected

    def set_user
      authorize User

      user_id = params[:id].presence || params[:user_id].presence

      if user_id.present?
        @twitch_user = Twitch::User.find(user_id)
      elsif params[:search_query].present?
        @twitch_user = Twitch::User.all({
          :where => {
            :text => params[:search_query],
            :skip_pagination => true
          }
        }).first
      end

      if @twitch_user.present?
        @user = User.find @twitch_user.id
      end

      if @user.present?
        authorize @user
      end
    end

    def handle_error(msg, response)
        begin
          body = response.body
        rescue
          description = ''
        else
          description = body.key?('message') ? body['message'] : body
        end

        flash[:error] = "#{msg}: #{description}"
    end
  end
end
