module PayoutEntities
  class InvitationsController < PayoutEntities::BaseController
    before_action :set_user, only: [:new, :destroy, :remove]
    helper_method :show_affiliate_downgrade?, :show_migrate_legacy_partner?, :show_remove_from_category?

    def new
      @invitation = Invitation.new
      authorize @invitation

      @category = @user.payout_type["category"].try(:downcase)

      @filtered_categories = []

      PayoutEntities::Invitation::AVAILABLE_CATEGORIES_AND_PERMISSIONS.each do |category, permission|
        if (@current_user.permitted? BeefCake::Permission.for(permission)) && progression_allowed(@category, category)
          @filtered_categories.push([category.humanize, category])
        end
      end
    end

    def create
      @invitation = Invitation.new invitation_params
      authorize @invitation

      unless permission_for_category(@invitation.user_category)
        flash[:error] = "You do not have permission to create an invitation in this category"
        redirect_back
        return
      end

      options = {ldap_login: current_user.ldap_login}
      if @invitation.save(options)
        unless @invitation.warnings.empty?
          flash[:warning] = @invitation.warnings.join("<br/>").html_safe
        end
        flash[:success] = "Successfully invited #{@invitation.user_login}! (#{@invitation.user_category})"
        redirect_to twitch_user_path(@invitation.user_id)
      else
        flash[:error] = @invitation.errors.full_messages.to_sentence
        redirect_back
      end
    end

    def destroy
      authorize Invitation

      unless permission_for_category(params[:category])
        flash[:error] = "You do not have permission to alter an invitation in this category"
        redirect_back
        return
      end

      options = {
        user_id: @user.id,
        category: params[:category],
        ldap_login: current_user.ldap_login
      }
      if Invitation.destroy(params[:invitation_id], options)
        flash[:success] = "Success"
      else
        flash[:error] = "Failed to revoke invitation"
      end

      redirect_back
    end

    def remove
      authorize Invitation

      old_category = @user.payout_type["category"]
      new_category = if params[:commit] == Invitation::ACTION_DOWNGRADE then "affiliate" else "" end

      unless permission_for_category(old_category) && (new_category.blank? || permission_for_category(new_category))
        flash[:error] = "You do not have permission to alter an invitation in this category"
        redirect_back
        return
      end

      options = {ldap_login: current_user.ldap_login}
      response = Invitation.remove(@user.id, old_category, new_category, options)

      if response.success?
        flash[:success] = "Success"
        redirect_to twitch_user_path(params[:user_id])
      else
        if response.body["message"].present?
          flash[:error] = response.body["message"]
        else
          flash[:error] = "Failed to remove user"
        end
        redirect_back
      end
    end

    protected

    def show_remove_from_category?
      permission_for_category(@category)
    end

    def show_migrate_legacy_partner?
      @category == PayoutEntities::Invitation::CATEGORY_PARTNER && @user.legacy? && permission_for_category(PayoutEntities::Invitation::CATEGORY_PARTNER)
    end

    def show_affiliate_downgrade?
      [PayoutEntities::Invitation::CATEGORY_PARTNER, PayoutEntities::Invitation::CATEGORY_0CPM].include?(@category) && permission_for_category(@category) && permission_for_category(PayoutEntities::Invitation::CATEGORY_AFFILIATE)
    end

    def progression_allowed(from_category, category)
      from_category.blank? || PayoutEntities::Invitation::ALLOWED_PROGRESSIONS[from_category].include?(category)
    end

    def permission_for_category(category)
      permission = PayoutEntities::Invitation::AVAILABLE_CATEGORIES_AND_PERMISSIONS[category]
      if permission.blank?
        return false
      end
      @current_user.permitted? BeefCake::Permission.for(permission)
    end

    def invitation_params
      params.require(:payout_entities_invitation)
    end
  end
end
