// @ts-nocheck

/* eslint-disable */
// Components
import { VData } from "../VData/index.mjs";
import VDataFooter from "./VDataFooter.mjs"; // Mixins

import Mobile from "../../mixins/mobile/index.mjs";
import Themeable from "../../mixins/themeable/index.mjs"; // Helpers

import mixins from "../../util/mixins.mjs";
import { deepEqual, getObjectValueByPath, getPrefixedScopedSlots, getSlot, camelizeObjectKeys, keyCodes } from "../../util/helpers.mjs";
import { breaking, removed } from "../../util/console.mjs"; // Types

/* @vue/component */
export default mixins(Mobile, Themeable).extend({
  name: 'v-data-iterator',
  props: { ...VData.options.props,
    // TODO: filter out props not used
    itemKey: {
      type: String,
      default: 'id'
    },
    value: {
      type: Array,
      default: () => []
    },
    singleSelect: Boolean,
    expanded: {
      type: Array,
      default: () => []
    },
    mobileBreakpoint: { ...Mobile.options.props.mobileBreakpoint,
      default: 600
    },
    singleExpand: Boolean,
    loading: [Boolean, String],
    noResultsText: {
      type: String,
      default: '$vuetify.dataIterator.noResultsText'
    },
    noDataText: {
      type: String,
      default: '$vuetify.noDataText'
    },
    loadingText: {
      type: String,
      default: '$vuetify.dataIterator.loadingText'
    },
    hideDefaultFooter: Boolean,
    footerProps: Object,
    selectableKey: {
      type: String,
      default: 'isSelectable'
    }
  },
  data: () => ({
    selection: {},
    expansion: {},
    internalCurrentItems: [],
    shiftKeyDown: false,
    lastEntry: -1
  }),
  computed: {
    everyItem() {
      return !!this.selectableItems.length && this.selectableItems.every(i => this.isSelected(i));
    },

    someItems() {
      return this.selectableItems.some(i => this.isSelected(i));
    },

    sanitizedFooterProps() {
      return camelizeObjectKeys(this.footerProps);
    },

    selectableItems() {
      return this.internalCurrentItems.filter(item => this.isSelectable(item));
    }

  },
  watch: {
    value: {
      handler(value) {
        this.selection = value.reduce((selection, item) => {
          selection[getObjectValueByPath(item, this.itemKey)] = item;
          return selection;
        }, {});
      },

      immediate: true
    },

    selection(value, old) {
      if (deepEqual(Object.keys(value), Object.keys(old))) return;
      this.$emit('input', Object.values(value));
    },

    expanded: {
      handler(value) {
        this.expansion = value.reduce((expansion, item) => {
          expansion[getObjectValueByPath(item, this.itemKey)] = true;
          return expansion;
        }, {});
      },

      immediate: true
    },

    expansion(value, old) {
      if (deepEqual(value, old)) return;
      const keys = Object.keys(value).filter(k => value[k]);
      const expanded = !keys.length ? [] : this.items.filter(i => keys.includes(String(getObjectValueByPath(i, this.itemKey))));
      this.$emit('update:expanded', expanded);
    }

  },

  created() {
    const breakingProps = [['disable-initial-sort', 'sort-by'], ['filter', 'custom-filter'], ['pagination', 'options'], ['total-items', 'server-items-length'], ['hide-actions', 'hide-default-footer'], ['rows-per-page-items', 'footer-props.items-per-page-options'], ['rows-per-page-text', 'footer-props.items-per-page-text'], ['prev-icon', 'footer-props.prev-icon'], ['next-icon', 'footer-props.next-icon']];
    /* istanbul ignore next */

    breakingProps.forEach(([original, replacement]) => {
      if (this.$attrs.hasOwnProperty(original)) breaking(original, replacement, this);
    });
    const removedProps = ['expand', 'content-class', 'content-props', 'content-tag'];
    /* istanbul ignore next */

    removedProps.forEach(prop => {
      if (this.$attrs.hasOwnProperty(prop)) removed(prop);
    });
  },

  mounted() {
    window.addEventListener('keydown', this.onKeyDown);
    window.addEventListener('keyup', this.onKeyUp);
  },

  beforeDestroy() {
    window.removeEventListener('keydown', this.onKeyDown);
    window.removeEventListener('keyup', this.onKeyUp);
  },

  methods: {
    onKeyDown(e) {
      if (e.keyCode !== keyCodes.shift) return;
      this.shiftKeyDown = true;
    },

    onKeyUp(e) {
      if (e.keyCode !== keyCodes.shift) return;
      this.shiftKeyDown = false;
    },

    toggleSelectAll(value) {
      const selection = Object.assign({}, this.selection);

      for (let i = 0; i < this.selectableItems.length; i++) {
        const item = this.selectableItems[i];
        if (!this.isSelectable(item)) continue;
        const key = getObjectValueByPath(item, this.itemKey);
        if (value) selection[key] = item;else delete selection[key];
      }

      this.selection = selection;
      this.$emit('toggle-select-all', {
        items: this.internalCurrentItems,
        value
      });
    },

    isSelectable(item) {
      return getObjectValueByPath(item, this.selectableKey) !== false;
    },

    isSelected(item) {
      return !!this.selection[getObjectValueByPath(item, this.itemKey)] || false;
    },

    select(item, value = true, emit = true) {
      if (!this.isSelectable(item)) return;
      const selection = this.singleSelect ? {} : Object.assign({}, this.selection);
      const key = getObjectValueByPath(item, this.itemKey);
      if (value) selection[key] = item;else delete selection[key];
      const index = this.selectableItems.findIndex(x => x.name === item.name);
      if (this.lastEntry === -1) this.lastEntry = index;else if (this.shiftKeyDown && !this.singleSelect && emit) this.multipleSelect(value, emit, selection, index);
      this.lastEntry = index;

      if (this.singleSelect && emit) {
        const keys = Object.keys(this.selection);
        const old = keys.length && getObjectValueByPath(this.selection[keys[0]], this.itemKey);
        old && old !== key && this.$emit('item-selected', {
          item: this.selection[old],
          value: false
        });
      }

      this.selection = selection;
      emit && this.$emit('item-selected', {
        item,
        value
      });
    },

    multipleSelect(value = true, emit = true, selection, index) {
      const start = index < this.lastEntry ? index : this.lastEntry;
      const end = index < this.lastEntry ? this.lastEntry : index;

      for (let i = start; i <= end; i++) {
        const currentItem = this.selectableItems[i];
        const key = getObjectValueByPath(currentItem, this.itemKey);
        if (value) selection[key] = currentItem;else delete selection[key];
        emit && this.$emit('item-selected', {
          currentItem,
          value
        });
      }
    },

    isExpanded(item) {
      return this.expansion[getObjectValueByPath(item, this.itemKey)] || false;
    },

    expand(item, value = true) {
      const expansion = this.singleExpand ? {} : Object.assign({}, this.expansion);
      const key = getObjectValueByPath(item, this.itemKey);
      if (value) expansion[key] = true;else delete expansion[key];
      this.expansion = expansion;
      this.$emit('item-expanded', {
        item,
        value
      });
    },

    createItemProps(item, index) {
      return {
        item,
        index,
        select: v => this.select(item, v),
        isSelected: this.isSelected(item),
        expand: v => this.expand(item, v),
        isExpanded: this.isExpanded(item),
        isMobile: this.isMobile
      };
    },

    genEmptyWrapper(content) {
      return this.$createElement('div', content);
    },

    genEmpty(originalItemsLength, filteredItemsLength) {
      if (originalItemsLength === 0 && this.loading) {
        const loading = this.$slots.loading || this.$vuetify.lang.t(this.loadingText);
        return this.genEmptyWrapper(loading);
      } else if (originalItemsLength === 0) {
        const noData = this.$slots['no-data'] || this.$vuetify.lang.t(this.noDataText);
        return this.genEmptyWrapper(noData);
      } else if (filteredItemsLength === 0) {
        const noResults = this.$slots['no-results'] || this.$vuetify.lang.t(this.noResultsText);
        return this.genEmptyWrapper(noResults);
      }

      return null;
    },

    genItems(props) {
      const empty = this.genEmpty(props.originalItemsLength, props.pagination.itemsLength);
      if (empty) return [empty];

      if (this.$scopedSlots.default) {
        return this.$scopedSlots.default({ ...props,
          isSelected: this.isSelected,
          select: this.select,
          isExpanded: this.isExpanded,
          isMobile: this.isMobile,
          expand: this.expand
        });
      }

      if (this.$scopedSlots.item) {
        return props.items.map((item, index) => this.$scopedSlots.item(this.createItemProps(item, index)));
      }

      return [];
    },

    genFooter(props) {
      if (this.hideDefaultFooter) return null;
      const data = {
        props: { ...this.sanitizedFooterProps,
          options: props.options,
          pagination: props.pagination
        },
        on: {
          'update:options': value => props.updateOptions(value)
        }
      };
      const scopedSlots = getPrefixedScopedSlots('footer.', this.$scopedSlots);
      return this.$createElement(VDataFooter, {
        scopedSlots,
        ...data
      });
    },

    genDefaultScopedSlot(props) {
      const outerProps = { ...props,
        someItems: this.someItems,
        everyItem: this.everyItem,
        toggleSelectAll: this.toggleSelectAll
      };
      return this.$createElement('div', {
        staticClass: 'v-data-iterator'
      }, [getSlot(this, 'header', outerProps, true), this.genItems(props), this.genFooter(props), getSlot(this, 'footer', outerProps, true)]);
    }

  },

  render() {
    return this.$createElement(VData, {
      props: this.$props,
      on: {
        'update:options': (v, old) => !deepEqual(v, old) && this.$emit('update:options', v),
        'update:page': v => this.$emit('update:page', v),
        'update:items-per-page': v => this.$emit('update:items-per-page', v),
        'update:sort-by': v => this.$emit('update:sort-by', v),
        'update:sort-desc': v => this.$emit('update:sort-desc', v),
        'update:group-by': v => this.$emit('update:group-by', v),
        'update:group-desc': v => this.$emit('update:group-desc', v),
        pagination: (v, old) => !deepEqual(v, old) && this.$emit('pagination', v),
        'current-items': v => {
          this.internalCurrentItems = v;
          this.$emit('current-items', v);
        },
        'page-count': v => this.$emit('page-count', v)
      },
      scopedSlots: {
        default: this.genDefaultScopedSlot
      }
    });
  }

});
//# sourceMappingURL=VDataIterator.mjs.map