import React, { useRef } from 'react';

import { Overlay, useModalOverlay, useDialog } from 'react-aria';
import { OverlayTriggerState } from 'react-stately';
import { DOMAttributes, FocusableElement } from '@react-types/shared';

/*
  This has to be a separate element otherwise the focus trap fails. Assuming this is because it needs
  to fit inside the 'Overlay' as a form of context.
*/
function ModalContent({
  children,
  ...props
}: {
  children: (titleProps: DOMAttributes<FocusableElement>) => React.ReactElement;
}) {
  const ref = useRef<HTMLDivElement>(null);
  const { dialogProps, titleProps } = useDialog(props, ref);

  return (
    <div
      {...dialogProps}
      ref={ref}
      className="z-50 relative bg-white rounded-lg h-screen lg:h-[calc(100vh-9rem)] w-screen max-w-[50rem] outline-0"
    >
      {children(titleProps)}
    </div>
  );
}

export type ModalProps = {
  isDismissable?: boolean;
  state: OverlayTriggerState;
  overlayProps: DOMAttributes<FocusableElement>;
  children: (titleProps: DOMAttributes<FocusableElement>) => React.ReactElement; // Returns the title props from the 'ModalContent'
  scope: 'squiz-gb-scope' | 'squiz-cb-scope' | 'squiz-rb-scope';
};
export function Modal({ isDismissable, state, overlayProps, children, scope, ...props }: ModalProps) {
  const ref = useRef<HTMLDivElement>(null);
  const { modalProps, underlayProps } = useModalOverlay({ isDismissable, ...props }, state, ref);

  return (
    <Overlay>
      <div className={scope}>
        <div
          {...underlayProps}
          className="h-full z-[9998] fixed inset-0 before:z-40 before:fixed before:inset-0 before:bg-black before:bg-opacity-25"
        >
          <div {...modalProps} ref={ref} className="h-full flex items-center justify-center">
            <ModalContent {...overlayProps}>{(titleProps) => children(titleProps)}</ModalContent>
          </div>
        </div>
      </div>
    </Overlay>
  );
}
