import * as RadixDialog from '@radix-ui/react-dialog';
import { Cross1Icon } from '@radix-ui/react-icons';
import { Flex, Theme } from '@radix-ui/themes';
import { useEffect } from 'react';
import { usePortalContainer } from '@/theme/portal-provider';
import { Heading } from './heading';
import { IconButton } from './icon-button';

type ContentProps = RadixDialog.DialogContentProps & {
  width?: string;
  maxWidth?: string;
  minWidth?: string;
  height?: string;
  maxHeight?: string;
  minHeight?: string;
  title?: string;
  hideCloseButton?: boolean;
  buttons?: React.ReactNode;
};

const preventDefault: RadixDialog.DialogContentProps['onPointerDownOutside'] = (
  e
) => {
  e.preventDefault();
};

function Content(props: ContentProps): React.ReactNode {
  const {
    children,
    style = {},
    width,
    maxWidth,
    minWidth,
    maxHeight,
    height,
    minHeight,
    title,
    buttons,
    hideCloseButton,
    className,
    ...rest
  } = props;
  const { dialogContainerRef } = usePortalContainer();

  return (
    <RadixDialog.Portal container={dialogContainerRef.current}>
      <Theme asChild>
        <RadixDialog.Overlay className="DialogOverlay">
          <RadixDialog.Content
            className={`DialogContent ${className || ''}`}
            onPointerDownOutside={preventDefault}
            style={{
              width,
              maxWidth,
              minWidth,
              maxHeight,
              height,
              minHeight,
              ...style,
            }}
            {...rest}
          >
            <Flex gap="2" justify="between" width="100%">
              <RadixDialog.Title asChild>
                {typeof title === 'string' && title !== '' ? (
                  <Heading mb="2" variant="heading3">
                    {title}
                  </Heading>
                ) : (
                  title
                )}
              </RadixDialog.Title>
              {!hideCloseButton && (
                <RadixDialog.Close asChild className="DialogClose">
                  <IconButton color="gray" variant="ghost">
                    <Cross1Icon />
                  </IconButton>
                </RadixDialog.Close>
              )}
            </Flex>
            {children}
            {buttons ? (
              <Flex gap="3" justify="end" mt="3" width="100%">
                {buttons}
              </Flex>
            ) : null}
          </RadixDialog.Content>
        </RadixDialog.Overlay>
      </Theme>
    </RadixDialog.Portal>
  );
}

function Close({
  children,
  ...rest
}: RadixDialog.DialogCloseProps): React.ReactNode {
  return (
    <RadixDialog.Close asChild {...rest}>
      {children}
    </RadixDialog.Close>
  );
}

function Trigger({
  children,
  ...rest
}: RadixDialog.DialogTriggerProps): React.ReactNode {
  return (
    <RadixDialog.Trigger asChild {...rest}>
      {children}
    </RadixDialog.Trigger>
  );
}

function Root(props: RadixDialog.DialogProps): React.ReactNode {

  // 모달이 닫힌 후 포커스 복원 및 이벤트 정리
  useEffect(() => {
    if (!props.open) {
      // 모달이 닫힌 후 약간의 지연을 두고 포커스 복원
      const timer = setTimeout(() => {
        // 활성 요소에 포커스 복원
        const activeElement = document.activeElement as HTMLElement | null;
        // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- 어떤 dom인지 확실하지 않음
        activeElement?.blur?.();

        // body의 pointer-events 복원
        document.body.style.pointerEvents = '';

        // 이벤트 리스너 정리
        // document.removeEventListener('click', () => {
        //   // 이벤트 리스너 정리
        // });
      }, 100);

      return () => { clearTimeout(timer); };
    }
  }, [props.open]);
  return <RadixDialog.Root {...props} />;
}

export const Dialog = {
  Root,
  Trigger,
  Content,
  Close,
  Description: RadixDialog.Description,
  Title: RadixDialog.Title,
};
