<template>
  <div class="page-picker">
    <popup v-if="customInput" ref="popup" overflow>
      <ul>
        <page-picker-tree-item
          v-for="page in pages"
          :page="page"
          :key="page.id"
          :page-enabled-test="pageEnabledTest"
          v-on:page-chosen="setPage"
        ></page-picker-tree-item>
      </ul>
    </popup>

    <picker-helper v-else v-model="searchQuery" ref="picker" :readonly="readonly">
      <template slot="value">
        <picker-value v-if="path" :ondelete="ondelete" :can-delete="canDelete">{{ path }}</picker-value>
      </template>
      <ul slot="options" :class="{ 'is-loading': isLoading }">
        <page-picker-tree-item
          v-for="page in pages"
          :page="page"
          :key="page.id"
          :page-enabled-test="pageEnabledTest"
          v-on:page-chosen="setPage"
          :searchQuery="searchQuery"
        ></page-picker-tree-item>
      </ul>
    </picker-helper>
  </div>
</template>

<style lang="scss" scoped>
ul {
  min-width: 200px;
  padding-left: 1.3em;
  margin: 0;

  &.is-loading {
    opacity: 0.5;
    pointer-events: none;
  }
}

.page-picker :deep(.form-control) {
  height: auto;
}
</style>

<script>
import { mapState, mapGetters } from 'vuex';
import _debounce from 'lodash/debounce';
import { ValueSyncMixin } from '../value-sync-mixin.js';
import pagePickerTreeItem from './page-picker-tree-item.vue';
import pickerHelper from '../picker-helper.vue';
import pickerValue from '../picker-value.vue';
import popup from '../popup.vue';
import PageApi from '../../api/page-api';

export default {
  mixins: [ValueSyncMixin],
  props: {
    value: {
      required: true,
      validator: (value) => value === null || typeof value === 'string',
      demoValue: null
    },
    schema: {
      type: Object
    },
    readonly: {
      type: Boolean,
      default: false
    },
    required: {
      type: Boolean,
      default: false
    },
    customInput: {},
    pageEnabledTestFn: {
      type: Function,
      default: () => 'enabled'
    }
  },
  data() {
    return {
      searchQuery: '',
      searchTree: [],
      path: ''
    };
  },
  computed: {
    ...mapState('pages', {
      allPages: 'allPages',
      isLoading: 'isLoadingPages'
    }),
    ...mapGetters('pages', ['pageTree']),
    pages() {
      return this.searchQuery ? this.searchTree : this.pageTree;
    },
    canDelete() {
      return !this.required && !this.readonly;
    }
  },
  methods: {
    ondelete() {
      this.valueCopy = null;
      this.path = '';
    },
    showPopup() {
      this.customInput ? this.$refs.popup.show(this.customInput) : this.$refs.picker.showPopup();
    },
    hidePopup() {
      this.customInput ? this.$refs.popup.hide() : this.$refs.picker?.hidePopup();
    },
    setPage(page) {
      this.path = page.url;
      this.valueCopy = page.id;

      // Come after the next focus event
      setTimeout(() => {
        this.hidePopup();
      }, 0);
    },
    search: _debounce(async function () {
      const allowedTypes = this.schema && this.schema.allowedTypes;
      this.searchTree = await PageApi.search(this.searchQuery, allowedTypes);
    }, 300),
    pageEnabledTest(page) {
      var result = this.pageEnabledTestFn(page);
      const allowedPageTypes = this.schema && this.schema.allowedTypes;
      if (allowedPageTypes) {
        const isNotAllowed = !allowedPageTypes.includes(page.pageType);
        return isNotAllowed ? 'disabled' : result;
      } else {
        return result;
      }
    }
  },
  watch: {
    searchQuery() {
      this.search();
    },
    value: {
      handler() {
        if (this.value) {
          PageApi.getPageById(this.value).then((page) => {
            this.path = page.url;
          });
        }
      },
      immediate: true
    }
  },
  components: {
    pagePickerTreeItem,
    pickerHelper,
    pickerValue,
    popup
  }
};
</script>
