import { getFixedTotalWidthByColumnKey, clsName } from '../util/index'
import { getValByUnit } from '@P/src/utils/index.js'

import { COMPS_NAME } from '../util/constant'

export default {
  name: COMPS_NAME.FAN_TABLE_BODY_TD,
  props: {
    rowData: {
      type: Object,
      required: true,
    },
    column: {
      type: Object,
      required: true,
    },
    rowIndex: {
      type: Number,
      required: true,
    },
    colgroups: {
      type: Array,
      required: true,
    },
    rowKeyFieldName: {
      type: String,
      default: null,
    },
    // cell span option
    cellSpanOption: {
      type: Object,
      default: function () {
        return null
      },
    },
    // cell style option
    cellStyleOption: {
      type: Object,
      default: function () {
        return null
      },
    },
    // event custom option
    eventCustomOption: {
      type: Object,
      default: function () {
        return null
      },
    },
    // cell selection key data
    cellSelectionData: {
      type: Object,
      default: function () {
        return null
      },
    },
    // footer rows
    footerRows: {
      type: Array,
      default: function () {
        return []
      },
    },
    // fixed footer
    fixedFooter: {
      type: Boolean,
      default: true,
    },
  },
  computed: {
    // is last left fixed column
    isLastLeftFixedColumn() {
      let result = false

      const { colgroups, column } = this

      const { fixed } = column

      if (fixed === 'left') {
        const { field } = column
        const leftFixedColumns = colgroups.filter(
          (x) => x.fixed === 'left',
        )
        const index = leftFixedColumns.findIndex(
          (x) => x.field === field,
        )

        if (index === leftFixedColumns.length - 1) {
          result = true
        }
      }
      return result
    },
    // is first right fixed column
    isfirstRightFixedColumn() {
      let result = false

      const { colgroups, column } = this

      const { fixed } = column

      if (fixed === 'right') {
        const { field } = column
        const leftFixedColumns = colgroups.filter(
          (x) => x.fixed === 'right',
        )

        if (leftFixedColumns[0].field === field) {
          result = true
        }
      }
      return result
    },
  },
  methods: {
    /*
         * @getBodyTdClass
         * @desc  get body td class
         * @param {string} fixed - 固定方式
         */
    getBodyTdClass({ fixed }) {
      const result = {
        [clsName('footer-td')]: true,
      }

      const {
        cellStyleOption,
        rowData,
        column,
        rowIndex,
        cellSelectionData,
        rowKeyFieldName,
      } = this

      // column fixed
      if (fixed) {
        result[clsName('fixed-left')] = fixed === 'left'
        result[clsName('fixed-right')] = fixed === 'right'
        result[clsName('last-left-fixed-column')] =
                    this.isLastLeftFixedColumn
        result[clsName('first-right-fixed-column')] =
                    this.isfirstRightFixedColumn
      }

      // cell style option
      if (
        cellStyleOption &&
                typeof cellStyleOption.footerCellClass === 'function'
      ) {
        const customClass = cellStyleOption.footerCellClass({
          row: rowData,
          column,
          rowIndex,
        })
        if (customClass) {
          result[customClass] = true
        }
      }
      // cell selection option
      if (cellSelectionData) {
        const { rowKey, colKey } = cellSelectionData.currentCell
        if (
          rowData[rowKeyFieldName] === rowKey &&
                    column.key === colKey
        ) {
          result[clsName('cell-selection')] = true
        }
      }

      return result
    },

    /*
         * @getBodyTdStyle
         * @desc  get body td style
         * @param {any} key - column key
         * @param {string} align - 居中方式
         * @param {bool} fixed - 固定方式
         */
    getBodyTdStyle({ key, align, fixed }) {
      const result = {}

      const { colgroups, rowIndex, footerRows } = this

      // text align
      result['text-align'] = align || 'center'

      // fixed left total width or right total width
      if (fixed) {
        let totalWidth = 0
        // column index
        const columnIndex = colgroups.findIndex((x) => x.key === key)
        if (
          (fixed === 'left' && columnIndex > 0) ||
                    (fixed === 'right' && columnIndex < colgroups.length - 1)
        ) {
          totalWidth = getFixedTotalWidthByColumnKey({
            colgroups,
            colKey: key,
            fixed,
          })

          totalWidth = getValByUnit(totalWidth)
        }

        result.left = fixed === 'left' ? totalWidth : ''
        result.right = fixed === 'right' ? totalWidth : ''
      }

      // footer rows th fixed bottom
      if (this.fixedFooter) {
        let rowHeight = 0
        if (rowIndex !== footerRows.length - 1) {
          rowHeight = footerRows.reduce(
            (total, currentVal, index) => {
              return index > rowIndex
                ? currentVal.rowHeight + total
                : total
            },
            0,
          )
        }
        rowHeight = getValByUnit(rowHeight)

        result.bottom = rowHeight
      }

      return result
    },

    // get render content
    getRenderContent(h) {
      let content = null

      const { column, rowData, rowIndex } = this

      // has render function
      if (typeof column.renderFooterCell === 'function') {
        const renderResult = column.renderFooterCell(
          {
            row: rowData,
            column,
            rowIndex,
          },
          h,
        )

        content = renderResult
      } else {
        content = rowData[column.field]
      }
      return content
    },

    // get cell span
    getCellSpan() {
      const { cellSpanOption, rowData, column, rowIndex } = this
      let rowspan = 1
      let colspan = 1

      if (cellSpanOption) {
        const { footerCellSpan } = cellSpanOption

        if (typeof footerCellSpan === 'function') {
          const result = footerCellSpan({
            row: rowData,
            column,
            rowIndex,
          })

          if (typeof result === 'object') {
            rowspan = result.rowspan
            colspan = result.colspan
          }
        }
      }

      return { rowspan, colspan }
    },
    // cell click
    cellClick(e, fn) {
      fn && fn(e)
    },
    // dblclick
    cellDblclick(e, fn) {
      fn && fn(e)
    },
    // contextmenu
    cellContextmenu(e, fn) {
      fn && fn(e)
    },
    // mouseenter
    cellMouseenter(e, fn) {
      fn && fn(e)
    },
    // mouseleave
    cellMouseleave(e, fn) {
      fn && fn(e)
    },
    // mousemove
    cellMousemove(e, fn) {
      fn && fn(e)
    },
    // mouseover
    cellMouseover(e, fn) {
      fn && fn(e)
    },
    // mousedown
    cellMousedown(e, fn) {
      fn && fn(e)
    },
    // mouseup
    cellMouseup(e, fn) {
      fn && fn(e)
    },
  },
  render(h) {
    const { column, rowData, rowIndex, eventCustomOption } = this

    const { rowspan, colspan } = this.getCellSpan()
    if (!rowspan || !colspan) {
      return null
    }

    // custom on cell event
    let customEvents = {}
    if (eventCustomOption) {
      const { footerCellEvents } = eventCustomOption
      customEvents = footerCellEvents
        ? footerCellEvents({ row: rowData, column, rowIndex })
        : {}
    }

    const {
      click,
      dblclick,
      contextmenu,
      mouseenter,
      mouseleave,
      mousemove,
      mouseover,
      mousedown,
      mouseup,
    } = customEvents

    // td props
    const tdProps = {
      class: this.getBodyTdClass(column),
      style: this.getBodyTdStyle(column),
      rowspan,
      colspan,
      onClick: (e) => {
        this.cellClick(e, click)
      },
      onDblclick: (e) => {
        this.cellDblclick(e, dblclick)
      },
      onContextmenu: (e) => {
        this.cellContextmenu(e, contextmenu)
      },
      onMouseenter: (e) => {
        this.cellMouseenter(e, mouseenter)
      },
      onMouseleave: (e) => {
        this.cellMouseleave(e, mouseleave)
      },
      onMousemove: (e) => {
        this.cellMousemove(e, mousemove)
      },
      onMouseover: (e) => {
        this.cellMouseover(e, mouseover)
      },
      onMousedown: (e) => {
        this.cellMousedown(e, mousedown)
      },
      onMouseup: (e) => {
        this.cellMouseup(e, mouseup)
      },
    }

    return (
      <td {...tdProps}>
        {/* other cell content */}
        {this.getRenderContent(h)}
      </td>
    )
  },
}
