<template>
    <table cellspacing="0" cellpadding="0" border="0" :style="styles">
        <colgroup>
            <col 
                v-for="(column, index) in columns" 
                :key="index"
                :width="setCellWidth(column)" />
            <col v-if="$parent.showVerticalScrollBar" :width="$parent.scrollBarWidth"/>
        </colgroup>
        <thead>
            <tr 
                v-for="(cols, rowIndex) in headRows"
                :key="rowIndex">
                <th
                    v-for="(column, index) in cols"
                    :key="index" 
                    :colspan="column.colSpan"
                    :rowspan="column.rowSpan"
                    :class="alignCls(column)"
                    @mousemove="handleMouseMove($event, column)"
                    @mouseout="handleMouseOut($event, column)"
                    @mousedown="handleMouseDown($event, column, index, cols[index + 1])">
                    <div :class="cellClasses(column)" :style="{'text-align': column.headerAlign ? column.headerAlign : 'center'}">
                        <template v-if="column.type === 'expand'">
                            <span v-if="!column.renderHeader">{{ column.title || '' }}</span>
                            <RenderHeader 
                                v-else 
                                :render="column.renderHeader" 
                                :column="column" :index="index" />
                        </template>
                        <template v-else-if="column.type === 'selection'">
                            <Checkbox :value="isSelectAll" :disabled="!data.length" @on-change="selectAll" />
                        </template>
                        <template v-else>
                            <span 
                                v-if="!column.renderHeader" 
                                :class="{[prefixCls + '-cell-sort']: column.sortable}" 
                                @click="handleSortByHead(getColumn(rowIndex, index)._index)">
                                {{ column.title || '#' }}
                            </span>
                            <RenderHeader 
                                v-else 
                                :render="column.renderHeader" 
                                :column="column" 
                                :index="index" />
                            <span 
                                v-if="column.sortable"
                                :class="[prefixCls + '-sort']">
                                <Icon type="sort-asc" 
                                    :class="{on: getColumn(rowIndex, index)._sortType === 'asc'}" 
                                    @click.native="handleSort(getColumn(rowIndex, index)._index, 'asc')"></Icon>
                                <Icon type="sort-desc"
                                     :class="{on: getColumn(rowIndex, index)._sortType === 'desc'}" 
                                     @click.native="handleSort(getColumn(rowIndex, index)._index, 'desc')"></Icon>
                            </span>
                            <Tip 
                                trigger="click" 
                                transfer
                                theme="light"
                                placement="bottom"
                                v-if="isPopperShow(column)"
                                v-model="getColumn(rowIndex, index)._filterVisible">
                                <span :class="[prefixCls + '-filter']">
                                    <Icon :type="getColumn(rowIndex, index)._isFiltered || getColumn(rowIndex, index)._filterVisible ? 'filter-fill' : 'filter'"></Icon>
                                </span>
                                <div 
                                    :class="[prefixCls + '-filter-popper']" 
                                    slot="content">
                                    <RenderHeader 
                                        :render="column.filter" 
                                        :column="column" 
                                        :index="index" />
                                    <div :class="[prefixCls + '-filter-popper-foot']">
                                        <Button
                                            style="margin-right: 4px"
                                            size="small" 
                                            type="default" 
                                            @click="handleFilterReset(getColumn(rowIndex, index)._index)">
                                            {{t('cancel')}}
                                        </Button>
                                        <Button 
                                            size="small" 
                                            type="primary" 
                                            @click="handleFilterSubmit(getColumn(rowIndex, index)._index)">
                                            {{t('ok')}}
                                        </Button>
                                    </div>
                                </div>
                            </Tip>
                        </template>
                    </div>
                </th>
                <th 
                    v-if="$parent.showVerticalScrollBar && rowIndex===0" 
                    :class='scrollBarCellClass()' 
                    :rowspan="headRows.length">
                </th>
            </tr>
        </thead>
    </table>
</template>
<script>
    import { hasClass, addClass, removeClass } from '../../../utils/assist'
    import CheckboxGroup from '../checkbox/checkbox-group'
    import Checkbox from '../checkbox/checkbox'
    import Icon from '../icon/icon'
    import Dropdown from '../select/dropdown'
    import Button from '../button/button'
    import RenderHeader from './header'
    import Mixin from './mixin'
    import Locale from '../../../mixins/locale'
    import Tip from '../tip/'
    import ClickOutside from '../../../directives/clickoutside'

    export default {
        name: 'YYTableHead',
        mixins: [Mixin, Locale],
        components: {
            CheckboxGroup,
            Checkbox,
            Icon,
            Button,
            Dropdown,
            RenderHeader,
            Tip
        },
        directives: {
            ClickOutside
        },
        props: {
            prefixCls: String,
            styleObject: Object,
            columns: Array,
            objData: Object,
            data: Array,
            columnsWidth: Object,
            fixed: {
                type: [Boolean, String],
                default: false
            },
            columnRows: Array,
            fixedColumnRows: Array,
            border: Boolean
        },
        data() {
            return {
                dragState: null,
                draggingColumn: null,
                dragging: false
            }
        },
        computed: {
            styles() {
                const style = Object.assign({}, this.styleObject)
                const width = parseInt(this.styleObject.width)
                style.width = `${width}px`
                return style
            },
            isSelectAll() {
                let isSelectAll = true
                if (!this.data.length) isSelectAll = false
                if (!this.data.find(item => !item._disabled)) isSelectAll = false
                for (let i = 0; i < this.data.length; i++) {
                    if (!this.objData[this.data[i]._index]._isChecked && !this.objData[this.data[i]._index]._isDisabled) {
                        isSelectAll = false
                        break
                    }
                }

                return isSelectAll
            },
            headRows() {
                const isGroup = this.columnRows.length > 1
                if (isGroup) {
                    return this.fixed ? this.fixedColumnRows : this.columnRows
                } else {
                    return [this.columns]
                }
            }
        },
        methods: {
            cellClasses(column) {
                return [
                    `${this.prefixCls}-cell`,
                    {
                        [`${this.prefixCls}-hidden`]: !this.fixed && column.fixed && (column.fixed === 'left' || column.fixed === 'right'),
                        [`${this.prefixCls}-cell-with-selection`]: column.type === 'selection'
                    }
                ]
            },
            scrollBarCellClass() {
                let hasRightFixed = false
                for (let i in this.headRows) {
                    for (let j in this.headRows[i]) {
                        if (this.headRows[i][j].fixed === 'right') {
                            hasRightFixed = true
                            break
                        }
                        if (hasRightFixed) break
                    }
                }
                return [{
                    [`${this.prefixCls}-hidden`]: hasRightFixed
                }]
            },
            handleMouseDown(event, column, index, nextColumn) {
                if (column.children && column.children.length > 0) return
                if (!(this.border && this.draggingColumn)) return

                this.dragging = true
                this.$parent.resizeProxyVisible = true

                const table = this.$parent

                const tableEl = table.$el
                const tableLeft = tableEl.getBoundingClientRect().left
                const columnEl = this.$el.querySelectorAll(`th`)[index]
                const columnRect = columnEl.getBoundingClientRect()
                const minLeft = columnRect.left - tableLeft + 30

                addClass(columnEl, 'noclick')

                this.dragState = {
                    startMouseLeft: event.clientX,
                    startLeft: columnRect.right - tableLeft,
                    startColumnLeft: columnRect.left - tableLeft,
                    tableLeft
                }

                const resizeProxy = table.$refs.resizeProxy
                resizeProxy.style.left = this.dragState.startLeft + 'px'

                document.onselectstart = function () {
                    return false
                }
                document.ondragstart = function () {
                    return false
                }

                const handleMouseMove = (event) => {
                    const deltaLeft = event.clientX - this.dragState.startMouseLeft
                    const proxyLeft = this.dragState.startLeft + deltaLeft

                    resizeProxy.style.left = Math.max(minLeft, proxyLeft) + 'px'
                }

                const handleMouseUp = () => {
                    if (this.dragging) {
                        const {
                            startColumnLeft,
                            startLeft
                        } = this.dragState
                        const finalLeft = parseInt(resizeProxy.style.left, 10)
                        const columnWidth = finalLeft - startColumnLeft
                        const currentColumnWidth = column._width - columnWidth

                        document.body.style.cursor = ''
                        this.dragging = false
                        this.draggingColumn = null
                        this.dragState = {}

                        table.resizeProxyVisible = false
                        table.hasResizeProxy = true

                        if ((nextColumn._width + currentColumnWidth) < 60 || columnWidth < 60) {
                            return
                        }
                        column.width = column._width = columnWidth
                        nextColumn.width = nextColumn._width += currentColumnWidth
                    }

                    document.removeEventListener('mousemove', handleMouseMove)
                    document.removeEventListener('mouseup', handleMouseUp)
                    document.onselectstart = null
                    document.ondragstart = null

                    setTimeout(function () {
                        removeClass(columnEl, 'noclick')
                    }, 0)
                }

                document.addEventListener('mousemove', handleMouseMove)
                document.addEventListener('mouseup', handleMouseUp)

            },
            handleMouseMove(event, column) {
                if (column.children && column.children.length > 0) return
                let target = event.target
                while (target && target.tagName !== 'TH') {
                    target = target.parentNode
                }
                if (!column || !column.resizable) return

                if (!this.dragging && this.border) {
                    let rect = target.getBoundingClientRect()

                    const bodyStyle = document.body.style
                    if (rect.width > 12 && rect.right - event.pageX < 8) {
                        bodyStyle.cursor = 'col-resize'
                        if (hasClass(target, 'is-sortable')) {
                            target.style.cursor = 'col-resize'
                        }
                        this.draggingColumn = column
                    } else if (!this.dragging) {
                        bodyStyle.cursor = ''
                        if (hasClass(target, 'is-sortable')) {
                            target.style.cursor = 'pointer'
                        }
                        this.draggingColumn = null
                    }
                }
            },
            handleMouseOut() {
                document.body.style.cursor = ''
            },
            selectAll() {
                const status = !this.isSelectAll
                this.$parent.selectAll(status)
            },
            handleSort(index, type) {
                const column = this.columns[index]
                const _index = column._index

                if (column._sortType === type) {
                    type = 'normal'
                }
                this.$parent.handleSort(_index, type)
            },
            handleSortByHead(index) {
                const column = this.columns[index]
                if (column.sortable) {
                    const type = column._sortType
                    if (type === 'normal') {
                        this.handleSort(index, 'asc')
                    } else if (type === 'asc') {
                        this.handleSort(index, 'desc')
                    } else {
                        this.handleSort(index, 'normal')
                    }
                }
            },
            handleFilter(column) {
                if(column._filterVisible) {
                    this.$parent.handleFilterHide(column._index)
                } else {
                    this.$parent.handleFilterShow(column._index)
                }
            },
            handleFilterHide(index) {
                // this.$parent.handleFilterHide(index)
            },
            handleFilterReset(index) {
                this.$parent.handleFilterReset(index)
            },
            handleFilterSubmit(index) {
                this.$parent.handleFilterSubmit(index)
            },
            getColumn(rowIndex, index) {
                const isGroup = this.columnRows.length > 1

                if (isGroup) {
                    const id = this.headRows[rowIndex][index].__id
                    return this.columns.filter(item => item.__id === id)[0]
                } else {
                    return this.headRows[rowIndex][index]
                }
            }
        }
    }
</script>
