import { ReactVisualEditorBlock, ReactVisualEditorConfig } from './ReactVisualEditor.utils';
import React,{ useEffect, useMemo, useRef } from 'react';
import { useUpdate } from './../hook/useUpdate';
import classNames from 'classnames';
import style from './ReactVisualEditor.less';
export const ReactVisualBlock: React.FC<{
  block: ReactVisualEditorBlock;
  config: ReactVisualEditorConfig;
  onMouseDown?: (e: React.MouseEvent<HTMLDivElement>) => void;
  onContextMenu?: (e: React.MouseEvent<HTMLDivElement>) => void;
  formData?: Record<any, any>;
  onFormDataChange?: (formData: Record<string, any>) => void;
  customProps?: Record<string, Record<string, any>>;
  click:(pre:any)=>void
}> = (props) => {
  const elRef = useRef({} as HTMLDivElement);
  const { forceUpdate } = useUpdate();
  const styles = useMemo(() => {
    return {
      top: `${props.block.top}px`,
      left: `${props.block.left}px`,
      zIndex: props.block.zIndex,
      opacity: props.block.adjustPosition ? '0' : '',
    };
  }, [props.block.top, props.block.left, props.block.zIndex, props.block.adjustPosition]);

  const classes = useMemo(
    () =>
      classNames([
        style.reactVisualEditorBlock,
        props.block.focus && style.reactVisualEditorBlockFocus,
      ]),
    [props.block.focus],
  );

  let render: any;

  const component = props.config.componentMap[props.block.componentKey];
  if (!!component) {
    render = component.render({
      block: props.block,
      custom:
        !props.block.slotName || !props.customProps
          ? {}
          : props.customProps[props.block.slotName] || {},
      size:
        props.block.hasResize && component.resize
          ? (() => {
              let styles = {
                height: undefined as undefined | string,
                width: undefined as undefined | string,
              };
              !!component.resize.width && (styles.width = `${props.block.width}px`);
              !!component.resize.height && (styles.height = `${props.block.height}px`);
              return styles;
            })()
          : {},
      props: props.block.props || {},
      model: Object.entries(component.model || {}).reduce((prev, item) => {
        const [modelProp] = item;
        prev[modelProp] = {
          value:null,
          onChange: (e) => {
            if (!props.block.model || !props.block.model[modelProp]) {
              return;
            }
            let val: any;
            if (!e) {
              val = e;
            } else {
              if (typeof e === 'object' && 'target' in e) {
                val = e.target.value;
              } else {
                val = e;
              }
            }
            props.onFormDataChange &&
              props.onFormDataChange({
                ...props.formData,
                [props.block.model[modelProp]]: val,
              });
          },
        };
        return prev;
      }, {} as Record<string, { value: any; onChange: (val: any) => void }>),
    });
  }

  useEffect(() => {
    if (props.block.adjustPosition) {
      const { top, left } = props.block;
      const { height, width } = elRef.current.getBoundingClientRect();
      props.block.adjustPosition = false;
      props.block.top = top - height / 2;
      props.block.left = left - width / 2;
      props.block.width = elRef.current.offsetWidth;
      props.block.height = elRef.current.offsetHeight;
      forceUpdate();
    }
  }, []);

  return (
    <div
      className={classes}
      style={styles}
      ref={elRef}
      onMouseDown={props.onMouseDown}
      onContextMenu={props.onContextMenu}
      onClick={()=>{
        props.click(props.block.props)
      }}
    >
      {render}
      {props.children}
    </div>
  );
};
