'use client';

/* eslint jsx-a11y/click-events-have-key-events: warn */

/* eslint jsx-a11y/no-static-element-interactions: warn */
import clsx from 'clsx';
import { PropsWithChildren, ReactElement, useRef } from 'react';
import { createPortal } from 'react-dom';
import { twMerge } from 'tailwind-merge';

import { FALLBACK_IMAGE_URL, SUPER_MODAL_Z_INDEX } from '@/utils/constants';

import CloseButton from '../button/CloseButton';

interface ModalProps extends PropsWithChildren {
  title?: string;
  subtitle?: string;
  onClose: (e?: any) => any;
  className?: string;
  width?: number | null;
  closeButtonClasses?: string;
  closeButtonProps?: object;
  titleWrapperClasses?: string;
  subtitleWrapperClasses?: string;
  contentWrapperClasses?: string;
  wrapperClasses?: string;
  mobileOnly?: boolean;
  withAuraBackground?: boolean;
  fullScreenHeight?: boolean;
  withHorizontalPadding?: boolean;
  disablePadding?: boolean;
  titleClassName?: string;
  subtitleClassName?: string;
  auraImage?: string;
  zIndex?: number;
  disableOutsideClick?: boolean;
  renderIcon?: () => ReactElement;
  showCloseButton?: boolean;
}

const Modal = ({
  title,
  subtitle,
  children,
  className,
  width = 500,
  closeButtonClasses,
  closeButtonProps = {},
  titleWrapperClasses,
  subtitleWrapperClasses,
  contentWrapperClasses,
  wrapperClasses,
  onClose,
  mobileOnly,
  withAuraBackground = false,
  fullScreenHeight = false,
  withHorizontalPadding = false,
  disablePadding = false,
  titleClassName = 'text-2xl',
  auraImage = FALLBACK_IMAGE_URL,
  subtitleClassName = 'text-sm',
  zIndex = SUPER_MODAL_Z_INDEX,
  disableOutsideClick = false,
  renderIcon,
  showCloseButton = true,
}: ModalProps) => {
  const contentContainerRef = useRef<HTMLDivElement>(null);
  const isOutsideClick = useRef<boolean>(false);

  return createPortal(
    <div
      className={twMerge(
        clsx(
          'modal-class modal-overlay fixed inset-0 flex h-screen items-center justify-center overflow-y-auto bg-black/60',
          'z-[100000]',
          {
            'block md:hidden': mobileOnly,
            'px-2 py-8': fullScreenHeight,
            'px-4': withHorizontalPadding,
          }
        ),
        className
      )}
      style={{ zIndex }}
      onMouseDown={(e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
        const isNotModalChild =
          (e.target as Element).closest('.prevent-modal-close') === null;
        const isModalOverlay = (e.target as Element).classList.contains(
          'modal-overlay'
        );
        if (
          e.target !== contentContainerRef.current &&
          !contentContainerRef.current?.contains(e.target as Node) &&
          (isNotModalChild || isModalOverlay)
        ) {
          isOutsideClick.current = true;
        } else {
          isOutsideClick.current = false;
        }
      }}
      onClick={() => {
        if (!disableOutsideClick && isOutsideClick.current) {
          onClose();
        }
      }}
    >
      <div
        ref={contentContainerRef}
        className={twMerge(
          `relative my-auto ${withAuraBackground ? 'bg-cover' : 'bg-background-secondary'} w-full rounded-[32px] text-foreground-primary ${fullScreenHeight ? 'h-full' : ''}`,
          contentWrapperClasses
        )}
        style={{
          maxWidth: width ? `${width}px` : undefined,
          ...(withAuraBackground
            ? { backgroundImage: `url(${auraImage})` }
            : {}),
        }}
        onClick={(e) => {
          e.stopPropagation();
        }}
      >
        {showCloseButton && (
          <div className='absolute top-4 right-4'>
            <CloseButton
              className={closeButtonClasses}
              onClick={onClose}
              {...closeButtonProps}
            />
          </div>
        )}
        <div
          className={`${withAuraBackground ? 'bg-black/40' : ''} h-full w-full ${disablePadding ? '' : 'p-6'}`}
        >
          {renderIcon ? (
            <div className='flex h-auto w-full flex-row justify-center'>
              {renderIcon()}
            </div>
          ) : null}
          {title !== undefined && (
            <div
              className={twMerge(
                'flex items-center justify-between pb-4',
                titleWrapperClasses
              )}
            >
              <span
                className={twMerge(
                  'pt-6 font-serif font-light whitespace-pre',
                  titleClassName
                )}
              >
                {title}
              </span>
            </div>
          )}
          {subtitle !== undefined && (
            <div
              className={twMerge(
                'flex items-center justify-between pb-4',
                subtitleWrapperClasses
              )}
            >
              <span
                className={twMerge(
                  'pt-0 text-[14px] leading-[20px] font-normal whitespace-pre opacity-70',
                  subtitleClassName
                )}
              >
                {subtitle ? subtitle : ' '}
              </span>
            </div>
          )}
          <div
            className={wrapperClasses || 'mb-4 max-h-[400px] overflow-y-auto'}
          >
            {children}
          </div>
        </div>
      </div>
    </div>,
    document.body
  );
};

export default Modal;
