<template>
  <div class="x-admin-tabs">
    <ElTabs
      class="x-admin-tabs__tabs"
      ref="tabs"
      type="card"
      @tab-remove="handleTabRemove"
      @tab-click="handleTabClick"
      v-model="currentValue">
      <ElTabPane v-for="item in showTabs"
                 :key="`tab-panel-${item.name}`"
                 :name="item.name"
                 lazy
                 v-bind="item">
        <template #label>
          <ElPopover trigger="hover"
                     popper-class="x-admin-tabs-tip"
                     width="auto"
                     :open-delay="300"
                     :disabled="isDisabled(item)">
          <span class="x-admin-tabs__label" slot="reference" :draggable="$admin.enableDialog && !item.home && item.enableDialog!==false"
                @dragstart="handleDropStart($event, item)">
            <XIcon v-if="item.icon" v-bind="iconProps(item.icon)" :size="12"></XIcon>
            {{item.label}}
          </span>
            <div class="x-admin-tabs-tip__content">
              <template v-if="item.enableRefresh !== false">
                <ElLink icon="el-icon-refresh"
                        :underline="false"
                        @click="$admin.reload(item)">刷新
                </ElLink>
                <ElDivider direction="vertical"></ElDivider>
              </template>
              <template v-if="!item.home && item.enableFavorite !== false">
                <ElLink :icon="`el-icon-star-${isFavorite(item)?'on':'off'}`"
                        :underline="false"
                        @click="toggleFavorite(item)">
                  收藏
                </ElLink>
                <ElDivider direction="vertical"></ElDivider>
              </template>
              <template v-if="$admin.enableDialog && !item.home && item.enableDialog !== false">
                <ElLink icon="el-icon-copy-document" :underline="false"
                        @click="$admin.openDialog(item)">弹出
                </ElLink>
              </template>
            </div>
          </ElPopover>
        </template>
      </ElTabPane>
    </ElTabs>
    <Dropdown class="x-admin-tabs__menu" placement="top-start" @command="handleCommand">
      <XIcon class="x-admin-icon-button" name="el-icon-more" :size="12"></XIcon>
      <DropdownMenu slot="dropdown">
        <DropdownItem command="other">关闭其他</DropdownItem>
        <DropdownItem command="all">关闭所有</DropdownItem>
        <DropdownItem v-for="item in dropdownTabs"
                      class="x-admin-tabs__menu-item"
                      :command="item"
                      :key="`dropdown-${item.name}`">{{item.label}}
          <i v-if="item.label" class="el-icon-close" @click.stop="removeTab(item)"></i>
        </DropdownItem>
      </DropdownMenu>
    </Dropdown>
  </div>
</template>

<script>
import {
  Tabs as ElTabs,
  TabPane as ElTabPane,
  Popover as ElPopover,
  Link as ElLink,
  Divider as ElDivider,
  Dropdown,
  DropdownMenu,
  DropdownItem,
  MessageBox
} from 'element-ui';
import { XIcon } from '@newpearl/ui';

export default {
  inject: ['$admin'],
  components: {
    ElTabs,
    ElTabPane,
    ElPopover,
    ElLink,
    ElDivider,
    Dropdown,
    DropdownMenu,
    DropdownItem,
    XIcon
  },
  props: {
    items: {
      type: Array,
      default() {
        return [];
      }
    },
    value: {
      type: String
    },
    limit: Number,
    beforeRemoveTab: Function
  },
  data() {
    return {
      currentValue: ''
    };
  },
  computed: {
    showTabs() {
      const { homeTabName, homePath } = this.$admin;
      const tabs = [{ name: homeTabName, path: homePath, home: true, icon: 'el-icon-s-home', closable: false }];
      const limitTabs = this.items.filter(n => !n.dialog).slice(0, this.limit);
      return tabs.concat(limitTabs);
    },
    dropdownTabs() {
      return this.items.filter(n => !n.dialog).slice(this.limit);
    },
    favorites() {
      const map = Object.create(null);
      this.$admin.favorites.forEach(n => {
        map[n.index] = n;
      });
      return map;
    }
  },
  watch: {
    currentValue(v) {
      this.$emit('input', v);
    },
    value: {
      immediate: true,
      handler(v) {
        this.currentValue = v;
      }
    }
  },
  methods: {
    isDisabled(tab) {
      const enables = ['enableRefresh', 'enableFavorite', 'enableDialog'];
      return this.currentValue !== tab.name || enables.every(n => tab[n] === false);
    },
    iconProps(icon) {
      return typeof icon === 'string' ? { name: icon } : icon;
    },
    handleCommand(command) {
      switch (command) {
        case 'all':
          MessageBox.confirm('是否关闭所有页签', '温馨提示', { type: 'warning' })
            .then(r => {
              this.$admin.removeAllTabs();
            });
          break;
        case 'other':
          MessageBox.confirm('是否关闭其他页签', '温馨提示', { type: 'warning' })
            .then(r => {
              const item = this.showTabs.find(n => n.name === this.currentValue);
              if (item) {
                this.$admin.removeOtherTabs(item);
              }
            });
          break;
        default:
          this.$admin.addTab(command);
          break;
      }
    },
    async removeTab(item) {
      const { removeTab, getViewCacheInstance } = this.$admin;
      const vm = getViewCacheInstance(item.path);
      if (vm && vm.$options.beforeRemoveTab) {
        const result = await vm.$options.beforeRemoveTab.call(vm, item);
        if (result !== false) {
          removeTab(item, true);
        }
        return;
      }
      if (this.beforeRemoveTab) {
        const result = await this.beforeRemoveTab(item);
        if (result !== false) {
          removeTab(item, true);
        }
        return;
      }
      MessageBox.confirm('是否关闭页签', '温馨提示', { type: 'warning' }).then(r => removeTab(item, true));
    },
    handleTabRemove(name) {
      const item = this.showTabs.find(n => n.name === name);
      if (item) {
        this.removeTab(item);
      }
    },
    handleTabClick({ index }) {
      const tab = this.showTabs[Number.parseInt(index)];
      this.$emit('tab-click', tab);
    },
    isFavorite(item) {
      return !!this.favorites[item.index || item.path];
    },
    toggleFavorite(item) {
      if (this.isFavorite(item)) {
        this.$admin.$emit('remove-favorite', item);
      } else {
        this.$admin.$emit('add-favorite', item);
      }
    },
    handleDropStart(e, tab) {
      this.$admin.isTabDragging = true;
      e.dataTransfer.setData('tabId', tab._id.toString());
    }
  }
};
</script>
