<template>
  <div>
    <template v-for="(item, n) in rows">
      <div
        :key="n"
        group="items"
        data-test="table-item"
        class="table-view-item grouped draggable-item"
        :class="{'selected': selectedIds.includes(item[idProperty]), 'active': isActive(item[idProperty]), 'disabled': item.isDisabled, [cssProperty && item[cssProperty]]: !!item[cssProperty]}"
      >
        <div class="table-row-template">
          <div accept-group="items" class="table-view-body-space"></div>
          <div class="shadow-area">
            <div class="toggler-wrapper"></div>
            <div class="handle-wrapper hover-only">
              <a href="" class="context-menu-toggle table-item-options-menu">
                <div class="v-popper--has-tooltip drag-handle">
                  <i data-test="table-item-options" class="ic-drag"></i>
                </div>
              </a>
            </div>
          </div>
          <div class="indicator sticky">
            <div v-if="indicatorType !== 'none'" class="table-view-row-count">
              <span v-if="indicatorType === 'order'">{{ (n + 1) }}</span>
              <span v-else-if="indicatorType === 'property'">{{ item[idProperty] }}</span>
              <span v-else-if="indicatorType === 'checkbox'"><itf-checkbox :disabled="item.isDisabled" :value="item[idProperty]" /></span>
            </div>
          </div>
          <div accept-group="items" class="table-item-inner" @click="$emit('row-click', item)">
            <template v-for="(column, k) in visibleAttributes">
              <div
                v-if="column.visible !== false"
                :data-column="k"
                :style="`width: ${column.width}px; max-width: ${column.width}px; left: ${column.left}px;`"
                :class="{[column.cssClass]: !!column.cssClass, 'justify-content-end': column.align === 'end', 'sticky': column.pinned && !getIsMobileView(), 'last-sticky-column': k === lastPinnedIndex && !getIsMobileView(), 'editable': column.editable && editable}"
                class="table-view-item-value d-flex h-100">
                <div class="table-view-item-value-content" :class="{'px-2': !(column.editable && editable), 'py-1': (column.editable && editable)}">
                  <slot
                    :name="`column.${column.property}`"
                    :toggle="() => $emit('toggle', item)"
                    :hasSubitems="!!(subrowsProperty && item[subrowsProperty] && item[subrowsProperty].length)"
                    :isExpanded="!!(item[subrowsProperty] && item[subrowsProperty].length && !isExpanded(item))"
                    :level="level" :editable="column.editable && editable" :item="item" :column="column" :updateFields="(val) => updateValues(item, val, n, column)" :update="(val) => updateValue(item, val, n, column)" :value="getValue(item, column)">
                    <template v-if="column.editable && editable && (!editableProperty || item[editableProperty])">
                      <slot :name="`edit.${column.type}`" :level="level" :toggle="() => $emit('toggle', item)" :update="(val) => updateValue(item, val, n, column)" :value="getValue(item, column)" :item="item" :column="column">
                        <itf-text-field class="w-100" v-if="column.type === 'text'" :postfix="column.postfix" :maxlength="column.maxlength" :value="getValue(item, column)" @input="updateValue(item, $event, n, column)" />
                        <itf-text-field class="w-100" v-if="column.type === 'number'" :postfix="column.postfix" :max="column.max" :min="column.min" :step="column.step" :maxlength="column.maxlength" type="number" :value="getValue(item, column)" @input="updateValue(item, $event, n, column)" />
                        <itf-hours-field
                          class="w-100 h-100"
                          placeholder="00h 00m"
                          v-else-if="column.type === 'time'"
                          :hours="getValue(item, column)"
                          @update:hours="updateValue(item, $event, n, column)"
                        />
                        <itf-textarea class="w-100" :rows="1" autogrow v-else-if="column.type === 'textarea'" :value="getValue(item, column)" @input="updateValue(item, $event, n, column)" />
                        <itf-money-field class="w-100" currency-disabled :currency="currency" :currencies="currencies" v-else-if="column.type === 'money'" :value="getValue(item, column)" @input="updateValue(item, $event, n, column)" />
                        <itf-select class="w-100" v-else-if="column.type === 'select'" :reduce="(item) => item.value" :value="getValue(item, column)" @input="updateValue(item, $event, n, column)" :options="column.options"></itf-select>
                      </slot>
                    </template>
                    <div v-else class="h-100 align-items-center d-flex w-100">
                      <slot :name="`format.${column.type}`" :toggle="() => $emit('toggle', item)" :level="level" :value="getValue(item, column)" :update="(value) => updateValue(item, value, n, column)" :item="item" :column="column">
                        {{getValue(item, column)}}
                      </slot>
                    </div>
                  </slot>
                </div>
              </div>
            </template>
            <div class="table-view-item-value extra"></div>
            <div v-if="showActions" class="table-view-item-actions">
              <slot name="actions" :level="level" :toggle="() => $emit('toggle', item)" :item="item"></slot>
            </div>
            <div class="boundary top"></div>
            <div class="boundary right"></div>
            <div class="boundary bottom"></div>
            <div class="boundary left"></div>
          </div>
        </div>
      </div>
      <template v-if="subrowsProperty && item[subrowsProperty] && item[subrowsProperty].length">
        <itf-table-rows
          v-show="isExpanded(item)"
          :selected-ids="selectedIds"
          :rows="item[subrowsProperty]"
          :columns="columns"
          :id-property="idProperty"
          :subrows-property="subrowsProperty"
          :show-add-column="showAddColumn"
          :show-actions="showActions"
          :no-select-all="noSelectAll"
          :editable="editable"
          :currency="currency"
          :currencies="currencies"
          :indicator-type="indicatorType"
          :level="level + 1"
          :expanded-ids="expandedIds"
          :expanded-all="expandedAll"
          :css-property="cssProperty"
          :editable-property="editableProperty"
          :active="active"
          @update="$emit('update', $event)"
          @toggle="$emit('toggle', $event)"
        >
          <template v-for="(_, name) in $slots" #[name]="slotData">
            <slot :name="name" v-bind="slotData || {}" />
          </template>
          <template v-for="(_, name) in $scopedSlots" #[name]="slotData">
            <slot :name="name" v-bind="slotData || {}" />
          </template>
        </itf-table-rows>
      </template>
      <div v-if="dividerProperty && item[dividerProperty]" :key="`divider-${n}`" class="itf-table2__row-divider"></div>
    </template>
  </div>
</template>
<script>
import { Vue, Component, Prop } from 'vue-property-decorator';
import get from 'lodash/get';
import set from 'lodash/set';
// import { RecycleScroller } from 'vue-virtual-scroller'
import itfCheckbox from '../checkbox/Checkbox.vue';
import itfTextField from '../text-field/TextField.vue';
import itfMoneyField from '../text-field/MoneyField.vue';
import itfTextarea from '../text-field/Textarea.vue';
import itfHoursField from '../text-field/HoursField.vue';
import itfSelect from '../select/Select.vue';
import itfTableBody from './TableBody.vue';
import { getIsMobileView } from "./mobile";
// import 'vue-virtual-scroller/dist/vue-virtual-scroller.css';

export default @Component({
  name: 'itfTableRows',
  components: {
    itfTableBody,
    itfCheckbox,
    itfMoneyField,
    itfHoursField,
    itfTextarea,
    itfTextField,
    itfSelect,
    // RecycleScroller
  }
})
class itfTableRows extends Vue {
  @Prop() columns;
  @Prop() rows;
  @Prop() idProperty;
  @Prop() subrowsProperty;
  @Prop() dividerProperty;
  @Prop() active;
  @Prop(Boolean) showAddColumn;
  @Prop(Boolean) noSelectAll;
  @Prop(Boolean) editable;
  @Prop(Boolean) expandedAll;
  @Prop(Boolean) striped;
  @Prop(Boolean) showActions;
  @Prop() editableProperty;
  @Prop() selectedIds;
  @Prop() expandedIds;
  @Prop() currency;
  @Prop() currencies;
  @Prop() cssProperty;
  @Prop({ type: Number, default: 0 }) level;
  @Prop({ type: String, default: null, validator: (val) => ['none', 'order', 'checkbox', 'toggle', 'property'].includes(val) }) indicatorType;

  getValue(item, column) {
    return get(item, column.property);
  }

  get visibleAttributes() {
    return this.columns;
  }

  get lastPinnedIndex() {
    return this.columns.findIndex((column) => column.lastPinned);
  }

  getIsMobileView() {
    return getIsMobileView();
  }

  updateValue(item, value, index, column) {
    const newItem = { ...item };
    if (newItem[column.property] !== value) {
      set(newItem, column.property, value);
      this.$emit('update', {
        index,
        item,
        inputValue: value,
        value: newItem,
        column
      });
    }
  }

  updateValues(item, values, index, column) {
    const newItem = { ...item };
    Object.assign(newItem, values);
    this.$emit('update', {
      index,
      item,
      inputValue: values,
      value: newItem,
      column
    });
  }

  isActive(id) {
    if (!this.idProperty) {
      return false;
    }
    if (Array.isArray(this.active)) {
      return this.active.includes(id);
    }
    return this.active === id;
  }

  isExpanded(item) {
    const isExpanded = this.expandedIds.includes(item[this.idProperty]);
    return this.expandedAll ? !isExpanded : isExpanded;
  }
}
</script>
