import { observer } from 'mobx-react';
import React from 'react';
import { omit } from '../../utils/obj/omit';
import { PopupProps } from './Popup.interface';
import { PopupFooter } from './PopupFooter';
import { PopupHeader } from './PopupHeader';
import { PopupBody } from './PopupBody';
import { PopupContainer } from './PopupContainer';
import { useApphouse } from '../..';
/**
 * The vertical space between the popup and the top and bottom of the screen
 * +------------------+
 * |       100        |
 * |  +------------+  |
 * |  |            |  |
 * |  |   Popup    |  |
 * |  |            |  |
 * |  +------------+  |
 * |       100        |
 * +------------------+
 * @internal 100
 */
const VERTICAL_SPACE = 100;
/**
 * Popup component
 *
 * Usage:
 * `npm install apphouse`
 *
 * `import { Popup } from 'apphouse'`
 *
 * Toggle the popup to open in any component:
 *
 * ```tsx
 * const {openPopup} = useApphouse();
 *
 * <Button onClick={() => { openPopup(popup) }}>Toggle Popup</Button>```
 */
export const Popup: React.FC<PopupProps> = observer((props) => {
  const { children, fullscreen = false, styleOverwrites } = props;
  const [bodyHeight, setBodyHeight] = React.useState<string>('auto');
  const gutters = props.gutters ?? 20;
  const {
    app: {
      layout: { windowHeight }
    }
  } = useApphouse();

  const popupBodyRef = React.useRef<HTMLDivElement>(null);
  const popupHeadRef = React.useRef<HTMLElement>(null);
  const popupFooterRef = React.useRef<HTMLElement>(null);

  React.useEffect(() => {
    // in order to add scroll to the body, we need to know the height of the content
    // and the height of the popup
    // if the content is larger than the popup, we add scroll to the body
    if (popupBodyRef.current !== null) {
      const contentHeight = popupBodyRef.current.offsetHeight;
      const footerHeight = popupFooterRef.current?.offsetHeight ?? 0;
      const headerHeight = popupHeadRef.current?.offsetHeight ?? 0;

      let availableBodyHeight = windowHeight - headerHeight - footerHeight;
      if (!fullscreen) {
        // If not fullscreen, we need to subtract the padding from the available height
        // takes into account the spacing from top and bottom of the screen, hence multiplied by 2
        availableBodyHeight = availableBodyHeight - VERTICAL_SPACE * 2;
      }
      if (contentHeight > availableBodyHeight) {
        setBodyHeight(`${availableBodyHeight}px`);
        popupBodyRef.current.style.overflowY = 'scroll';
      }
    }
  }, [fullscreen, windowHeight]);
  const containerMaxHeight = windowHeight - VERTICAL_SPACE * 2;

  return (
    <PopupContainer maxHeight={`${containerMaxHeight}px`} {...props}>
      <PopupHeader
        ref={popupHeadRef}
        {...omit(props, ['styleOverwrites', 'children', 'gutters'])}
        styleOverwrites={styleOverwrites?.header}
        gutters={gutters}
      />

      <PopupBody
        ref={popupBodyRef}
        fullscreen={fullscreen}
        height={bodyHeight}
        styleOverwrites={styleOverwrites?.body}
        gutters={gutters}
      >
        {children}
      </PopupBody>

      <PopupFooter
        ref={popupFooterRef}
        {...omit(props, ['styleOverwrites', 'children', 'gutters'])}
        styleOverwrites={styleOverwrites?.footer}
      />
    </PopupContainer>
  );
});
