<template>
  <tr
    class="c-data-table__row"
    @mouseenter="$emit('mouseenter', $event)"
    @mouseleave="$emit('mouseleave', $event)"
    @click="handleRowClick($event)"
    :class="classesForRow">

    <!-- triggers column start -->
    <td
      v-if="hasActionableElements"
      class="c-data-table__block c-data-table__block--action"
      :class="{ 'c-data-table__block--pinned': pinFirstColumn }">

      <div v-if="!isChildRow && !isSummary" class="c-data-table__triggers">

        <!-- radio/checkbox start -->
        <div v-if="singleSelect || selectable" class="c-data-table__trigger">
          <el-radio
            v-if="singleSelect"
            v-model="rowData.$selected"
            :label="rowData.$rowId"
            class="u-p0"
            @click.native.stop
            @change="$emit('row-selected', rowData)"
          ></el-radio>
          <el-checkbox
            v-else-if="selectable"
            v-model="rowData.$selected"
            @click.native.stop
            @change="$emit('row-selected', rowData)">
          </el-checkbox>
        </div>
        <!-- radio/checkbox end -->

        <!-- drag handle start -->
        <div v-if="draggable && !searchQuery" class="c-data-table__trigger drag-handle">
          <fa-icon icon="bars" aria-hidden="true" />
        </div>
        <!-- drag handle end -->

        <!-- collapsible row trigger start -->
        <div v-if="hasCollapsibleRows" class="c-data-table__trigger">
          <el-button
            class="u-link"
            @click.native.stop
            @click="toggleCollapsed">
            <!-- 100% width when open so the icon remains it's original size -->
            <fa-icon
              :icon="['fal', 'chevron-right']"
              class="c-data-table__collapse-arrow"
              :class="{ 'c-data-table__collapse-arrow--open': !rowData.$collapsed }" />
          </el-button>
        </div>
        <!-- collapsible row trigger end -->

        <!-- child rows trigger start -->
        <div v-if="hasChildRows" class="c-data-table__trigger">
          <fa-icon
            v-if="rowData.$childrenData.loading"
            class="c-data-table__icon icon--spin-fast"
            :icon="['far', 'spinner-third']" spin></fa-icon>
          <el-button
            v-else
            class="u-link"
            @click.native.stop
            @click="toggleCollapseChildRows">
            <!-- 100% width when open so the icon remains its original size -->
            <fa-icon
              :icon="['fal', 'chevron-right']"
              class="c-data-table__collapse-arrow"
              :class="{ 'c-data-table__collapse-arrow--open': !rowData.$childrenData.collapsed }" />
          </el-button>
        </div>
        <!-- child rows trigger end -->

      </div>

    </td>
    <!-- triggers column end -->

    <!-- user-provided columns start -->
    <template v-for="(column, index) in columns">
      <component
        v-if="column.visible"
        v-on="column.$listeners"
        :is="rowData.$link && column.enableLink ? 'router-link' : 'td'"
        :to="rowData.$link"
        :key="column.dataKey + index"
        tag="td"
        class="c-data-table__block"
        :class="{
          [`c-data-table__block--${column.computedAlign}`]: !!column.computedAlign,
          'c-data-table__block--pinned': pinFirstColumn && index === 0
        }"
        :style="index === 0 && pinFirstColumn && hasActionableElements ? { left: pinnedColumnLeftOffset } : {}">
          <el-data-table-cell v-bind="{ rowData, column, isSummary }" />
      </component>
    </template>
    <!-- user-provided columns end -->

  </tr>
</template>

<script>
export default {
  name: 'ElDataTableRow',
  props: {
    columns: { type: Array, required: true },
    rowData: { type: Object, required: true },
    searchQuery: { type: String, required: true },
    striped: { type: Boolean, default: false },
    selectable: { type: Boolean, default: false },
    singleSelect: { type: Boolean, default: false },
    draggable: { type: Boolean, default: false },
    actionable: { type: Boolean, default: false },
    rowClasses: { type: Function, default: () => [] },
    hasCollapsibleRows: { type: Boolean, default: false },
    hasChildRows: { type: Boolean, default: false },
    isChildRow: { type: Boolean, default: false },
    hasActionableElements: { type: Boolean, required: true },
    pinFirstColumn: { type: Boolean, default: false },
    pinnedColumnLeftOffset: { default: '0px' },
    isSummary: { type: Boolean, default: false }
  },
  methods: {
    toggleCollapsed() {
      this.$emit('toggle-collapsed-row', this.rowData);
    },
    toggleCollapseChildRows() {
      this.$emit('toggle-child-rows', this.rowData);
    },
    handleRowClick(evt) {
      this.$emit('row-clicked', evt);

      const { selectable, singleSelect, hasChildRows, hasCollapsibleRows, rowData } = this;
      if (!selectable && !singleSelect && !hasChildRows && !hasCollapsibleRows) return;
      if (evt.target.tagName.toLowerCase() === 'a') return;

      if (hasChildRows) {
        this.toggleCollapseChildRows();
      } else if (selectable || singleSelect) {
        if (selectable) this.$set(rowData, '$selected', !rowData.$selected);
        else if (singleSelect) this.$set(rowData, '$selected', rowData.$rowId);
        this.$emit('row-selected', this.rowData);
      } else if (hasCollapsibleRows) {
        this.toggleCollapsed();
      }
    }
  },
  computed: {
    classesForRow() {
      const {
        rowData, columns, rowClasses, striped, actionable, isSummary, isChildRow, hasChildRows,
        singleSelect, selectable, hasCollapsibleRows, draggable
      } = this;

      const hasLink = rowData.$link && columns.some(column => column.enableLink);
      let classes = {
        'c-data-table__summary': isSummary,
        'c-data-table__row--striped': striped,
        'c-data-table__row--selectable': actionable || singleSelect || selectable || hasCollapsibleRows || hasLink || hasChildRows,
        'c-data-table__row--child': isChildRow,
        'c-data-table__row--collapse-expanded': !rowData.$collapsed,
        'c-data-table__row--has-collapse-content': hasCollapsibleRows,
        'drag-handle__row': draggable
      };
      if (rowClasses) {
        let computedRowClasses = rowClasses(rowData);
        if (Array.isArray(computedRowClasses)) {
          computedRowClasses.forEach(className => {
            classes[className] = true;
          });
        } else if (typeof computedRowClasses === 'object') {
          classes = Object.assign(classes, computedRowClasses);
        }
      }
      return classes;
    }
  }
};
</script>
