import React from 'react';
import { config } from './config';
import { getDetail } from './detail';
import { emptyModel } from './_utils/setFormatter';
import { transferAttr } from './_utils/transferAttr';
import { BaseComponentProps, BaseComponentState } from '../interface';

// 此方法为高阶组件,不应再render里面频繁调用,防止频繁实例化,带来性能上的浪费
/*
 *@params(type)  string    组件type
 *@return component
 */
export const getComponent = (type: string) => {
    const NodeObj = config[type] || {};
    const Node = NodeObj.component || null;
    if (!Node) {
        console.error(type + '组件未定义');
        return;
    }
    const setFormat = (columnConfig: any, value: any[]) => {
        const { columnAttrObj, columnType } = columnConfig || {};
        const transferColumn = transferAttr(columnType, {
            ...(NodeObj.componentAttr || {}),
            ...(columnAttrObj || {}),
        });
        if (NodeObj.setFormatter) return NodeObj.setFormatter(value, transferColumn);
        return value;
    };

    const getFormat = (columnConfig: any, value: any) => {
        const { columnAttrObj, columnType } = columnConfig || {};
        if (!value || !Array.isArray(value) || value.length <= 0) return undefined;
        const transferColumn = transferAttr(columnType, {
            ...(NodeObj.componentAttr || {}),
            ...(columnAttrObj || {}),
        });
        if (NodeObj.getFormatter) {
            return NodeObj.getFormatter(value, transferColumn);
        }
        return value;
    };
    const com: any = class Base extends React.Component<BaseComponentProps, BaseComponentState> {
        static getDerivedStateFromProps(nextProps: BaseComponentProps, prevState: BaseComponentState) {
            const { columnConfig } = prevState;

            let nextState: BaseComponentState = {
                ...prevState,
            };
            if (JSON.stringify(columnConfig) !== JSON.stringify(nextProps.columnConfig)) {
                nextState.columnConfig = nextProps.columnConfig;
            }
            return nextState;
        }
        constructor(props: BaseComponentProps) {
            super(props);
            const { columnConfig } = props;
            this.state = {
                columnConfig,
            };
        }

        onChange = (changedValue: any) => {
            const { columnConfig } = this.state;
            const { onChange } = this.props;
            let value = setFormat(columnConfig, changedValue);
            if (typeof onChange === 'function') {
                onChange(value);
            }
        };
        // 触发修改回调
        onEmitChange = (changedValue: any,option:any) => {
            const { columnConfig } = this.state;
            const { onEmitChange } = this.props;
            let value = setFormat(columnConfig, changedValue);
            if (typeof onEmitChange === 'function') {
                onEmitChange(value,option);
            }
        };

        render() {
            const { value, ...others } = this.props;
            const { columnConfig } = this.state;
            const { columnAttrObj, columnType } = columnConfig || {};
            let transferColumn = transferAttr(columnType, {
                ...(NodeObj.componentAttr || {}),
                ...(columnAttrObj || {}),
            });
            const newProps = {
                ...others,
                ...(transferColumn || {}),
            };
            return (
                <Node
                    {...newProps}
                    value={getFormat(columnConfig, value)}
                    onChange={this.onChange}
                    onEmitChange={this.onEmitChange}
                />
            );
        }
    };
    com.Detail = getDetail(type);
    return com;
};
