import React, {Component} from 'react';
import PropTypes from 'prop-types';
import {Form} from 'antd';
import './style.less';

/**
 * 基于antd FormItem进行布局，label固定宽度，表单元素自适应
 * 使用了antd的两个class，会依赖FormItem的结构
 *
 * */
const FormItem = Form.Item;
export default class FormItemLayout extends Component {
    static defaultProps = {
        labelSpaceCount: 5,
        labelFontSize: 14,
        tipColor: 'rgba(0,0,0,.43)',
        labelJustify: true,
        labelHeight: 20,
        labelMarginTop: 4,
    };

    static propTypes = {
        className: PropTypes.string, // 添加在FormItem父级div上的class
        style: PropTypes.object, // 添加在FormItem 父级div上的样式
        width: PropTypes.oneOfType([ // FormItem父级div的总宽度 label + element
            PropTypes.string,
            PropTypes.number,
        ]),
        float: PropTypes.bool, // 是否是浮动，如果true，将左浮动
        labelWidth: PropTypes.number, // label宽度，如果设置此值，labelSpaceCount 和 labelFontSize将失效
        labelSpaceCount: PropTypes.number, // label所占空间个数，用于与其他label对齐
        labelFontSize: PropTypes.number, // label字体大小，最终labelWidth = labelSpaceCount * labelFontSize
        tip: PropTypes.oneOfType([ // 输入框后面的提示信息
            PropTypes.string,
            PropTypes.element,
        ]),
        tipWidth: PropTypes.number, // tip信息的宽度
        tipColor: PropTypes.string, // tip信息的颜色
        labelJustify: PropTypes.bool, // 实现label两端对齐
        labelHeight: PropTypes.number,
        labelMarginTop: PropTypes.number,
    };

    state = {};

    componentDidMount() {
        const labelWidth = this.getLabelWidth();
        const antFormItemLabel = this.formItemDom.querySelector('.ant-form-item-label');
        const antFormItemControlWrapper = this.formItemDom.querySelector('.ant-form-item-control-wrapper');
        if (antFormItemLabel) {
            antFormItemLabel.style.width = `${labelWidth}px`;
            antFormItemLabel.style.float = 'left';
        }
        if (antFormItemControlWrapper) {
            antFormItemControlWrapper.style.paddingLeft = `${labelWidth}px`;
        }
    }

    /**
     * 获取 label宽度，labelWidth属性优先
     * 如果没有设置width，最终labelWidth = labelSpaceCount * labelFontSize
     * 默认width = 5 * 12 = 60
     *
     * @returns {Number}
     */
    getLabelWidth() {
        const {labelWidth, labelSpaceCount, labelFontSize} = this.props;
        if (labelWidth !== undefined) return labelWidth;
        return (labelSpaceCount + 2) * labelFontSize;
    }

    getLabelWidthJustify = () => {
        const {labelWidth, labelSpaceCount, labelFontSize} = this.props;
        if (labelWidth !== undefined) return labelWidth;
        return (labelSpaceCount + 1) * labelFontSize;
    };

    render() {
        const {
            id,
            className,
            style,
            width,
            float,
            children,
            tip,
            tipWidth,
            tipColor,
            labelJustify,
            label = '',
            labelFontSize,
            labelHeight,
            labelMarginTop,
        } = this.props;

        const wrapperProps = {};
        if (id) wrapperProps.id = id;
        if (className) wrapperProps.className = className;
        if (style) wrapperProps.style = style;
        if (!wrapperProps.style) wrapperProps.style = {};
        if (width && !wrapperProps.style.width) wrapperProps.style.width = width;
        if (float && !wrapperProps.style.float) wrapperProps.style.float = 'left';

        const formItemProps = {...this.props};
        const ignoreProps = [
            'tip',
            'tipWidth',
            'tipColor',
            'className',
            'style',
            'width',
            'float',
            'labelWidth',
            'labelSpaceCount',
            'labelFontSize',
            'label',
            'labelHeight',
            'labelMarginTop',
        ];
        ignoreProps.forEach(item => {
            Reflect.deleteProperty(formItemProps, item);
        });

        if (tip || tipWidth) {
            wrapperProps.style.display = 'table';
            wrapperProps.style.tableLayout = 'fixed';
            if (!wrapperProps.style.width) wrapperProps.style.width = '100%';
        }

        let justifyLabel = '';
        if (labelJustify && label) {
            const labelWidth = this.getLabelWidthJustify();
            justifyLabel = (
                <p
                    className="label-in-form-item-justify"
                    style={{
                        fontSize: labelFontSize,
                        width: `${labelWidth - 14}px`,
                        height: labelHeight,
                        lineHeight: `${labelHeight}px`,
                        marginTop: labelMarginTop,
                    }}
                >
                    <span style={{fontSize: labelFontSize}}>{label}</span>
                    <span className="label-in-form-item-empty-justSpan"/>
                </p>
            );
        }

        return (
            <div {...wrapperProps} ref={node => this.formItemDom = node} className="form-item-layout-justify-label">
                <FormItem
                    label={justifyLabel || label}
                    {...formItemProps}
                    // colon={false}
                >
                    {children}
                </FormItem>
                {
                    (tip || tipWidth) ?
                        <div style={{
                            display: 'table-cell',
                            width: tipWidth,
                            paddingLeft: 8,
                            paddingTop: 8,
                            color: tipColor,
                        }}>
                            {tip}
                        </div>
                        : null
                }
            </div>
        );
    }
}
