import React, { Component } from 'react'
import { Form, Spin } from 'antd'
import { AntIcon } from 'components'
import { cloneDeep, isEqual } from 'lodash'

const initialValues = {}

const layout = {
    labelCol: { flex: '150px' },
    wrapperCol: { flex: '1' },
}

export default class part extends Component {
    state = {
        loading: true,
        codes: {},
        options: {},
    }

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

    // 初始化数据
    record = {}

    /**
     * 阻止外部组件引发的渲染,提升性能
     * 可自行添加渲染条件
     * [必要]
     * @param {*} props
     * @param {*} state
     * @returns
     */
    shouldComponentUpdate(props, state) {
        return !isEqual(this.state, state)
    }

    /**
     * DOM加载完成钩子,在此将自身传递给父级,并且绑定数据
     */
    componentDidMount() {
        if (this.props.onRef) {
            this.props.onRef(this)
        }
        this.fillData({
            record: this.props.record,
        })
    }

    /**
     * 填充数据
     * 可以在设置this.record之后对其作出数据结构调整
     * [异步,必要]
     * @param {*} params
     */
    async fillData(params) {
        this.record = cloneDeep(params.record)
        //#region 从后端转换成前段所需格式
        //#endregion
        this.form.current.setFieldsValue(this.record)

        this.setState({
            loading: false,
        })
    }

    /**
     * 获取数据
     * 可以对postData进行数据结构调整
     * [异步,必要]
     * @returns
     */
    async getData() {
        const form = this.form.current

        const valid = await form.validateFields()
        if (valid) {
            const postData = form.getFieldsValue()
            //#region 从前段转换后端所需格式
            //#endregion
            return postData
        }
    }

    //#region 自定义方法
    /**
     * 表单change事件处理,包括了所有字段的change
     * [异步,非必要]
     * @param {*} changedValues
     * @param {*} allValues
     */
    async onValuesChange(changedValues, allValues) {}
    //#endregion

    render() {
        const { loading } = this.state

        return (
            <Spin spinning={loading} indicator={<AntIcon type="loading" />}>
                <Form
                    initialValues={initialValues}
                    ref={this.form}
                    {...layout}
                    onValuesChange={(changedValues, allValues) =>
                        this.onValuesChange(changedValues, allValues)
                    }
                ></Form>
            </Spin>
        )
    }
}
