<template>
  <tr
    :class="rowClassName"
    :style="rowStyle"
    :draggable="isDraggable"
    v-on="rowEventsListeners()"
    @dragstart="dragstartHandler"
    @dragend="handleDragend"
    @dragenter="dragenterHandler"
    @mousedown="captureDragHandler"
    @dragover.prevent
    @drop="dropHandler">
    <slot> </slot>
  </tr>
</template>

<script>
import isFunction from "lodash/isFunction"
import get from "lodash/get"
import mapValues from "lodash/mapValues"
import { getClassName } from "../../utils/helper"

export default {
  props: {
    row: [Object, Array],
    rowIndex: Number,
    rowHeight: Number,
    fixed: String,
    handleDragstart: Function,
    handleDragend: Function,
    handleDragenter: Function,
    handleDrop: Function,
    sticky: Boolean,
    dragHandle: String,
    rowEvents: Object,
  },
  inject: {
    rootTable: {
      from: "mm-table",
      default: null,
    },
  },
  data() {
    return {
      isDraggable: false,
    }
  },
  computed: {
    draggable() {
      return this.rootTable.draggable
    },
    state() {
      return this.rootTable.store.state
    },
    layout() {
      return this.rootTable.store.layout
    },
    rowStyle() {
      if (this.sticky) {
        return {
          height: this.rowHeight ? `${this.rowHeight}px` : "",
        }
      }
      return {
        height: this.fixed
          ? `${this.layout.rowHeightList[this.rowIndex]}px`
          : "",
      }
    },
    rowCustomClass() {
      const row = this.row
      const rowIndex = this.rowIndex
      const rowKey = this.rootTable.rowKey
      const rowClass = this.rootTable.rowClass

      return isFunction(rowClass)
        ? rowClass({ row, rowIndex, rowKey })
        : rowClass
    },
    rowClassName() {
      const row = this.row
      const rowIndex = this.rowIndex
      const rowKey = this.state.rowKey
      const layout = this.layout

      return [
        {
          "mm-tbody-tr": true,
          "mm-tbody-tr--selected": this.state.selectedRows.includes(
            rowKey ? get(row, rowKey) : row
          ),
          "mm-tbody-tr--dragover-up":
            rowIndex === layout.dragoverRowIndex && !layout.dragDirection,
          "mm-tbody-tr--dragover-down":
            rowIndex === layout.dragoverRowIndex && layout.dragDirection,
        },
        this.rowCustomClass,
      ]
    },
  },
  methods: {
    rowEventsListeners() {
      return mapValues(this.rowEvents, (item) => {
        return (e) => item(e, this.row, this.rowIndex)
      })
    },
    getTargetClassName(el) {
      let className = getClassName(el)
      let isDragHandle = className.indexOf(this.dragHandle) !== -1
      while (el.parentNode && !isDragHandle) {
        className = getClassName(el.parentNode) || ""
        el = el.parentNode
        isDragHandle = className.indexOf(this.dragHandle) !== -1
      }
      return isDragHandle
    },
    captureDragHandler(e) {
      if (!this.draggable) {
        this.isDraggable = false
        return
      }

      if (this.dragHandle && !this.getTargetClassName(e.target)) {
        this.isDraggable = false
        return
      }

      this.isDraggable = true
    },
    dragstartHandler() {
      if (this.isDraggable) {
        this.handleDragstart(this.row)
      }
    },
    dragenterHandler() {
      this.handleDragenter(this.row, this.rowIndex)
    },
    dropHandler() {
      this.handleDrop(this.row)
    },
    inputHandler(val) {
      this.state.selectedRows = val
    },
  },
}
</script>
