class List
  module JoinRequests
    extend ActiveSupport::Concern
    included do
      property :join_request_user_ids, type: Array, default: []
    end

    def join_request_for_user(user)
      JoinRequest.new(user: user, list: self, created_at: created_at, updated_at: updated_at)
    end

    def join_requests
      @join_requests ||= join_request_user_ids.any? ? self.class.database.load_document(join_request_user_ids).map{|user| join_request_for_user(user) } : []
    end

    def send_table_join_request_for_user!(requester)
      #unless join_request_user_ids.include?(requester.id) or user_ids.include?(requester.id) # do not resend
      unless user_ids.include?(requester.id) # resend for the sake of it for now
        @join_requests = nil # bust cache
        self.join_request_user_ids |= [requester.id]
        self.is_dirty
        if save
          broadcast_users 'user_join_request', payload: Users::JoinRequestSerializer.serialize(join_request_for_user(requester), include: %w[list user])
        end
      end
    end

    def approve_join_request_for_user!(user)
      if join_request_user_ids.include?(user.id)
        join_request_user_ids.delete(user.id)
        user.active_list_id = self.id
        add_user(user)
        user.save
        self.is_dirty
        save and broadcast_users 'join_request_approved', id: "jr-#{user.id}"
      end
    end

    def reject_join_request_for_user!(user_id)
      user_id = user_id.id if user_id.is_a?(User) # allow model to be passed as argument
      if join_request_user_ids.include?(user_id)
        join_request_user_ids.delete(user_id)
        self.is_dirty
        if save
          # user_id is not part of the list, so should be broadcasted separately
          broadcast_user user_id, 'join_request_rejected', id: "jr-#{user_id}"
          broadcast_users 'join_request_rejected', id: "jr-#{user_id}"
        end
      end
    end
  end
end
