<!--
Copyright Yahoo Inc.
SPDX-License-Identifier: Apache-2.0
-->
<template>
  <div class="d-inline-flex align-items-center">
    <label v-if="label" :for="`user-dropdown-${roleId}`" class="mb-0 mr-1">{{ label }}</label>
    <b-dropdown
        size="sm"
        @shown="setFocus"
        class="users-dropdown"
        data-testid="user-dropdown"
        :id="`user-dropdown-${roleId}`"
        v-b-tooltip.topright="selectedTooltip ? getUsersStr() : ''">

      <!--   Text on dropdown (configurable via default slot)   -->
      <template #button-content>
        <slot :count="localSelectedUsers.length" :filter="searchTerm" :unknown="loading || error">
          {{ getUsersStr() }}
        </slot>
      </template><!--   /Text on dropdown (configurable via default slot)   -->

      <b-dropdown-form>
        <!-- search bar -->
        <b-dropdown-header class="w-100 sticky-top">
          <b-input-group size="sm">
            <b-form-input
              debounce="400"
              v-focus="focus"
              v-model="searchTerm"
              placeholder="Begin typing to search for users by name or id"
            />
            <template #append>
              <b-button
                :disabled="!searchTerm"
                @click="clearSearchTerm"
                variant="outline-secondary"
                v-b-tooltip.hover="'Clear search'">
                <span class="fa fa-close" />
              </b-button>
            </template>
          </b-input-group>
          <b-dropdown-divider />
        </b-dropdown-header> <!-- /search bar -->

        <!-- loading -->
        <template v-if="loading">
          <div class="mt-3 text-center">
            <span class="fa fa-circle-o-notch fa-spin fa-2x" />
            <p>Loading users...</p>
          </div>
        </template> <!-- /loading -->

        <!-- error -->
        <template v-else-if="error">
          <div class="mt-3 alert alert-warning">
            <span class="fa fa-exclamation-triangle" />&nbsp;
            {{ error }}
          </div>
        </template> <!-- /error -->

        <!-- user checkboxes -->
        <template v-else>
          <b-form-checkbox-group
            class="d-flex flex-column"
            v-model="localSelectedUsers">
            <b-form-checkbox
              :key="user.userId"
              :value="user.userId"
              v-for="user in users"
              @change="updateUsers(user.userId, $event)">
              {{ user.userName }} ({{ user.userId }})
            </b-form-checkbox>
          </b-form-checkbox-group>
        </template> <!-- /user checkboxes -->
      </b-dropdown-form>
    <b-dropdown-item disabled
      v-if="users && !users.length && searchTerm">
      No users match your search
    </b-dropdown-item>
    </b-dropdown>
  </div>

</template>

<script>
import UserService from './UserService';
import Focus from './Focus.vue';

export default {
  name: 'UserDropdown',
  directives: { Focus },
  props: {
    roleId: {
      type: String,
      required: false // during creation, a role will not have an ID
    },
    selectedUsers: {
      type: Array,
      required: false // can use initializeSelectionWithRole instead
    },
    requestRoleStatus: { type: Boolean },
    initializeSelectionWithRole: { type: Boolean },
    selectedTooltip: { type: Boolean },
    label: {
      type: String,
      required: false
    }
  },
  data () {
    return {
      error: '',
      focus: false,
      loading: true,
      searchTerm: '',
      users: undefined,
      localSelectedUsers: this.selectedUsers || []
    };
  },
  watch: {
    searchTerm () {
      this.loadUsers();
    }
  },
  methods: {
    getUsersStr () {
      const userArr = [...this.localSelectedUsers];
      userArr.sort();
      return userArr.join(', ');
    },
    loadUsers () {
      const query = {
        filter: this.searchTerm
      };
      if (this.requestRoleStatus && this.roleId != null) {
        query.roleId = this.roleId;
      }

      UserService.searchUsersMin(query).then((response) => {
        this.error = '';
        this.loading = false;
        this.users = JSON.parse(JSON.stringify(response.data));
        if (this.initializeSelectionWithRole) {
          this.localSelectedUsers = this.users.filter(u => u.hasRole).map(u => u.userId);
        }
      }).catch((error) => {
        this.loading = false;
        this.error = error.text;
      });
    },
    updateUsers (userId, newSelection) { // emits both the new array and changed user-value
      const change = {
        newSelection,
        changedUser: {
          userId,
          newState: newSelection.length > this.localSelectedUsers.length
        }
      };
      this.$emit('selected-users-updated', change, this.roleId);
    },
    clearSearchTerm () {
      this.searchTerm = '';
      this.setFocus();
    },
    setFocus () {
      this.focus = true;
      setTimeout(() => {
        this.focus = false;
      }, 100);
    }
  },
  mounted () {
    this.loadUsers();
  }
};
</script>

<style scoped>
/* hides elements scrolling behind sticky search bar */
.users-dropdown .dropdown-header {
  padding: 0rem 0.5rem;
  background-color: var(--color-background);
}
.users-dropdown .dropdown-header > li {
  padding-top: 10px;
  background-color: var(--color-background);
}
.users-dropdown .dropdown-divider {
  margin-top: 0px;
}

.users-dropdown .dropdown-item,
.users-dropdown .custom-control {
  padding-left: 2rem;
}
</style>
