import { useCallback, useEffect, useId, useMemo, useRef, useState } from 'react';
import Button from './Button';
import Dropdown from './Dropdown';
import Icon from './Icon';

const ROOT = 'tfds-split-button inline-flex shrink-0 items-center';
const PRIMARY_BUTTON = '!shrink-0 !rounded-r-none';
const SECONDARY_BUTTON = '!-ml-px !shrink-0 !rounded-l-none';
const SECONDARY_DIVIDER_PRIMARY =
  'before:pointer-events-none before:absolute before:left-0 before:top-1/2 before:h-[60%] before:w-px before:-translate-y-1/2 before:bg-white/25 hover:before:bg-white/40';
const SECONDARY_BUTTON_RELATIVE = 'relative';

function stopEvent(event) {
  event.stopPropagation();
}

/**
 * SplitButton — 由两个标准 Button 拼接形成的复合动作。
 *
 * 左侧承载主动作，右侧承载更多操作或次级菜单入口。
 * 次级菜单复用 Dropdown 基础组件。
 */
export default function SplitButton({
  variant = 'outline-black',
  size = 'md',
  primaryLabel,
  menuItems = [],
  placement = 'auto',
  open,
  defaultOpen = false,
  onOpenChange = null,
  onPrimaryClick = null,
  onSecondaryClick = null,
  onMenuItemClick = null,
  secondaryIconName = 'chevron-down-stroked',
  secondaryTooltip = '更多操作',
  secondaryAriaLabel,
  disabled = false,
  loading = false,
  className = '',
  primaryClassName = '',
  secondaryClassName = '',
  style,
}) {
  const menuId = useId();
  const rootRef = useRef(null);
  const isOpenControlled = open !== undefined;
  const [innerOpen, setInnerOpen] = useState(defaultOpen);
  const [resolvedPlacement, setResolvedPlacement] = useState(placement === 'top' ? 'top' : 'bottom');
  const normalizedMenuItems = useMemo(
    () => (Array.isArray(menuItems) ? menuItems.filter((item) => item && item.label) : []),
    [menuItems],
  );
  const hasMenu = normalizedMenuItems.length > 0;
  const isOpen = isOpenControlled ? open : innerOpen;

  useEffect(() => {
    if (!isOpenControlled) setInnerOpen(defaultOpen);
  }, [defaultOpen, isOpenControlled]);

  const updateOpen = useCallback((nextValue) => {
    if (!isOpenControlled) setInnerOpen(nextValue);
    onOpenChange?.(nextValue);
  }, [isOpenControlled, onOpenChange]);

  const dropdownItems = useMemo(
    () => normalizedMenuItems.map((item) => ({
      id: item.id || item.label,
      value: item.id || item.label,
      label: item.label,
      iconName: item.iconName,
      danger: item.danger,
      disabled: item.disabled,
      onClick: (menuItem, event) => {
        stopEvent(event);
        if (menuItem.disabled) return;
        item.onClick?.(item, event);
        onMenuItemClick?.(item, event);
      },
    })),
    [normalizedMenuItems, onMenuItemClick],
  );

  const showIconColumn = normalizedMenuItems.some((item) => item.iconName);

  const resolvedSecondaryAriaLabel = secondaryAriaLabel || `${primaryLabel || '操作'}${secondaryTooltip}`;
  const resolvedSecondaryIconName = hasMenu && (!secondaryIconName || secondaryIconName === 'chevron-down-stroked' || secondaryIconName === 'chevron-up-stroked')
    ? (resolvedPlacement === 'top' ? 'chevron-up-stroked' : 'chevron-down-stroked')
    : (secondaryIconName || 'chevron-down-stroked');

  function handlePrimaryAction(event) {
    onPrimaryClick?.(event);
  }

  function handleSecondaryAction(event) {
    stopEvent(event);
    if (disabled || loading) return;
    if (!hasMenu) {
      onSecondaryClick?.(event);
    }
  }

  const primaryButtonStyle = style && (style.backgroundColor || style.backgroundImage)
    ? {
        backgroundColor: style.backgroundColor,
        backgroundImage: style.backgroundImage,
        color: style.color,
        borderColor: style.borderColor,
      }
    : undefined;
  const secondaryButtonStyle = primaryButtonStyle
    ? { ...primaryButtonStyle, borderColor: primaryButtonStyle.borderColor || 'transparent' }
    : undefined;

  const secondaryButton = (
    <Button
      id={menuId}
      type="button"
      variant={variant}
      size={size}
      iconOnly
      tooltip={isOpen && hasMenu ? null : secondaryTooltip}
      className={[
        SECONDARY_BUTTON,
        variant === 'primary' ? `${SECONDARY_BUTTON_RELATIVE} ${SECONDARY_DIVIDER_PRIMARY}` : '',
        secondaryClassName,
      ].filter(Boolean).join(' ')}
      icon={<Icon name={resolvedSecondaryIconName} size={16} aria-hidden="true" />}
      aria-label={resolvedSecondaryAriaLabel}
      aria-haspopup={hasMenu ? 'menu' : undefined}
      aria-expanded={hasMenu ? isOpen : undefined}
      onClick={handleSecondaryAction}
      disabled={disabled || loading}
      style={secondaryButtonStyle}
    />
  );

  return (
    <span
      ref={rootRef}
      className={[ROOT, className].filter(Boolean).join(' ')}
      data-tfds-component="SplitButton"
    >
      <Button
        type="button"
        variant={variant}
        size={size}
        className={[PRIMARY_BUTTON, primaryClassName].filter(Boolean).join(' ')}
        onClick={handlePrimaryAction}
        disabled={disabled}
        loading={loading}
        style={primaryButtonStyle}
      >
        {primaryLabel}
      </Button>

      {hasMenu ? (
        <Dropdown
          className="inline-flex"
          open={isOpen}
          onOpenChange={(next) => {
            updateOpen(next);
            if (next) {
              requestAnimationFrame(() => {
                const panel = rootRef.current?.querySelector('[data-tfds-component="Dropdown.Panel"]');
                const nextPlacement = panel?.getAttribute('data-placement');
                if (nextPlacement === 'top' || nextPlacement === 'bottom') {
                  setResolvedPlacement(nextPlacement);
                }
              });
            }
          }}
          placement={placement}
          panelAlign="end"
          selectionIndicator="none"
          showIcon={showIconColumn}
          matchTriggerWidth={false}
          minWidth={168}
          items={dropdownItems}
          trigger={secondaryButton}
        />
      ) : secondaryButton}
    </span>
  );
}
