import * as React from 'react';

import { keyframes, css } from '@emotion/react';
import styled from '@emotion/styled';
import { Placement } from '@popperjs/core';
import { useContextSelector } from 'use-context-selector';

import { IStyledProp } from '@eduzz/houston-styles';

import PopoverContext from './context';

export interface IPopoverProps extends IStyledProp {
  targetRef: React.RefObject<HTMLElement>;
  children?: React.ReactNode;
  fullWidth?: boolean;
  placement?: Placement;
}

export interface IPopoverRef {
  open(): void;
  close(): void;
}

const Popover = React.forwardRef<IPopoverRef, IPopoverProps>(
  ({ targetRef, children, className, fullWidth, placement }, ref) => {
    const setState = useContextSelector(PopoverContext, context => context.setState);
    const contentRef = React.useRef<HTMLDivElement>();
    const closeRef = React.useRef<() => void>();

    React.useImperativeHandle(
      ref,
      () => ({
        open() {
          closeRef.current = setState({
            opened: true,
            target: targetRef.current,
            content: contentRef.current,
            placement
          });

          contentRef.current.style.width = fullWidth ? `${targetRef.current.offsetWidth}px` : 'auto';
        },
        close() {
          closeRef.current && closeRef.current();
        }
      }),
      [fullWidth, placement, setState, targetRef]
    );

    return (
      <div ref={contentRef} className={className}>
        <div className='__container'>{children}</div>
      </div>
    );
  }
);

const showAnimation = keyframes`
  0% { transform: scale(0.5); opacity: 0; }
  100% { transform: scale(1); opacity: 1; }
`;

const hideAnimation = keyframes`
  0% { transform: scale(1); opacity: 1; }
  100% { transform: scale(0.9); opacity: 0; }
`;

export default styled(Popover, { label: 'houston-popover' })(
  ({ theme }) => css`
    box-sizing: border-box;
    max-width: 100vw;
    z-index: 1000;
    pointer-events: none;
    position: absolute;
    top: calc(100vh * -1000);
    left: calc(100vh * -1000);

    & > .__container {
      width: 100%;
      max-height: 50vh;
      overflow-y: auto;
      overflow-x: hidden;
      background-color: white;
      box-shadow: ${theme.shadow.level[1]};
      border-radius: ${theme.border.radius.xs};
      box-sizing: border-box;
      transform-origin: top center;
      animation-duration: 0.2s;
      animation-name: ${hideAnimation};
      animation-fill-mode: forwards;
    }

    &.--opened {
      pointer-events: auto;

      & > .__container {
        animation-name: ${showAnimation};
      }
    }
  `
);