import React, { useCallback, useEffect, useRef, useState } from 'react';
import { Flex, SilkeBox } from '../silke-box';
import { SilkeTitle } from '../silke-text';
import { SilkeButton } from '../silke-button';
import { useKeyUp } from '@vev/utils';
import { useMouseDownOutside } from '../../hooks';
import classnames from 'classnames/bind';
import styles from './silke-drawer.scss';
import { SilkeTitleKind } from '../silke-text/silke-text-types';

const cl = classnames.bind(styles);

export interface SilkeDrawerProps {
  title?: React.ReactNode;
  titleKind?: SilkeTitleKind;
  open: boolean;
  onRequestClose: () => void;
  displayCloseButton?: boolean;
  disableFocusTrap?: boolean;
  displayFader?: boolean;
}

export const SilkeDrawer = ({
  open,
  onRequestClose,
  displayCloseButton = true,
  children,
  title,
  titleKind = 's',
  displayFader,
}: React.PropsWithChildren<SilkeDrawerProps>) => {
  const [shouldRender, setShouldRender] = useState(false);
  const ref = useRef<HTMLDivElement>(null);

  useKeyUp('Escape', () => {
    if (open) {
      onRequestClose();
    }
  });

  useMouseDownOutside(ref, onRequestClose, !open);

  useEffect(() => {
    if (open) {
      setShouldRender(true);
    }
  }, [open]);

  const onTransitionEnd = useCallback(() => {
    if (!open) {
      setShouldRender(false);
    }
  }, [open]);

  const [doDisplayFader, setDoDisplayFader] = useState(displayFader);

  const onScroll = () => {
    if (ref.current) {
      const { scrollTop, scrollHeight, clientHeight } = ref.current;
      const isOnBottom = scrollTop + clientHeight === scrollHeight;
      setDoDisplayFader(displayFader && !isOnBottom);
    }
  };

  return (
    <div className={cl('sidebar', { open })} id="sliding-sidebar" onTransitionEnd={onTransitionEnd}>
      <SilkeBox bg="neutral-5" className={cl('content', { fader: doDisplayFader })}>
        <SilkeBox
          pad="xl"
          column
          fill
          scroll
          tabIndex={-1}
          ref={ref}
          gap="l"
          className={cl('content-inner')}
          onScroll={onScroll}
        >
          {title || displayCloseButton ? (
            <SilkeBox vAlign="center" hAlign="spread">
              {title ? (
                <SilkeTitle kind={titleKind} tag="h4">
                  {title}
                </SilkeTitle>
              ) : (
                <Flex />
              )}
              <SilkeButton icon="close" kind="ghost" onClick={onRequestClose} />
            </SilkeBox>
          ) : null}
          {shouldRender ? children : <button />}
        </SilkeBox>
      </SilkeBox>
    </div>
  );
};
