import React, { isValidElement, useState } from 'react';
import { getWebProps } from 'react-native-unistyles/web';
import { breadcrumbStyles } from './Breadcrumb.styles';
import type { BreadcrumbProps, BreadcrumbItem as BreadcrumbItemType } from './types';
import { IconSvg } from '../Icon/IconSvg/IconSvg.web';
import { IconRegistry } from '../Icon/IconRegistry';
import { isIconName } from '../Icon/icon-resolver';
import Menu from '../Menu/Menu.web';
import type { MenuItem } from '../Menu/types';
import { mdiDotsHorizontal } from '@mdi/js';

// Self-register icons used internally by Breadcrumb
IconRegistry.registerMany({
  'dots-horizontal': mdiDotsHorizontal,
});

interface BreadcrumbItemProps {
  item: BreadcrumbItemType;
  isLast: boolean;
  size: BreadcrumbProps['size'];
  intent: BreadcrumbProps['intent'];
  itemStyle?: BreadcrumbProps['itemStyle'];
}

const BreadcrumbItem: React.FC<BreadcrumbItemProps> = ({ item, isLast, size, intent, itemStyle }) => {
  const isClickable = !!item.onPress && !item.disabled;
  const isDisabled = item.disabled || false;

  breadcrumbStyles.useVariants({
    size,
    intent,
    active: isLast,
    disabled: isDisabled,
  });

  const itemProps = getWebProps([breadcrumbStyles.item]);
  const itemTextProps = getWebProps([breadcrumbStyles.itemText, itemStyle]);
  const iconProps = getWebProps([breadcrumbStyles.icon]);

  const handleClick = () => {
    if (!item.disabled && item.onPress) {
      item.onPress();
    }
  };

  const renderIcon = () => {
    if (!item.icon) return null;

    if (isIconName(item.icon)) {
      return (
        <IconSvg
          name={item.icon}
          aria-label={item.icon}
        />
      );
    } else if (isValidElement(item.icon)) {
      return item.icon;
    }

    return null;
  };

  if (isClickable) {
    return (
      <button
        {...itemProps}
        onClick={handleClick}
        disabled={isDisabled}
        aria-current={isLast ? 'page' : undefined}
        style={{
          background: 'none',
          border: 'none',
          padding: 0,
          margin: 0,
          cursor: 'pointer',
          textDecoration: 'none',
          font: 'inherit',
          color: 'inherit',
        }}
      >
        {item.icon && (
          <span
            {...iconProps}
            style={{
              display: 'inline-flex',
              alignItems: 'center',
              justifyContent: 'center',
            }}
          >
            {renderIcon()}
          </span>
        )}
        <span {...itemTextProps}>
          {item.label}
        </span>
      </button>
    );
  }

  return (
    <div {...itemProps} aria-current={isLast ? 'page' : undefined}>
      {item.icon && (
        <span
          {...iconProps}
          style={{
            display: 'inline-flex',
            alignItems: 'center',
            justifyContent: 'center',
          }}
        >
          {renderIcon()}
        </span>
      )}
      <span {...itemTextProps}>
        {item.label}
      </span>
    </div>
  );
};

interface BreadcrumbSeparatorProps {
  separator: React.ReactNode;
  size: BreadcrumbProps['size'];
  separatorStyle?: BreadcrumbProps['separatorStyle'];
}

const BreadcrumbSeparator: React.FC<BreadcrumbSeparatorProps> = ({ separator, size, separatorStyle }) => {
  breadcrumbStyles.useVariants({ size });
  const isTextSeparator = typeof separator === 'string';

  if (isTextSeparator) {
    const separatorProps = getWebProps([breadcrumbStyles.separator, separatorStyle]);
    return (
      <span {...separatorProps} aria-hidden="true">
        {separator}
      </span>
    );
  }

  const separatorIconProps = getWebProps([breadcrumbStyles.separatorIcon, separatorStyle]);
  return (
    <span {...separatorIconProps} aria-hidden="true">
      {separator}
    </span>
  );
};

interface BreadcrumbEllipsisProps {
  size: BreadcrumbProps['size'];
  intent: BreadcrumbProps['intent'];
}

const BreadcrumbEllipsis: React.FC<BreadcrumbEllipsisProps> = ({ size, intent }) => {
  breadcrumbStyles.useVariants({ size, intent });
  const ellipsisProps = getWebProps([breadcrumbStyles.ellipsis]);
  const iconProps = getWebProps([breadcrumbStyles.ellipsisIcon]);

  return (
    <span {...ellipsisProps}>
      <IconSvg
        name="dots-horizontal"
        {...iconProps}
        aria-label="more items"
      />
    </span>
  );
};

/**
 * Navigation trail showing the current page location within a hierarchy.
 * Supports custom separators, responsive collapsing, and icon prefixes.
 */
const Breadcrumb: React.FC<BreadcrumbProps> = ({
  items,
  separator = '/',
  maxItems,
  intent = 'primary',
  size = 'md',
  style,
  itemStyle,
  separatorStyle,
  testID,
  responsive = false,
  minVisibleItems = 3,
  id,
}) => {
  const [menuOpen, setMenuOpen] = useState(false);

  breadcrumbStyles.useVariants({ size, intent });
  const containerProps = getWebProps([breadcrumbStyles.container, style as any]);
  const menuButtonProps = getWebProps([breadcrumbStyles.menuButton]);
  const menuIconProps = getWebProps([breadcrumbStyles.menuButtonIcon]);

  // Handle responsive collapsing
  let displayItems = items;
  let collapsedItems: BreadcrumbItemType[] = [];
  let showMenu = false;
  let showEllipsis = false;

  if (responsive && items.length > minVisibleItems) {
    // Responsive mode: show first item + menu + last (minVisibleItems - 2) items
    showMenu = true;
    const lastItemCount = Math.max(1, minVisibleItems - 2);
    displayItems = [
      items[0],
      ...items.slice(-lastItemCount),
    ];
    collapsedItems = items.slice(1, -(lastItemCount));
  } else if (maxItems && items.length > maxItems) {
    // Legacy truncation mode
    showEllipsis = true;
    const firstItems = items.slice(0, 1);
    const lastItems = items.slice(-(maxItems - 1));
    displayItems = [...firstItems, ...lastItems];
  }

  // Convert collapsed breadcrumb items to menu items
  const menuItems: MenuItem[] = collapsedItems.map((item, index) => ({
    id: `collapsed-${index}`,
    label: item.label,
    onClick: item.onPress,
    disabled: item.disabled,
    icon: isIconName(item.icon) ? item.icon : undefined,
  }));

  return (
    <nav {...containerProps} aria-label="Breadcrumb" id={id} data-testid={testID}>
      {displayItems.map((item, index) => {
        const isLast = index === displayItems.length - 1;
        const shouldShowEllipsis = showEllipsis && index === 1;
        const shouldShowMenu = showMenu && index === 1;

        return (
          <React.Fragment key={index}>
            {shouldShowEllipsis && (
              <>
                <BreadcrumbEllipsis size={size} intent={intent} />
                <BreadcrumbSeparator separator={separator} size={size} separatorStyle={separatorStyle} />
              </>
            )}

            {shouldShowMenu && (
              <>
                <Menu
                  items={menuItems}
                  open={menuOpen}
                  onOpenChange={setMenuOpen}
                  placement="bottom-start"
                  size={size}
                >
                  <button
                    className={menuButtonProps.className}
                    style={{
                      background: 'none',
                      border: 'none',
                      cursor: 'pointer',
                      display: 'inline-flex',
                      alignItems: 'center',
                      justifyContent: 'center',
                    }}
                    aria-label="Show more breadcrumb items"
                  >
                    <IconSvg
                      name="dots-horizontal"
                      {...menuIconProps}
                      aria-label="dots-horizontal"
                    />
                  </button>
                </Menu>
                <BreadcrumbSeparator separator={separator} size={size} separatorStyle={separatorStyle} />
              </>
            )}

            <BreadcrumbItem
              item={item}
              isLast={isLast}
              size={size}
              intent={intent}
              itemStyle={itemStyle}
            />

            {!isLast && (
              <BreadcrumbSeparator separator={separator} size={size} separatorStyle={separatorStyle} />
            )}
          </React.Fragment>
        );
      })}
    </nav>
  );
};

export default Breadcrumb;
