import { css, CSSProperties } from 'glamor';
import { observer } from 'mobx-react';
import { FiMoreHorizontal } from 'react-icons/fi';
import React, { useEffect, useState } from 'react';
import { Button } from '../../components/Button';
import { useApphouse } from '../../context/useApphouse';
import { useLocalStyles } from '../../styles/defaults/useLocalStyles';
import { ApphouseComponent } from '../component.interfaces';

const InvisibleBackgroundStyle = {
  position: 'fixed',
  top: 0,
  left: 0,
  width: 90000,
  height: 90000
  // backgroundColor: 'green'
};

export interface PortalStyles {
  /**
   * The style applied to the container of the portal
   */
  container?: CSSProperties;
  /**
   * The style applied to the trigger button for the component
   */
  button?: CSSProperties;
  /**
   * The style for the invisible overlay that is rendered behind the portal
   * when the panel is open, clicking on this overlay will close the panel
   */
  overlay?: CSSProperties;
  /**
   * The style applied to contentWrapper
   */
  contentWrapper?: CSSProperties;
}

export interface PortalProps extends ApphouseComponent<PortalStyles> {
  id: string;
  children?: React.ReactNode;
  toggle?: React.ReactNode;
  onToggle?: (isShowing: boolean) => void;
}
export const Portal: React.FC<PortalProps> = observer(
  ({ children, id, toggle, onToggle, styleOverwrites, gutters }) => {
    const childrenRef = React.useRef<HTMLDivElement>(null);
    const { app } = useApphouse();
    const [x, setX] = useState<undefined | number>(undefined);
    const [y, setY] = useState<undefined | number>(undefined);
    const [positioned, setPositioned] = useState<boolean>(false);
    const [show, setShow] = useState(false);

    const open = (e: React.MouseEvent<HTMLButtonElement>) => {
      setY(e.pageY);
      setX(e.pageX);
      setShow(true);
    };

    const onClick = (e: React.MouseEvent<HTMLButtonElement>) => {
      // e?.stopPropagation();
      // e?.preventDefault();
      onToggle && onToggle(show);
      open(e);
    };

    const showOutsideClickDetectionArea = show;
    const componentStyles: PortalStyles = {
      button: { backgroundColor: 'inherit', border: 'none' },
      container: { position: 'relative' },
      contentWrapper: { position: 'fixed', top: y, left: x, zIndex: 2 },
      overlay: InvisibleBackgroundStyle
    };
    const localStyles = useLocalStyles(
      componentStyles,
      styleOverwrites,
      gutters
    );
    useEffect(() => {
      const height = childrenRef.current?.getBoundingClientRect().height;
      const width = childrenRef.current?.getBoundingClientRect().width;
      if (height && window?.innerHeight - (y || 0) < height) {
        // padding is for some room in the bottom
        const PADDING = 20;
        setY(window.innerHeight - height - PADDING);
      }
      if (width && window?.innerWidth - (x || 0) < width) {
        // padding is for some room in the right
        const PADDING = 20;
        setX(window.innerWidth - width - PADDING);
      }
      if (!positioned) {
        setPositioned(true);
      }
    }, [y, x, show, positioned]);

    return (
      <div data-id={id} id={id} {...css(localStyles.container)}>
        {showOutsideClickDetectionArea && (
          <div
            {...css(localStyles.overlay)}
            data-id="invisible-background"
            onClick={() => {
              app.view.setView(id, false);
              setY(undefined);
              setX(undefined);
              setShow(false);
              setPositioned(false);
            }}
          />
        )}

        <Button
          variant="clear"
          styleOverwrites={localStyles?.button}
          onClick={onClick}
        >
          {!toggle && (
            <span {...css({ color: 'inherit' })}>
              <FiMoreHorizontal size={20} />
            </span>
          )}
          {toggle && toggle}
        </Button>

        {show && (
          <div
            ref={childrenRef}
            {...css(localStyles.contentWrapper, {
              position: 'fixed',
              // top: y,
              // left: x
              top: 0,
              left: 0
            })}
          >
            {children}
          </div>
        )}
      </div>
    );
  }
);
