import type { MouseEvent } from 'react'
import { useEffect, useMemo, useCallback } from 'react'

import Box from '../box'
import Button from '../button'
import type { VuiComponent } from '../core'
import { omitThemingProps, styled, th, vui } from '../core'
import Popover from '../popover'
import { colors } from '../theme'
import Tooltip from '../tooltip'
import { cs, generateMenuItemId } from '../utils'
import { collapsedWidth, expandedWidth } from './consts'
import SidemenuItemContent from './SidemenuItemContent'
import type { SidemenuItemV2Props } from './sidemenuV2.types'
import useSidemenuItem from './useSidemenuItem'

export const PopoverHovered = styled.div<{ hoverColor: string }>`
  &:hover .vui-sidemenu-item-popover .vui-button.vui-button {
    background: ${p => th.color(p.hoverColor)};
  }
  &:hover div:last-child .tippy-content .vui-sidemenu-item-content > .vui-box > .vui-button.vui-button {
    background: ${p => th.color(p.hoverColor)};
  }
`

// SidemenuPopover component extracted from inline Popover logic
const SidemenuPopover = ({
  isDark,
  className,
  buttonStyles,
  isExactlyActive,
  icon,
  title,
  isMenuExpanded,
  children,
}: {
  isDark: boolean
  className?: string
  buttonStyles: any
  isExactlyActive: boolean
  icon?: any
  title: string
  isMenuExpanded: boolean
  children: React.ReactNode
}) => (
  <Popover offset={[0, collapsedWidth - expandedWidth - 2]} placement="right-start" trigger="mouseenter">
    {({ isOpen }: { isOpen: boolean }) => (
      <PopoverHovered hoverColor={isDark ? colors.seaBlue.main : colors.skyBlue.selected}>
        <Popover.Trigger as={Box} className={cs('vui-sidemenu-item-popover', className)}>
          <Button
            {...buttonStyles}
            borderLeft={`3px solid ${isDark ? 'digiGreen.main' : 'seaBlue.main'}`}
            isActive={isExactlyActive}
            className={cs('focusAsBorder')}
          >
            <SidemenuItemContent
              icon={icon}
              iconSize={buttonStyles.iconSize}
              title={title}
              isMenuExpanded={isMenuExpanded}
            />
          </Button>
        </Popover.Trigger>
        <Popover.Content elevation="none" className={cs('vui-sidemenu-item-content', className)}>
          <Box flexDirection="column" justifyContent="start" w="100%">
            <Button
              {...buttonStyles}
              borderLeftColor={'transparent!important'}
              minW={'240px'}
              isActive={isOpen && isExactlyActive}
              className={cs('focusAsBorder')}
            >
              <SidemenuItemContent title={title} isInPopover={true} />
            </Button>
            {children}
          </Box>
        </Popover.Content>
      </PopoverHovered>
    )}
  </Popover>
)

/** A menu item. */
export const SidemenuItemV2 = vui<'button', SidemenuItemV2Props>((props, ref) => {
  const {
    children,
    className,
    disabled = false,
    icon,
    isActive = false,
    isExpanded = true,
    itemId,
    level = 0,
    onBottom = false,
    onClick,
    onCollapse,
    onExpand,
    title,
    ...rest
  } = omitThemingProps(props)

  // Use consistent itemId generation - prioritize provided itemId, then use utility function
  const computedItemId = itemId || generateMenuItemId(title, level) || `item-${Math.random().toString(36).substr(2, 9)}`

  const { isDark, isMenuExpanded, styles, size, isSubmenuOpen, toggleSubmenu } = useSidemenuItem(computedItemId)

  // Use the isActive prop directly - parent should handle exact path matching
  const isExactlyActive = isActive

  useEffect(() => {
    // Only call onExpand/onCollapse if the main menu is expanded
    // This prevents child items from expanding the main menu when it's collapsed
    if (isMenuExpanded) {
      if (isSubmenuOpen) onExpand?.()
      if (!isSubmenuOpen) onCollapse?.()
    }
  }, [isSubmenuOpen, onExpand, onCollapse, isMenuExpanded])

  // Memoized computed values for better performance
  const computedStates = useMemo(() => {
    const hasChildren = !!children
    const isSubmenuCollapsed = hasChildren && !isSubmenuOpen
    // Only allow submenu expansion when main menu is expanded
    const isSubmenuExpanded = hasChildren && isSubmenuOpen && isMenuExpanded
    const shouldShowExpandButton = hasChildren && isMenuExpanded
    const buttonSize = level < 1 ? ('lg' as const) : ('md' as const)
    const iconSize = level < 1 ? ('sm' as const) : ('xs' as const)

    const states = {
      hasChildren,
      hasChildrenCollapsed: isSubmenuCollapsed,
      hasChildrenExpanded: isSubmenuExpanded,
      shouldShowExpandButton,
      buttonSize,
      iconSize,
      isDisabled: disabled,
      shouldShowBorder: !hasChildren || isSubmenuOpen,
    }

    return states
  }, [children, isSubmenuOpen, isMenuExpanded, disabled, size, level])

  // Memoized theme values to prevent recalculation
  const themeValues = useMemo(
    () => ({
      activeColor: isDark ? 'digiGreen.main' : 'seaBlue.main',
      buttonVariant: isDark ? 'menuDark' : 'menuLight',
    }),
    [isDark],
  )

  // Optimized stable callback
  const handleClick = useCallback(
    (event: MouseEvent) => {
      if (!computedStates.isDisabled) {
        const targetTag = event.target as HTMLElement
        if (
          (targetTag.classList.contains('vui-tagText') || targetTag.classList.contains('vui-tag')) &&
          typeof window !== 'undefined' &&
          (targetTag.parentElement?.dataset.link || targetTag?.dataset.link)
        ) {
          const url = atob(targetTag.parentElement?.dataset.link ?? targetTag?.dataset.link ?? '')
          window.open(url, '_blank', 'noopener,noreferrer')
        } else {
          event?.stopPropagation?.()
          onClick?.()
        }
      }
      toggleSubmenu?.()
    },
    [onClick, computedStates.isDisabled],
  )

  // Memoized button styles - Major performance improvement
  const buttonStyles = useMemo(
    () => ({
      // Get base item styles from theme
      ...(styles && 'item' in styles && styles.item ? styles.item : {}),

      // Dynamic border color based on active state
      borderLeftColor: isExactlyActive ? themeValues.activeColor : 'transparent',

      // Animation properties (enhanced from theme)
      transitionProperty: 'background-color, border-color, color, transform, opacity',

      // Button specific properties
      size: computedStates.buttonSize,
      h: computedStates.buttonSize === 'lg' ? 40 : 36,
      iconSize: computedStates.iconSize,
      variant: themeValues.buttonVariant,

      // Event handlers
      onClick: handleClick,
      disabled: computedStates.isDisabled,

      // Accessibility
      role: 'button',
      tabIndex: computedStates.isDisabled ? -1 : 0,
      'aria-disabled': computedStates.isDisabled,
      'aria-pressed': isExactlyActive,

      // Merge custom props
      ...rest,
    }),
    [
      // Dependencies grouped logically - simplified since computedStates contains most values
      styles,
      computedStates,
      isExactlyActive,
      themeValues,
      handleClick,
      rest,
    ],
  )

  // Memoized expand/collapse button properties
  const expandButtonProps = useMemo(() => {
    const isExpanded = isSubmenuOpen
    const chevronIcon = isExpanded ? 'falChevronUp' : 'falChevronDown'
    const ariaLabel = isExpanded ? 'Collapse' : 'Expand'

    return {
      'aria-label': ariaLabel,
      className: 'vui-sidemenu-item-expand',
      variant: themeValues.buttonVariant,
      icon: chevronIcon,
      size: 'sm' as const,
      pl: '4px',
      pr: '16px',
      ml: 'auto',
      h: '100%',
      border: 'none',
      bg: 'transparent',
      hoverBg: 'transparent',
      activeBg: 'transparent',
    }
  }, [isSubmenuOpen, themeValues.buttonVariant])

  // Helper: Render collapsed popover
  const renderPopover = () => (
    <SidemenuPopover
      isDark={isDark}
      className={className}
      buttonStyles={buttonStyles}
      isExactlyActive={isExactlyActive}
      icon={icon}
      title={title}
      isMenuExpanded={isMenuExpanded}
    >
      {children ? children : undefined}
    </SidemenuPopover>
  )

  // Helper: Render expanded button
  const renderButton = () => {
    if (level === 0 && !isMenuExpanded) {
      return (
        <Tooltip text={title} placement="right" offset={[0, -200]}>
          <Button
            className={cs('vui-sidemenu-item focusAsBorder', isExactlyActive && 'vui-sidemenu-item--active', className)}
            {...buttonStyles}
            isActive={isExactlyActive}
          >
            <SidemenuItemContent icon={icon} iconSize={buttonStyles.iconSize} />
            {isMenuExpanded && computedStates.shouldShowExpandButton && <Button {...expandButtonProps} />}{' '}
          </Button>
        </Tooltip>
      )
    }

    return (
      <Button
        className={cs('vui-sidemenu-item focusAsBorder', isExactlyActive && 'vui-sidemenu-item--active', className)}
        {...buttonStyles}
        isActive={isExactlyActive}
        title={!isMenuExpanded ? title : undefined}
      >
        <SidemenuItemContent
          icon={icon}
          iconSize={buttonStyles.iconSize}
          title={title}
          isMenuExpanded={isMenuExpanded}
          badge={props.badge}
          badgeLinkUrl={props.badgeLinkUrl}
        />
        {isMenuExpanded && computedStates.shouldShowExpandButton && <Button {...expandButtonProps} />}{' '}
        {/* Expand/Collapse button */}
      </Button>
    )
    // No leftover return, handled above
  }

  // Helper: Render expanded children
  const renderChildren = () => (
    <Box flexDirection="column" justifyContent="start" w="100%">
      {children}
    </Box>
  )

  const shouldShowPopover = Boolean(!isMenuExpanded && level === 0 && !!children)
  const shouldShowChildren = computedStates.hasChildrenExpanded

  return (
    <Box flexDirection="column" ref={ref} w="100%" mt={onBottom ? 'auto' : 0} id={computedItemId}>
      {shouldShowPopover && renderPopover()}
      {!shouldShowPopover && renderButton()}
      {shouldShowChildren && renderChildren()}
    </Box>
  )
}) as VuiComponent<'div', SidemenuItemV2Props>

SidemenuItemV2.displayName = 'SidemenuItemV2'

export default SidemenuItemV2
