import React from 'react'
import { DeviceMenuItem, getClassName, getMergedClassNames, SelectMenuProps, StyledComponent } from '../../../common'
import { TranscriptionStatus } from '../../../../store'
import zocksStyle from './AudioControlMenu.module.scss'
import classNames from 'classnames'

export const DefaultAudioControlMenu: React.FC<SelectMenuProps<DeviceMenuItem>> = ({
  styles,
  menuItems,
  onMenuItemClick,
}) => {
  const mergedStyles = getMergedClassNames(zocksStyle, styles)
  const groupedMenuItems = getGroupedMenuItems(menuItems)
  return (
    <div className={getClassName('select-button__popover-container', mergedStyles)}>
      <ul className={getClassName('select-button__popover-list', mergedStyles)}>
        <DeviceItems
          label={'Microphone Settings'}
          menuItems={groupedMenuItems['audioinput']}
          onMenuItemClick={onMenuItemClick}
          styles={mergedStyles}
        />
        <DeviceItems
          label={'Audio Output Settings'}
          menuItems={groupedMenuItems['audiooutput']}
          onMenuItemClick={onMenuItemClick}
          styles={mergedStyles}
        />
      </ul>
    </div>
  )
}

export const TranscriptionAudioControlMenu = (
  transcriptionStatus: TranscriptionStatus,
  toggleTranscription: () => Promise<void>
): React.FC<SelectMenuProps<DeviceMenuItem>> => {
  return ({ styles, menuItems, onMenuItemClick, hideMenu }) => {
    const onTranscriptionClick = async () => {
      hideMenu()
      await toggleTranscription()
    }
    const groupedMenuItems = getGroupedMenuItems(menuItems)
    const { autoEnabled, serviceEnabled, displayTranscriptions } = transcriptionStatus
    const enableButtonText = autoEnabled ? 'Show Transcriptions' : 'Enable Transcription'
    const disableButtonText = autoEnabled ? 'Hide Transcriptions' : 'Disable Transcription'
    const showDisableButton = autoEnabled ? displayTranscriptions : serviceEnabled

    const mergedStyles = getMergedClassNames(zocksStyle, styles)

    return (
      <div className={getClassName('select-button__popover-container', mergedStyles)}>
        <ul className={getClassName('select-button__popover-list', mergedStyles)}>
          <DeviceItems
            label={'Microphone Settings'}
            systemDefaultLabel={'System Default Microphone Device'}
            menuItems={groupedMenuItems['audioinput']}
            onMenuItemClick={onMenuItemClick}
            styles={mergedStyles}
          />
          <DeviceItems
            label={'Audio Output Settings'}
            systemDefaultLabel={'System Default Speaker Device'}
            menuItems={groupedMenuItems['audiooutput']}
            onMenuItemClick={onMenuItemClick}
            styles={mergedStyles}
          />
          <li
            className={`${getClassName('select-button__popover-item', mergedStyles)} ${getClassName(
              'transcription-menu-item',
              mergedStyles
            )}`}
            onClick={onTranscriptionClick}
          >
            {showDisableButton ? (
              <>
                <i className={getClassName('icon-close', mergedStyles)} />
                {disableButtonText}
              </>
            ) : (
              <>
                <i className={getClassName('icon-message', mergedStyles)} />
                {enableButtonText}
              </>
            )}
          </li>
        </ul>
      </div>
    )
  }
}

const DeviceItems: React.FC<
  {
    label: string
    systemDefaultLabel?: string | null
    menuItems: DeviceMenuItem[]
    onMenuItemClick: (item: DeviceMenuItem | null) => void
  } & StyledComponent
> = ({ label, systemDefaultLabel, menuItems, onMenuItemClick, styles }) => {
  const mergedStyles = getMergedClassNames(zocksStyle, styles)

  return (
    <div>
      <li
        className={`${getClassName('select-button__popover-item', mergedStyles)} ${getClassName(
          'audio-control-menu-item',
          mergedStyles
        )}`}
      >
        {label}
      </li>
      {menuItems && menuItems.length > 0 ? (
        menuItems.map((item) => {
          return (
            <li
              className={classNames(getClassName('select-button__popover-item', mergedStyles), {
                [getClassName('select-button__popover-item--disabled', mergedStyles)]: item.disabled,
              })}
              key={`${item.kind}-${item.value}`}
              onClick={() => {
                if (!item.disabled) {
                  onMenuItemClick(item)
                }
              }}
            >
              {item.label}
              {item.selected ? <i className={getClassName('icon-check-mark', mergedStyles)} /> : null}
            </li>
          )
        })
      ) : (
        <>
          {!!systemDefaultLabel && (
            <li
              className={getClassName('select-button__popover-item', mergedStyles)}
              onClick={() => onMenuItemClick(null)}
            >
              {systemDefaultLabel}
              <i className={getClassName('icon-check-mark', mergedStyles)} />
            </li>
          )}
        </>
      )}
    </div>
  )
}

const getGroupedMenuItems = (menuItems: DeviceMenuItem[]) => {
  return menuItems.reduce(
    (
      prev: {
        [key: string]: DeviceMenuItem[]
      },
      current
    ) => {
      const groupedItems = { ...prev }
      const currentMenuItem = current
      if (groupedItems[currentMenuItem.kind]) {
        groupedItems[currentMenuItem.kind].push(currentMenuItem)
      } else {
        groupedItems[currentMenuItem.kind] = [currentMenuItem]
      }
      return groupedItems
    },
    {}
  )
}
