import React, { Component } from 'react'
import { Form, Button, Table, Tooltip } from 'antd'
import { AntIcon } from 'components'

const clearChildren = (data) => {
    data.forEach(p => {
        if (p.children) {
            if (p.children.length) {
                p.children = clearChildren(p.children)
            } else {
                delete p.children
            }
        }
    })
    return data
}

/**
     * 渲染查询栏
     * @returns 
     */
function renderQueryBar() {

    const { query, moreQuery, onQueryChange } = this.props

    return (
        <div className="yo-query-bar">
            <Form
                layout="inline"
                ref={this.form}
                onFinish={(value) => this.onQuery(value)}
                initialValues={this.props.queryInitialValues}
                onValuesChange={(changedValues, allValues) => onQueryChange && onQueryChange(changedValues, allValues)}
            >
                {query}
                <Form.Item>
                    <Button.Group className="mr-xs">
                        <Button htmlType="submit" type="primary" icon={<AntIcon type="search" />}>查询</Button>
                        <Tooltip placement="bottom" title="重置查询">
                            <Button onClick={() => this.onResetQuery()} icon={<AntIcon type="undo" />} />
                        </Tooltip>
                    </Button.Group>
                    {
                        moreQuery && <Button>更多查询条件</Button>
                    }
                </Form.Item>
            </Form>
        </div>
    )
}

function renderTable(props, on) {
    return <Table className="yo-table" {...props} {...on} />
}

export default class QueryTable extends Component {

    state = {
        // 加载状态
        loading: false,
        // 表格类型
        type: '',
        // 数据
        dataSource: []
    }

    // 查询表单实例
    form = React.createRef()

    // 查询值
    query = {}

    // 分页器配置
    pagination = {
        current: 1,
        pageSize: 10,
        total: 0,
        size: 'small',
        showSizeChanger: true,
        showQuickJumper: true,
        showTotal: (total) => `总共${total}条数据`,
        position: ['bottomLeft']
    }

    // 默认选中页码
    pageIndex = 1
    // 默认页面尺寸
    pageSize = 10

    // 排序字段
    sorter = {
        sortField: '',
        sortOrder: '',
    }

    constructor(props) {
        super(props)

        this.autoLoad = typeof this.props.autoLoad === 'boolean' ? this.props.autoLoad : true
        this.loadData = typeof this.props.loadData === 'function' ? this.props.loadData : async () => { }

        if (this.props.pageIndex) {
            this.pageIndex = this.props.pageIndex
            this.pagination.current = this.pageIndex
        }
        if (this.props.pageSize) {
            this.pageSize = this.props.pageSize
            this.pagination.pageSize = this.pageSize
        }
    }

    /**
     * 自动加载数据
     */
    componentDidMount() {
        if (this.autoLoad) {
            this.onLoadData()
        }
    }

    /**
     * 加载数据
     * 调用外部传入的loadData函数,可在loadData中自行改变参数
     */
    onLoadData = async () => {
        this.onLoading()

        const res = await this.loadData({
            pageIndex: this.pagination.current,
            pageSize: this.pagination.pageSize,
            ...this.sorter
        }, this.query)
        if (res.rows || res.data || res.items) {
            this.setState({
                type: 'table',
                dataSource: res.rows || res.data || res.items
            })

            this.pagination.total = res.totalCount
        } else if (res) {
            this.setState({
                type: 'tree',
                dataSource: clearChildren(res)
            })

            this.pagination = false
        }

        this.onLoaded()
    }

    /**
     * 数据开始加载
     */
    onLoading = () => {
        this.setState({
            loading: {
                indicator: <AntIcon type="loading" />
            }
        })
    }

    /**
     * 数据加载完成
     */
    onLoaded = () => {
        this.setState({ loading: false })
    }

    /**
     * 进行查询
     * 返回表单字段值,加载数据,并且返回到第一页
     * @param {*} values 
     */
    onQuery = (values) => {
        this.query = values
        this.onReloadData(true)
    }

    /**
     * 重置查询
     * 初始化表单字段值,加载数据,并返回到第一页
     */
    onResetQuery = () => {

        const { queryInitialValues, onQueryChange } = this.props

        this.form.current.resetFields()
        this.query = {
            ...queryInitialValues
        }
        const values = this.form.current.getFieldsValue()
        onQueryChange && onQueryChange(values, values)
        this.onReloadData(true)
    }

    /**
     * 重新加载表格数据
     * @param {Boolean} resetPage 是否重置页码
     */
    onReloadData = (resetPage = false) => {
        if (resetPage) {
            this.pagination = {
                ...this.pagination,
                current: this.pageIndex
            }
        }
        this.onLoadData()
    }

    /**
     * 表格分页/筛选/排序
     * @param {*} pagination 
     * @param {*} filters 
     * @param {*} sorter 
     */
    onTableChange = (pagination, filters, sorter) => {
        this.pagination = {
            ...pagination,
            showTotal: (total) => `总共${total}条数据`
        }
        this.sorter = {
            sortField: sorter.field,
            sortOrder: sorter.order,
        }
        this.onLoadData()
    }

    onAddRow = (record = {}) => {
        let { dataSource } = this.state
        if (!dataSource.find(item => !item.id)) {
            dataSource = [...dataSource, record]
            this.setState({
                dataSource
            })
            return dataSource.length - 1
        }
        return false
    }

    render() {

        const { loading, dataSource } = this.state

        const { query, operator, columns } = this.props

        const props = {
            loading,
            pagination: this.pagination,
            dataSource,
            columns: (columns || []).filter(p => !p.hidden),
            bordered: true,
            size: 'middle',
            rowKey: record => record.id || Math.random().toString(16).slice(2),
            sticky: true,
            ...this.props
        }

        const on = {
            onChange: (...args) => this.onTableChange.apply(this, args)
        }

        return (
            <section>
                {query && renderQueryBar.call(this)}
                <div className="yo-action-bar">
                    <div className="yo-action-bar--actions">
                        {operator}
                    </div>
                    <div className="yo-action-bar--actions">
                        <Button.Group>
                            <Tooltip placement="bottom" title="刷新">
                                <Button onClick={() => this.onReloadData()} type="text" icon={<AntIcon type="reload" />} />
                            </Tooltip>
                        </Button.Group>
                    </div>
                </div>
                {
                    this.props.editable ?
                        <Form ref={this.props.form}>
                            {renderTable.call(this, props, on)}
                        </Form>
                        :
                        renderTable.call(this, props, on)
                }
            </section>
        )
    }
}
