<script>
import TableColumn from './table-column';
import TableHeader from './table-header';
import TableBody from './table-body';
import { prefix, prefixMixins, guid } from 'jdd-design/utils';
import Event from 'jdd-design/utils/event';
// import Checkbox from '../checkbox';
// const TableColumnConstructor = Vue.extend(TableColumn);
export default {
    name: `${prefix}-table`,
    mixins: [prefixMixins],
    components: { TableColumn, TableBody },
    props: {
        dataList: Array,
        size: {
            type: String,
            default: 'medium'
        },
        border: Boolean,
        loading: Boolean,
        height: Number,
        valign: {
            type: String,
            default: 'middle'
        },
        fixed: {
            type: String
        },
        rowKey: String
    },
    computed: {
        tableClass() {
            let clsNames = [`${prefix}-table`, `${prefix}-table--${this.size}`];
            this.border && clsNames.push('is-border');
            return clsNames;
        },
        tableBodyClass() {
            let clsNames = [`${prefix}-table__inner`];
            return clsNames;
        }
    },
    data() {
        return {
            columns: [],
            minColumnWidth: 80,
            realWidth: 0,
            bus: new Event(),
            barSpace: { width: 0, height: 0 },
            leftWidth: 0,
            rightWidth: 0,
            scrollClass: 'scroll-left',
            shouldScroll: false,
            selection: []
        };
    },
    provide() {
        return {
            jddTable: this
        };
    },
    methods: {
        addColumn(column) {
            this.$set(this.columns, this.columns.length, column);
        },
        removeColumn(column) {
            this.columns.splice(this.columns.indexOf(column), 1);
        },
        setSpace(space) {
            this.barSpace = { ...space };
        },
        handleScroll(type) {
            this.scrollClass = `scroll-${type}`;
        },
        selectChange() {
            this.selection = this.dataList
                .filter(m => m.$$checked)
                .map(m => m[this.rowKey]);
            this.$emit('selected-change', this.selection);
        }
    },
    render(h) {
        let loading = this.$slots.loading
            ? this.$slots.loading
            : '加载中。。。';
        let opts = { ...this.$props, columns: this.columns };
        let optsAll = { ...opts, emptySlot: this.$slots.empty };
        let height;
        if (optsAll.height) {
            height = optsAll.height - this.barSpace.height;
        }
        return (
            <div class={this.tableClass}>
                <div class="hidden-columns" ref="hiddenColumns">
                    {this.$slots.default}
                </div>
                {this.loading ? (
                    <div class={`${prefix}-table__loading`}>{loading}</div>
                ) : null}
                {this.barSpace.width ? (
                    <div
                        class="before"
                        style={{ width: `${this.barSpace.width}px` }}
                    />
                ) : null}
                <TableHeader
                    columns={this.columns}
                    width={this.realWidth}
                    bus={this.bus}
                />
                <TableBody
                    {...{ props: optsAll }}
                    onScroll={this.handleScroll}
                    width={this.realWidth}
                    loading={this.loading}
                    bus={this.bus}
                />
                {this.shouldScroll && this.leftWidth ? (
                    <div
                        class={[
                            `${prefix}-table__fixed--left`,
                            this.scrollClass
                        ]}
                        style={{ width: `${this.leftWidth}px` }}
                    >
                        <TableHeader
                            columns={this.columns}
                            width={this.realWidth}
                            fixed="left"
                        />
                        <TableBody
                            {...{
                                props: { ...optsAll, height, fixed: 'left' }
                            }}
                            width={this.realWidth}
                            bus={this.bus}
                        />
                    </div>
                ) : null}
                {this.shouldScroll && this.rightWidth ? (
                    <div
                        class={[
                            `${prefix}-table__fixed--right`,
                            this.scrollClass
                        ]}
                        style={{
                            width: `${this.rightWidth - this.barSpace.width}px`,
                            right: `${this.barSpace.width}px`
                        }}
                    >
                        <TableHeader
                            columns={this.columns}
                            width={this.realWidth}
                            fixed="right"
                        />
                        <TableBody
                            {...{
                                props: { ...optsAll, height, fixed: 'right' }
                            }}
                            width={this.realWidth}
                            bus={this.bus}
                        />
                    </div>
                ) : null}
            </div>
        );
    },
    mounted() {
        this.$refs.hiddenColumns.parentNode.removeChild(
            this.$refs.hiddenColumns
        );
        this.$nextTick(() => {
            this.realWidth = this.$el.clientWidth;
            let realWidth = 0;
            let noWidthColumns = [];
            let tmpClumns = [],
                leftColumns = [],
                rightColumns = [],
                rightFlag = false;
            this.columns.forEach(m => {
                if (m.columnWidth) {
                    realWidth += m.columnWidth;
                } else {
                    noWidthColumns.push(m);
                }
                tmpClumns.push(m);
                if (m.fixed === true || m.fixed === 'left') {
                    leftColumns = [...tmpClumns];
                }
                if (m.fixed === 'right' || rightFlag) {
                    rightFlag = true;
                    rightColumns.push(m);
                }
            });

            if (
                this.$el.clientWidth >
                realWidth + noWidthColumns.length * this.minColumnWidth
            ) {
                let leftWidth = this.$el.clientWidth - realWidth;
                let avgWidth = Math.round(leftWidth / noWidthColumns.length);
                noWidthColumns.forEach((m, n) => {
                    if (n === noWidthColumns.length - 1) {
                        m.columnWidth = leftWidth;
                    } else {
                        m.columnWidth = avgWidth;
                        leftWidth -= avgWidth;
                    }
                });
            } else {
                this.shouldScroll = true;
                noWidthColumns.forEach(m => {
                    m.columnWidth = this.minColumnWidth;
                });
                this.realWidth =
                    realWidth + noWidthColumns.length * this.minColumnWidth;
            }

            this.leftWidth = leftColumns.reduce((p, c) => {
                return p + c.columnWidth;
            }, 0);
            this.rightWidth = rightColumns.reduce((p, c) => {
                return p + c.columnWidth;
            }, 0);
        });
        this.bus.on('bar-space', this.setSpace);
    }
};
</script>
