import React from 'react';
import classnames from 'classnames';
import styles from './index.less';

interface FlexibleProps {
  className?: string;
  style?: React.CSSProperties;
  minHeight?: number;
  maxHeight?: number;
  height?: number;
}

interface FlexibleContainerProps {
  className?: string;
  style?: React.CSSProperties;
}

interface FlexibleContextData {
  flexHeight?: number;
  setFlexHeight?: (flexHeight: number) => void;
  visible?: boolean;
  setVisible?: (visible: boolean) => void;
}

export const FlexibleContext = React.createContext<FlexibleContextData>({});

export const FlexibleWrap: React.FC<FlexibleContainerProps> = props => {
  const { children, className, style } = props;
  const { visible, flexHeight } = React.useContext(FlexibleContext);
  const flexStyle = visible
    ? {
        height: `calc(100vh - 64px  - ${flexHeight}px)`,
        minHeight: `calc(100vh - 64px  - ${flexHeight}px)`,
        overflowY: 'auto',
      }
    : {};

  return (
    //@ts-ignore
    <div className={className} style={{ ...style, ...flexStyle }}>
      {children}
    </div>
  );
};

//这里先简单这么写吧，这个还不够灵活
export const FlexibleContainer: React.FC<FlexibleContainerProps> = props => {
  const { children, className, style } = props;
  const [flexHeight, setFlexHeight] = React.useState<number>();
  const [visible, setVisible] = React.useState<boolean>(false);
  return (
    <FlexibleContext.Provider
      value={{ flexHeight, setFlexHeight, visible, setVisible }}
    >
      <FlexibleWrap className={className} style={style}>
        {children}
      </FlexibleWrap>
    </FlexibleContext.Provider>
  );
};

const Flexible: React.FC<FlexibleProps> = props => {
  const {
    height = 450,
    minHeight = 130,
    maxHeight = 554,
    style,
    className,
    children,
  } = props;

  const activeRef = React.useRef<boolean>(false);
  const containerRef = React.useRef(null);

  const { setFlexHeight, setVisible } = React.useContext(FlexibleContext);
  React.useEffect(() => {
    setVisible?.(true);
    setFlexHeight?.(height);
    return () => {
      setVisible?.(false);
    };
  }, [height]);

  // const [currentHeight, setCurrentHeight] = React.useState(height);
  const handleMouseMove = (e: any) => {
    if (activeRef.current) {
      if (activeRef?.current) {
        const deltaY = e.movementY;
        // @ts-ignore
        const style: any = containerRef?.current?.style;
        let height = parseInt(style.getPropertyValue('height'), 10);
        // @ts-ignore
        let resized = Math.clamp(height - deltaY, minHeight, maxHeight);
        style.setProperty('height', `${resized}px`);
        setFlexHeight?.(resized);
      }
    }
  };

  const handleMouseUp = (e: any) => {
    activeRef.current = false;
  };

  React.useEffect(() => {
    document.addEventListener('mousemove', handleMouseMove);
    document.addEventListener('mouseup', handleMouseUp);
    return () => {
      document.removeEventListener('mousemove', handleMouseMove);
      document.removeEventListener('mouseup', handleMouseUp);
    };
  }, []);

  return (
    <div
      className={classnames(styles.flexible, className)}
      style={style}
      ref={containerRef}
    >
      <div
        className={styles.dragSpot}
        onMouseDown={async e => {
          e.persist();
          e.stopPropagation();
          activeRef.current = true;
        }}
      ></div>
      {children}
    </div>
  );
};

export default Flexible;
