import React, { ComponentType, useState } from 'react'
import classNames from 'classnames'
import { Popover } from 'react-tiny-popover'
import { MenuItem, SelectMenuProps, StyledComponent } from './models'
import { getClassName, getMergedClassNames } from './utils'
import zocksStyle from './SelectButton.module.scss'

export const SelectButton: React.FC<
  {
    menuItems: MenuItem[]
    onMenuItemSelected?: (item: MenuItem) => void
    disabled?: boolean
    buttonLabel?: string
    SelectMenu?: ComponentType<SelectMenuProps>
  } & StyledComponent
> = ({ styles, menuItems, onMenuItemSelected, disabled, buttonLabel, SelectMenu }) => {
  const [popoverVisible, setPopoverVisible] = useState(false)

  const hideMenu = () => {
    setPopoverVisible(false)
  }

  const handleMenuItemClick = (item: MenuItem) => {
    hideMenu()
    onMenuItemSelected && onMenuItemSelected(item)
  }

  const SelectMenuElement = SelectMenu ?? DefaultSelectMenu
  const mergedStyles = getMergedClassNames(zocksStyle, styles)

  return (
    <div className={getClassName('select-button-container', mergedStyles)}>
      <Popover
        isOpen={popoverVisible}
        positions={['top']}
        content={
          <SelectMenuElement
            menuItems={menuItems}
            onMenuItemClick={handleMenuItemClick}
            hideMenu={hideMenu}
            styles={mergedStyles}
          />
        }
        onClickOutside={() => setPopoverVisible(false)}
      >
        <div
          className={classNames(getClassName('select-button__button-container', mergedStyles), {
            disabled: disabled,
          })}
        >
          <button
            disabled={disabled}
            className={getClassName('select-button__button', mergedStyles)}
            onClick={() => setPopoverVisible(!popoverVisible)}
            aria-label={buttonLabel}
          >
            <div className={getClassName('select-button__button-icon', mergedStyles)} />
          </button>
        </div>
      </Popover>
    </div>
  )
}

const DefaultSelectMenu: React.FC<SelectMenuProps> = ({ menuItems, onMenuItemClick, styles }) => {
  const mergedStyles = getMergedClassNames(zocksStyle, styles)
  return (
    <div className={getClassName('select-button__popover-container', mergedStyles)}>
      <ul className={getClassName('select-button__popover-list', mergedStyles)}>
        {menuItems?.map((item, i) => {
          return (
            <li
              className={getClassName('select-button__popover-item', mergedStyles)}
              key={i}
              onClick={() => onMenuItemClick(item)}
            >
              {item.label}
              {item.selected ? <i className={getClassName('icon-check-mark', mergedStyles)} /> : null}
            </li>
          )
        })}
      </ul>
    </div>
  )
}
