import React, { useRef, useLayoutEffect } from 'react';
import { createControllerBox, Schema } from '@formily/react-schema-renderer';
import { IFormTextBox } from '../types';
import { toArr } from '@formily/shared';
import { FormItemProps as ItemProps } from 'antd/lib/form';
import { version } from 'antd';
import { AntdSchemaFieldAdaptor, pickFormItemProps } from '@formily/antd';
import styled from 'styled-components';

const isV4 = /^4\./.test(version);

export const FormTextBox = createControllerBox<IFormTextBox & ItemProps>(
  'text-box',
  styled(({ props, form, className, children }) => {
    const schema = new Schema(props);
    const mergeProps = schema.getExtendsComponentProps();
    const { title, label, text, gutter, style } = Object.assign(
      {
        gutter: 5,
      },
      mergeProps,
    );
    const formItemProps = pickFormItemProps(mergeProps);
    const ref: React.RefObject<HTMLDivElement> = useRef();
    const arrChildren = toArr(children);
    const split = text.split('%s');
    let index = 0;
    useLayoutEffect(() => {
      if (ref.current) {
        const elements = ref.current.querySelectorAll('.text-box-field');
        const syncLayouts = Array.prototype.map.call(
          elements,
          (el: HTMLElement) => {
            return [
              el,
              () => {
                const ctrl = el.querySelector('.ant-form-item-children');
                setTimeout(() => {
                  if (ctrl) {
                    const editable = form.getFormState(state => state.editable);
                    el.style.width = editable
                      ? ctrl.getBoundingClientRect().width + 'px'
                      : 'auto';
                  }
                });
              },
            ];
          },
        );
        syncLayouts.forEach(([el, handler]) => {
          handler();
          el.addEventListener('DOMSubtreeModified', handler);
        });

        return () => {
          syncLayouts.forEach(([el, handler]) => {
            el.removeEventListener('DOMSubtreeModified', handler);
          });
        };
      }
    }, []);
    const newChildren = split.reduce((buf, item, key) => {
      return buf.concat(
        item ? (
          <p
            key={index++}
            className="text-box-words"
            style={{
              marginRight: gutter / 2,
              marginLeft: gutter / 2,
              ...style,
            }}
          >
            {item}
          </p>
        ) : null,
        arrChildren[key] ? (
          <div key={index++} className="text-box-field">
            {arrChildren[key]}
          </div>
        ) : null,
      );
    }, []);

    const textChildren = (
      <div
        className={`${className} ${mergeProps.className}`}
        style={{
          marginRight: -gutter / 2,
          marginLeft: -gutter / 2,
        }}
        ref={ref}
      >
        {newChildren}
      </div>
    );

    if (!title && !label) return textChildren;
    return (
      <AntdSchemaFieldAdaptor {...formItemProps}>
        {textChildren}
      </AntdSchemaFieldAdaptor>
    );
  })`
    display: flex;
    .text-box-words:nth-child(1) {
      margin-left: 0;
    }
    .text-box-words {
      margin-bottom: 0 !important;
      ${isV4 ? 'line-height:32px' : ''}
    }
    .text-box-field {
      display: inline-block;
      .ant-form-item {
        margin-bottom: 0 !important;
      }
    }
    .next-form-item {
      margin-bottom: 0 !important;
    }
    .preview-text {
      text-align: center !important;
    }
  `,
);

export default FormTextBox;
