module InfinumId
  module Requests
    class InviteSender
      def initialize(user_id, current_user_uid)
        @user = User.find(user_id)
        @current_user_uid = current_user_uid
      end

      def self.call(user_id, current_user_uid)
        new(user_id, current_user_uid).call
      end

      def call
        send_invite_request
        handle_response
      end

      private

      attr_reader :user, :current_user_uid, :response

      def send_invite_request
        @response = HTTP.headers(headers).post(invitation_url, json: invitation_params)
      end

      def handle_response
        case response.code
        when 200
          update_user
          send_email if Rails.configuration.infinum_id_send_email
        when 400, 403, 404
          return response.to_s
        when 401..599
          raise response.to_s
        end
      end

      def update_user
        user.update(user_params)
      end

      def send_email
        params[:invitation_accept_path].blank? ? send_welcome_email : send_invite_email
      end

      def send_invite_email
        UserMailer.with(
          user_id: user.id, invited_by_uid: current_user_uid,
          accept_path: params[:invitation_accept_path]
        ).invite_email.deliver_later
      end

      def send_welcome_email
        UserMailer.with(
          user_id: user.id, invited_by_uid: current_user_uid
        ).welcome_email.deliver_later
      end

      def params
        @params ||= ActionController::Parameters.new(response.parse)
      end

      def user_params
        params.require(:user).permit(
          :uid, :email, :first_name, :last_name, :slack_username,
          :time_zone, :deactivated_at, :avatar_url
        )
      end

      def headers
        {
          client_id: InfinumId.client_id,
          client_secret: InfinumId.client_secret
        }
      end

      def invitation_params
        {
          user: user.as_json,
          invited_by_uid: current_user_uid,
          send_invitation: !Rails.configuration.infinum_id_send_email
        }
      end

      def invitation_url
        "#{InfinumId.url}/api/invitations"
      end
    end
  end
end