import {
  type ComponentProps,
  type CSSProperties,
  type ReactNode,
  useEffect,
  useId,
} from 'react';
import { createPortal } from 'react-dom';

import { getNineSliceStyle, UI_CHROME } from '../../uiAssets';
import { PlatformModalCloseButton } from './PlatformModalCloseButton';

type UnifiedModalVariant = 'platform' | 'pixel';
type UnifiedModalSize = 'sm' | 'md' | 'lg' | 'xl' | 'fullscreen';
type UnifiedModalCloseVariant = NonNullable<
  ComponentProps<typeof PlatformModalCloseButton>['variant']
>;
type UnifiedModalCloseIcon = ComponentProps<
  typeof PlatformModalCloseButton
>['icon'];

type UnifiedModalProps = {
  open: boolean;
  title: string;
  ariaLabel?: string;
  titleId?: string;
  description?: ReactNode;
  children: ReactNode;
  footer?: ReactNode;
  onClose: () => void;
  variant?: UnifiedModalVariant;
  size?: UnifiedModalSize;
  showHeader?: boolean;
  closeDisabled?: boolean;
  closeOnBackdrop?: boolean;
  closeOnEscape?: boolean;
  showCloseButton?: boolean;
  closeLabel?: string;
  closeVariant?: UnifiedModalCloseVariant;
  closeIcon?: UnifiedModalCloseIcon;
  portal?: boolean;
  zIndexClassName?: string;
  overlayClassName?: string;
  overlayStyle?: CSSProperties;
  panelClassName?: string;
  headerClassName?: string;
  titleClassName?: string;
  descriptionClassName?: string;
  bodyClassName?: string;
  footerClassName?: string;
  panelStyle?: CSSProperties;
};

const PLATFORM_SIZE_CLASS: Record<UnifiedModalSize, string> = {
  sm: 'max-w-md',
  md: 'max-w-xl',
  lg: 'max-w-3xl',
  xl: 'max-w-5xl',
  fullscreen: 'max-w-[min(100vw,76rem)] sm:h-[min(92vh,60rem)]',
};

const PIXEL_SIZE_CLASS: Record<UnifiedModalSize, string> = {
  sm: 'max-w-sm',
  md: 'max-w-md',
  lg: 'max-w-3xl',
  xl: 'max-w-5xl',
  fullscreen: 'max-w-[min(96vw,64rem)]',
};

function joinClassNames(...classNames: Array<string | false | null | undefined>) {
  return classNames.filter(Boolean).join(' ');
}

function getPanelStyle(
  variant: UnifiedModalVariant,
  panelStyle: CSSProperties | undefined,
) {
  if (variant !== 'pixel') {
    return panelStyle;
  }

  return {
    ...getNineSliceStyle(UI_CHROME.modalPanel),
    ...panelStyle,
  };
}

function UnifiedModalContent({
  open,
  title,
  ariaLabel,
  titleId: titleIdProp,
  description,
  children,
  footer,
  onClose,
  variant = 'platform',
  size = 'md',
  showHeader = true,
  closeDisabled = false,
  closeOnBackdrop = true,
  closeOnEscape = true,
  showCloseButton = true,
  closeLabel = '关闭',
  closeVariant,
  closeIcon,
  zIndexClassName = 'z-[90]',
  overlayClassName,
  overlayStyle,
  panelClassName,
  headerClassName,
  titleClassName,
  descriptionClassName,
  bodyClassName,
  footerClassName,
  panelStyle,
}: Omit<UnifiedModalProps, 'portal'>) {
  const generatedTitleId = useId();
  const descriptionId = useId();
  const titleId = titleIdProp ?? generatedTitleId;

  useEffect(() => {
    if (!open || closeDisabled || !closeOnEscape) {
      return;
    }

    const handleKeyDown = (event: KeyboardEvent) => {
      if (event.key === 'Escape') {
        onClose();
      }
    };

    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, [closeDisabled, closeOnEscape, onClose, open]);

  if (!open) {
    return null;
  }

  const isPixel = variant === 'pixel';
  const sizeClassName = isPixel
    ? PIXEL_SIZE_CLASS[size]
    : PLATFORM_SIZE_CLASS[size];

  const overlayClasses = isPixel
    ? 'fixed inset-0 flex items-center justify-center bg-black/72 p-3 backdrop-blur-sm sm:p-4'
    : 'platform-overlay fixed inset-0 flex items-end justify-center p-3 backdrop-blur-sm sm:items-center sm:p-4';

  const panelClasses = isPixel
    ? 'pixel-nine-slice pixel-modal-shell flex max-h-[min(92vh,58rem)] w-full flex-col overflow-hidden shadow-[0_24px_80px_rgba(0,0,0,0.55)]'
    : 'platform-modal-shell flex max-h-[min(92vh,58rem)] w-full flex-col overflow-hidden rounded-t-[1.75rem] sm:rounded-[1.75rem]';

  const headerClasses = isPixel
    ? 'flex items-start justify-between gap-3 border-b border-white/10 px-4 py-3 sm:px-5 sm:py-4'
    : 'flex items-start justify-between gap-3 border-b border-[var(--platform-subpanel-border)] px-4 py-4 sm:px-5';

  const titleClasses = isPixel
    ? 'truncate text-sm font-semibold text-white'
    : 'text-base font-semibold text-[var(--platform-text-strong)]';

  const descriptionClasses = isPixel
    ? 'mt-1 text-xs leading-5 text-zinc-400'
    : 'mt-1 text-xs leading-5 text-[var(--platform-text-base)]';

  const bodyClasses = isPixel
    ? 'min-h-0 flex-1 overflow-y-auto p-4 sm:p-5'
    : 'min-h-0 flex-1 overflow-y-auto px-4 py-4 sm:px-5 sm:py-5';

  const footerClasses = isPixel
    ? 'flex flex-wrap items-center justify-end gap-3 border-t border-white/10 px-4 py-3 sm:px-5 sm:py-4'
    : 'flex flex-wrap items-center justify-end gap-3 border-t border-[var(--platform-subpanel-border)] px-4 py-4 sm:px-5';

  return (
    <div
      className={joinClassNames(overlayClasses, zIndexClassName, overlayClassName)}
      style={overlayStyle}
      onClick={(event) => {
        if (
          closeOnBackdrop &&
          !closeDisabled &&
          event.target === event.currentTarget
        ) {
          onClose();
        }
      }}
    >
      <div
        role="dialog"
        aria-modal="true"
        aria-labelledby={showHeader && !ariaLabel ? titleId : undefined}
        aria-label={ariaLabel ?? (!showHeader ? title : undefined)}
        aria-describedby={description ? descriptionId : undefined}
        className={joinClassNames(panelClasses, sizeClassName, panelClassName)}
        style={getPanelStyle(variant, panelStyle)}
        onClick={(event) => event.stopPropagation()}
      >
        {showHeader ? (
          <div className={joinClassNames(headerClasses, headerClassName)}>
            <div className="min-w-0">
              <div
                id={titleId}
                className={joinClassNames(titleClasses, titleClassName)}
              >
                {title}
              </div>
              {description ? (
                <div
                  id={descriptionId}
                  className={joinClassNames(
                    descriptionClasses,
                    descriptionClassName,
                  )}
                >
                  {description}
                </div>
              ) : null}
            </div>
            {showCloseButton ? (
              <PlatformModalCloseButton
                label={closeLabel}
                onClick={onClose}
                disabled={closeDisabled}
                variant={closeVariant ?? (isPixel ? 'pixel' : 'platformIcon')}
                icon={closeIcon}
              />
            ) : null}
          </div>
        ) : null}
        <div className={joinClassNames(bodyClasses, bodyClassName)}>
          {/* 无头部弹窗仍需要把描述挂到 aria-describedby，避免只剩可访问名称没有上下文。 */}
          {!showHeader && description ? (
            <div id={descriptionId} className="sr-only">
              {description}
            </div>
          ) : null}
          {children}
        </div>
        {footer ? (
          <div className={joinClassNames(footerClasses, footerClassName)}>
            {footer}
          </div>
        ) : null}
      </div>
    </div>
  );
}

/**
 * 统一模态窗口外壳。
 * 业务组件只传入标题、内容和操作区；遮罩、无障碍属性、Escape 与移动端布局在这里收口。
 */
export function UnifiedModal({ portal = true, ...props }: UnifiedModalProps) {
  if (!portal || typeof document === 'undefined') {
    return <UnifiedModalContent {...props} />;
  }

  return createPortal(<UnifiedModalContent {...props} />, document.body);
}
