import React, { MouseEvent, useEffect } from 'react'

import Box from '../box'
import Button from '../button'
import { omitThemingProps, vui, VuiComponent } from '../core'
import Icon from '../icon'
import { Popover } from '../popover'
import T from '../t'
import { cs } from '../utils'
import { SidemenuItemProps } from './sidemenu.types'
import useSidemenuItem from './useSidemenuItem'

/** A menu item. */
export const SidemenuItem = vui<'button', SidemenuItemProps>((props, ref) => {
  const {
    className,
    children,
    icon,
    iconSize = 'md',
    isActive,
    isExpanded = true,
    onClick,
    onCollapse,
    onExpand,
    title,
    ...rest
  } = omitThemingProps(props)

  const { isExpandedVertically, setIsExpandedVertically, isDark, size, isExpandedHorizontally, styles } =
    useSidemenuItem(isExpanded)

  useEffect(() => {
    if (isExpandedVertically) onExpand?.()
    if (!isExpandedVertically) onCollapse?.()
  }, [isExpandedVertically])

  const hasChildrenExpanded = !!children && isExpandedHorizontally

  const innerContent = (
    <Box centerV px={2} py={1} w="100%" whiteSpace="pre">
      <Icon ml={iconSize === 'sm' ? '4px' : 0} name={icon} size={iconSize} />
      <T isTruncated ml={2}>
        {title}
      </T>
    </Box>
  )

  const toggle = (e: MouseEvent<HTMLButtonElement>) => {
    e.preventDefault()
    e.stopPropagation()
    setIsExpandedVertically(!isExpandedVertically)
  }

  const buttonStyles = {
    alignItems: 'center',
    border: 'none',
    borderRadius: 0,
    borderLeft: !hasChildrenExpanded && children ? 'none' : '3px solid transparent',
    borderLeftColor: isActive ? (isDark ? 'digiGreen.main' : 'seaBlue.main') : undefined,
    bg: isDark ? 'darkBlue.main' : isActive ? 'skyBlue.95' : 'white',
    color: hasChildrenExpanded ? 'seaBlue.main' : isDark ? 'digiGreen.main' : 'sandstone.10',
    h: 'auto',
    justifyContent: 'space-between',
    onClick: () => onClick?.(),
    p: 0,
    size: 'md',
    variant: isDark ? 'tertiaryLight' : 'tertiaryDark',
    w: '100%',
    ...styles.item,
    minH: size === 'lg' ? '56px' : '40px',
    hoverBg: isDark ? 'seaBlue.main' : 'skyBlue.90',
    ...rest,
  }

  return (
    <Box flexDirection="column" ref={ref} w="100%">
      {!hasChildrenExpanded && children ? (
        <Popover offset={[0, 0]} placement="right-start" trigger="mouseenter">
          <Popover.Trigger as={Box} className={cs('vui-sidemenu-item-popover', className)}>
            <Box {...buttonStyles} borderLeft={`3px solid ${isDark ? 'digiGreen.main' : 'seaBlue.main'}`}>
              {innerContent}
            </Box>
          </Popover.Trigger>
          <Popover.Content shadow="none">
            <Box flexDirection="column" justifyContent="start" w="100%">
              {children}
            </Box>
          </Popover.Content>
        </Popover>
      ) : (
        <Button className={cs('vui-sidemenu-item', className)} {...buttonStyles}>
          {innerContent}
          {hasChildrenExpanded && (
            <Button
              aria-label={isExpandedVertically ? 'Collapse' : 'Expand'}
              className="vui-sidemenu-item-expand"
              icon={isExpandedVertically ? 'falChevronUp' : 'falChevronDown'}
              mr={1}
              onClick={toggle}
              size="sm"
              variant={isDark ? 'tertiaryLight' : 'tertiaryDark'}
            />
          )}
        </Button>
      )}
      {!!children && hasChildrenExpanded && isExpandedVertically && (
        <Box flexDirection="column" justifyContent="start" w="100%">
          {children}
        </Box>
      )}
    </Box>
  )
}) as VuiComponent<'div', SidemenuItemProps>

SidemenuItem.displayName = 'SidemenuItem'

export default SidemenuItem
