<script>
import $ from 'jquery';
import 'select2/select2';
import _ from 'underscore';
import Api from 'ee/api';
import { __ } from '~/locale';

const anyBranch = {
  id: null,
  name: __('Any branch'),
};

function formatSelection(object) {
  return `<span>${object.name}</span>`;
}
function formatResult(result) {
  const isAnyBranch = result.id ? `monospace` : '';

  return `
    <span class="result-name ${isAnyBranch}">${result.name}</span>
  `;
}

export default {
  props: {
    projectId: {
      type: String,
      required: true,
    },
    initRule: {
      type: Object,
      required: false,
      default: null,
    },
    isInvalid: {
      type: Boolean,
      required: false,
      default: false,
    },
  },
  watch: {
    value(val) {
      if (val.length > 0) {
        this.clear();
      }
    },
    isInvalid(val) {
      const $container = this.$input.select2('container');

      $container.toggleClass('is-invalid', val);
    },
  },
  mounted() {
    const $modal = $('#project-settings-approvals-create-modal .modal-content');
    this.$input = $(this.$refs.input);

    this.$input
      .select2({
        minimumInputLength: 0,
        multiple: false,
        closeOnSelect: false,
        formatResult,
        formatSelection,
        initSelection: (element, callback) => this.initialOption(element, callback),
        query: _.debounce(({ term, callback }) => this.fetchBranches(term).then(callback), 250),
        id: ({ type, id }) => `${type}${id}`,
      })
      .on('change', e => this.onChange(e))
      .on('select2-open', () => {
        // https://stackoverflow.com/questions/18487056/select2-doesnt-work-when-embedded-in-a-bootstrap-modal
        // Ensure search feature works in modal
        // (known issue with our current select2 version, solved in version 4 with "dropdownParent")
        $modal.removeAttr('tabindex', '-1');
      })
      .on('select2-close', () => {
        $modal.attr('tabindex', '-1');
      });
  },
  beforeDestroy() {
    this.$input.select2('destroy');
  },
  methods: {
    fetchBranches(term) {
      const excludeAnyBranch = term && !term.toLowerCase().includes('any');
      return Api.projectProtectedBranches(this.projectId, term).then(results => ({
        results: excludeAnyBranch ? results : [anyBranch, ...results],
      }));
    },
    initialOption(element, callback) {
      let currentBranch = anyBranch;

      if (this.initRule?.protectedBranches.length) {
        const { name, id } = this.initRule.protectedBranches[0];
        if (id) {
          currentBranch = { name, id };
          this.selectedId = id;
        }
      }

      return callback(currentBranch);
    },
    onChange() {
      const value = this.$input.select2('data');
      this.$emit('input', value.id);
    },
    clear() {
      this.$input.select2('data', []);
    },
  },
};
</script>

<template>
  <input ref="input" name="protected_branch_ids" type="hidden" />
</template>
