import { useEffect } from 'react';
import { get, omit } from 'lodash';
import { ComponentPlugin, COMPONENT_EVENT } from '../../models/component';
import { useForceUpdate } from '../hooks';
import { ConfigPanelGeneratorProps } from './types';

export default function ConfigPanelGenerator(props: ConfigPanelGeneratorProps) {
  const {
    component,
    component: {
      config: { config },
      componentPlugin: { configPanelSchema },
    },
  } = props;

  const forceUpdate = useForceUpdate();

  useEffect(() => {
    component.on(COMPONENT_EVENT.UpdateConfigPanel, forceUpdate);

    return () => {
      component.off(COMPONENT_EVENT.UpdateConfigPanel);
    };
  }, [component]);

  const handleChange = (value: any, property: string) => {
    component.updateConfigPanelProperty(property, value);
  };

  const generateConfigPanel = (
    schema: ComponentPlugin['configPanelSchema'],
    parentPath?: string,
    childComponents: JSX.Element[][] = []
  ) => {
    return schema.map((item, i) => {
      const { type, property, initialValue, children } = item;
      const path = parentPath ? `${parentPath}.${property}` : `${property}`;
      const { Component } = component.getConfigPanelPlugin(type);
      const value = get(config, path);

      if (!children)
        return (
          <Component
            key={i}
            {...omit(item, 'initialValue')}
            value={value === 0 ? value : value || initialValue}
            onChange={(value: any) => handleChange(value, path)}
          />
        );

      childComponents.push(generateConfigPanel(children, path, []));
      return (
        <Component
          key={i}
          {...omit(item, 'initialValue')}
          value={value || initialValue}
          childComponents={childComponents}
          onChange={(value: any) => handleChange(value, path)}
        />
      );
    });
  };

  return <>{generateConfigPanel(configPanelSchema)}</>;
}
