import React, { useState } from 'react';
import { observer } from 'mobx-react';
import { CSSProperties, css } from 'glamor';
import { useApphouse } from '../../context/useApphouse';
import { ApphouseComponent } from '../../components/component.interfaces';
import { useLocalStyles } from '../../styles/defaults/useLocalStyles';
import { toRems } from '../../utils/units/toRems';
import { setAlpha } from '../../utils/color/setAlpha';

export interface FullPageSplitViewStyles {
  container?: CSSProperties;
  bar?: CSSProperties;
  panel?: CSSProperties;
}

export interface FullPageSplitViewProps
  extends ApphouseComponent<FullPageSplitViewStyles> {
  /**
   * If true, the views will be split vertically.
   * @optional
   * @default false it will be split horizontally
   */
  vertical?: boolean;
  /**
   * The number of columns.
   * @optional
   * @default 2 // we only support 2 columns for now
   */
  columns?: 2;
  /**
   * The width of the bar.
   * @optional
   * @default 1
   */
  barWidth?: number;
  /**
   * The views in the split view.
   * Max 2 views. (children)
   */
  children: React.ReactNode[];
}

/**
 * A full page split view.
 * The component splits the page into two equal views.
 * The user can drag the bar to resize the views.
 */
export const FullPageSplitView: React.FC<FullPageSplitViewProps> = observer(
  (props) => {
    const {
      styleOverwrites,
      gutters,
      vertical,
      children,
      barWidth = 1
    } = props;
    const [dragging, setDragging] = useState(false);
    const [position, setPosition] = useState(50);
    const views = React.Children.toArray(children);
    if (views.length < 2) {
      throw new Error(
        'SplitView must have at least two View components as children'
      );
    }
    const { theme } = useApphouse();
    const { onBackground } = theme.colors;
    const barColor = setAlpha(onBackground, 0.1);
    const barHoverColor = setAlpha(onBackground, 0.2);
    const handleMouseDown = () => {
      setDragging(true);
    };

    const handleMouseUp = () => {
      setDragging(false);
    };

    const handleMouseMove = (e: { clientY: number; clientX: number }) => {
      if (!dragging) {
        return;
      }
      if (vertical) {
        const newPosition = (e.clientY / window.innerHeight) * 100;
        setPosition(newPosition);
        return;
      }
      const newPosition = (e.clientX / window.innerWidth) * 100;
      setPosition(newPosition);
    };

    const barStyles = {
      zIndex: 1,
      backgroundColor: barColor,
      transition: 'all 0.2s ease-in-out',
      ':hover': {
        backgroundColor: barHoverColor
      }
    };

    const horizontalBar = {
      cursor: 'col-resize',
      height: '100%',
      width: toRems(barWidth),
      ...barStyles
    };

    const verticalBar = {
      cursor: 'row-resize',
      width: '100%',
      height: toRems(barWidth),
      ...barStyles
    };

    const componentStyles: FullPageSplitViewStyles = {
      container: {
        display: 'flex',
        flexDirection: vertical ? 'column' : 'row',
        height: '100vh'
      },
      bar: vertical ? verticalBar : horizontalBar,
      panel: {
        overflow: 'auto'
      }
    };
    const localStyles = useLocalStyles<FullPageSplitViewStyles>(
      componentStyles,
      styleOverwrites,
      gutters
    );
    return (
      <div
        {...css(localStyles.container)}
        onMouseMove={handleMouseMove}
        onMouseUp={handleMouseUp}
        data-xray="FullPageSplitView"
        data-style="FullPageSplitViewStyles.container"
      >
        <div
          {...css(
            vertical ? { height: `${position}%` } : { width: `${position}%` },
            { zIndex: 1 },
            localStyles.panel
          )}
          data-style="FullPageSplitViewStyles.panel"
        >
          {views[0]}
        </div>
        <div
          {...css(localStyles.bar)}
          onMouseDown={handleMouseDown}
          data-style="FullPageSplitViewStyles.bar"
        ></div>
        <div
          {...css(
            vertical
              ? { height: `${100 - position}%` }
              : { width: `${100 - position}%` },
            localStyles.panel
          )}
          data-style="FullPageSplitViewStyles.panel"
        >
          {views[1]}
        </div>
      </div>
    );
  }
);
