import FormCore from '@wowpic/xform-core';
import { IForm, IReactFormProps } from '@wowpic/xform-types';
import { ConfigProvider, Form } from 'antd';
import zhCN from 'antd/es/locale/zh_CN';
import React, { forwardRef, ForwardRefRenderFunction, useEffect, useImperativeHandle, useState } from 'react';
import { COMPONENT_LIST } from './components';
import Switcher from './switcher';

COMPONENT_LIST.forEach(({ name, component }) =>
    FormCore.registerComponent(name, component)
);

const XForm: ForwardRefRenderFunction<unknown, IReactFormProps> = (
    { schema, ignoreValues, status, values, onChange, ...restProps },
    ref
) => {
    const [core, setCore] = useState<IForm>(null);

    useEffect(() => {
        const newCore: IForm = new FormCore({
            schema,
            ignoreValues,
            status,
            values
        });

        newCore.on('FORM_CHANGE', (event, key, field, aCore) => {
            onChange && onChange({
                event,
                key,
                field,
                aCore
            });
        });

        setCore(newCore);
    }, [schema, ignoreValues, status, onChange]);

    useEffect(() => {
        if (core && typeof status !== 'undefined') {
            core.setStatus(status);
        }
    }, [core, status]);

    useEffect(() => {
        if (core && typeof values !== 'undefined') {
            core.setValue(values);
        }
    }, [core, values]);

    useImperativeHandle(
        ref,
        () => {
            if (core) {
                return Object.getOwnPropertyNames(
                    Object.getPrototypeOf(core)
                ).reduce(
                    (prev: any, cur: string) => ({
                        ...prev,
                        [cur]: (core as any)[cur].bind(core)
                    }),
                    { core }
                );
            }
            return null;
        },
        [core]
    );

    const fields = core && core.fields ? core.fields : [];

    return (
        <ConfigProvider locale={zhCN}>
            <Form
                {...restProps}
                className={`x-form-react ${restProps.className}`}>
                <Switcher core={core} fields={fields} />
            </Form>
        </ConfigProvider>
    );
};

export default forwardRef(XForm);
