<template>
  <li>
    <span
      v-if="!searchQuery"
      :class="['expander', expanded ? 'icon-minus' : expandable ? 'icon-plus' : null]"
      @click="expandCollapse()"
    ></span>
    <p
      @click="choosePage"
      :class="{ 'not-enabled': !enabled, 'not-published': !isPublished(page.id), 'search-result': page.isSearchResult }"
    >
      {{ page.name }}
      <span v-if="!enabled">🚫</span>
    </p>
    <ul v-if="expanded">
      <page-picker-tree-item
        v-for="subPage in page.children"
        :page="subPage"
        :key="subPage.id"
        :page-enabled-test="subpageEnabledTest"
        ref="children"
        v-on:page-chosen="bubbleEvent"
        :searchQuery="searchQuery"
      ></page-picker-tree-item>
    </ul>
  </li>
</template>

<style lang="scss" scoped>
ul,
li {
  list-style: none;
  margin: 0;
  padding: 0;
  position: relative;
}
ul {
  padding-left: 1em;
}
p {
  margin: 0 2px;
  padding: 2px 3px;
  cursor: pointer;

  &.search-result {
    font-weight: bold;
  }

  &.not-published {
    color: #bbb;
  }

  &.not-enabled {
    cursor: not-allowed;
  }

  &:not(.not-enabled):hover {
    background: #eee;
  }
}
.expander {
  cursor: pointer;
  position: absolute;
  right: 100%;
  top: 9px;
  font-size: 10px;
}
</style>

<script>
import { mapActions, mapState } from 'vuex';

export default {
  name: 'page-picker-tree-item',
  props: {
    page: {
      type: Object
    },
    pageEnabledTest: {
      type: Function
    },
    searchQuery: {
      type: String
    }
  },
  data() {
    return {
      expanded: false
    };
  },
  methods: {
    ...mapActions('pages', ['expandPage', 'collapsePage']),
    choosePage() {
      if (this.enabled) {
        this.bubbleEvent(this.page);
      }
    },
    bubbleEvent(page) {
      // page-picker-tree-item can be nested, so can't emit 'this.page.id', because that is the current page-picker-tree-item
      this.$emit('page-chosen', page);
    },
    expandCollapse() {
      if (this.expanded) {
        this.collapsePage(this.page.id);
      } else {
        this.expandPage(this.page.id);
      }
      this.expanded = !this.expanded;
    },
    isPublished(pageId) {
      return this.publishedPageIds.includes(pageId);
    }
  },
  computed: {
    ...mapState('pages', ['publishedPageIds']),
    pageEnabled() {
      var pageEnabled = this.pageEnabledTest(this.page);
      if (!['enabled', 'disabled', 'subtree-disabled'].includes(pageEnabled)) {
        console.warn(`page-enabled-test must return 'enabled', 'disabled' or 'subtree-disabled', got ${pageEnabled}`);
      }
      return pageEnabled;
    },
    expandable() {
      return this.page.hasUnloadedChildren || (this.hasChildren && !this.expanded);
    },
    enabled() {
      return this.pageEnabled == 'enabled' && this.page.isSelectable;
    },
    subpageEnabledTest() {
      return this.pageEnabled == 'subtree-disabled' ? () => 'disabled' : this.pageEnabledTest;
    },
    hasChildren() {
      return this.page.children && this.page.children.length;
    },
    isPageCollapsed() {
      return this.$store.getters['pages/isPageCollapsed'](this.page.id);
    }
  },
  watch: {
    searchQuery: {
      handler() {
        this.expanded = this.isPageCollapsed ? !!this.searchQuery : !!this.hasChildren;
      },
      immediate: true
    }
  }
};
</script>
