<script>
import { GlCollapsibleListbox } from '@gitlab/ui';
import { debounce } from 'lodash';
import { createAlert } from '~/alert';
import { __ } from '~/locale';
import axios from '~/lib/utils/axios_utils';

export default {
  components: {
    GlCollapsibleListbox,
  },
  props: {
    staticData: {
      type: Array,
      required: false,
      default: () => [],
    },
    endpoint: {
      type: String,
      required: false,
      default: '',
    },
    default: {
      type: Object,
      required: true,
    },
    dropdownHeader: {
      type: String,
      required: true,
    },
    isProject: {
      type: Boolean,
      required: false,
      default: false,
    },
    inputId: {
      type: String,
      required: true,
    },
    inputName: {
      type: String,
      required: true,
    },
    toggleClass: {
      type: String,
      required: false,
      default: '',
    },
    qaSelector: {
      type: String,
      required: false,
      default: null,
    },
  },
  data() {
    return {
      current: this.default,
      selected: this.default.value,
      isLoading: false,
      data: this.staticData,
      searchStr: '',
    };
  },
  computed: {
    filteredData() {
      if (this.endpoint) return this.data;

      return this.data.filter(
        (d) => d.text.toLowerCase().indexOf(this.searchStr.toLowerCase()) >= 0,
      );
    },
  },
  methods: {
    async fetchData() {
      if (!this.endpoint) return;

      this.isLoading = true;

      try {
        const { data } = await axios.get(this.endpoint, {
          params: { search: this.searchStr },
        });

        if (this.isProject) {
          this.data = data.map((p) => ({
            value: `${p.id}`,
            text: p.full_path.replace(/^\//, ''),
            refsUrl: p.refs_url,
          }));
        } else {
          this.data = data.Branches.map((d) => ({
            value: d,
            text: d,
          }));
        }

        this.isLoading = false;
      } catch {
        createAlert({
          message: __('Error fetching data. Please try again.'),
          primaryButton: { text: __('Try again'), clickHandler: () => this.fetchData() },
        });
      }
    },
    searchData: debounce(function searchData(search) {
      this.searchStr = search;
      this.fetchData();
    }, 500),
    selectItem(id) {
      this.current = this.data.find((d) => d.value === id);

      this.$emit('selected', this.current);
    },
  },
};
</script>

<template>
  <div>
    <input
      :id="inputId"
      type="hidden"
      :value="current.value"
      :name="inputName"
      data-testid="target-project-input"
    />
    <gl-collapsible-listbox
      v-model="selected"
      :items="filteredData"
      :toggle-text="current.text || dropdownHeader"
      :header-text="dropdownHeader"
      :searching="isLoading"
      searchable
      class="gl-w-full dropdown-target-project"
      :toggle-class="[
        'gl-align-items-flex-start! gl-justify-content-start! mr-compare-dropdown',
        toggleClass,
      ]"
      :data-qa-selector="qaSelector"
      @shown="fetchData"
      @search="searchData"
      @select="selectItem"
    />
  </div>
</template>
