require 'uri'

module HandleMethodNotAllowedTrait
  as_trait do |*args|

    options = args.extract_options!

    fallback_url_proc = options[:fallback_url] || proc { root_url }
    flash_message_proc = options[:flash] || (I18n.locale.to_s == 'de' ? "Das hat nicht funktioniert, bitte versuchen Sie es noch einmal." : "This did not work. Please try again.")

    rescue_from 'ActionController::MethodNotAllowed', :with => :handle_method_not_allowed


    private

    define_method :handle_method_not_allowed do |error|
      begin
        fallback_url = fallback_url_proc.respond_to?(:call) ? instance_eval(&fallback_url_proc) : fallback_url_proc
        flash_message = flash_message_proc.respond_to?(:call) ? instance_eval(&flash_message_proc) : flash_message_proc

        flash[:notice] = flash_message
        referer = request.env['HTTP_REFERER']
        if referer.present? and (URI.parse(referer).host == request.host rescue false)
          redirect_to referer
        else
          redirect_to fallback_url
        end
      rescue Exception => e
        rescue_action_without_handler(e)
      end
    end

  end
end
