text: import React, { Component } from 'react'
  import PropTypes from 'prop-types'
  import debounce from 'lodash.debounce'
  import Fuse from 'fuse.js'
  import InputAdornment from '@material-ui/core/InputAdornment'
  
  import { Menu, Item, Divider, CloseArea } from '../dropdowns/components/menu'
  import { ENVIRONMENT_TYPE_POPUP } from '../../../../../app/scripts/lib/enums'
  import { getEnvironmentType } from '../../../../../app/scripts/lib/util'
  import Tooltip from '../../ui/tooltip'
  import Identicon from '../../ui/identicon'
  import IconWithFallBack from '../../ui/icon-with-fallback'
  import UserPreferencedCurrencyDisplay from '../user-preferenced-currency-display'
  import { PRIMARY } from '../../../helpers/constants/common'
  import {
    SETTINGS_ROUTE,
    ABOUT_US_ROUTE,
    NEW_ACCOUNT_ROUTE,
    IMPORT_ACCOUNT_ROUTE,
    CONNECT_HARDWARE_ROUTE,
    DEFAULT_ROUTE,
  } from '../../../helpers/constants/routes'
  import TextField from '../../ui/text-field'
  import SearchIcon from '../../ui/search-icon'
  
  export default class AccountMenu extends Component {
    static contextTypes = {
      t: PropTypes.func,
      metricsEvent: PropTypes.func,
    }
  
    static propTypes = {
      shouldShowAccountsSearch: PropTypes.bool,
      accounts: PropTypes.array,
      history: PropTypes.object,
      isAccountMenuOpen: PropTypes.bool,
      keyrings: PropTypes.array,
      lockMetamask: PropTypes.func,
      selectedAddress: PropTypes.string,
      showAccountDetail: PropTypes.func,
      showRemoveAccountConfirmationModal: PropTypes.func,
      toggleAccountMenu: PropTypes.func,
      addressConnectedDomainMap: PropTypes.object,
      originOfCurrentTab: PropTypes.string,
    }
  
    accountsRef;
  
    state = {
      shouldShowScrollButton: false,
      searchQuery: '',
    }
  
    addressFuse = new Fuse([], {
      shouldSort: false,
      threshold: 0.45,
      location: 0,
      distance: 100,
      maxPatternLength: 32,
      minMatchCharLength: 1,
      keys: [
        { name: 'name', weight: 0.5 },
        { name: 'address', weight: 0.5 },
      ],
    })
  
    componentDidUpdate (prevProps, prevState) {
      const { isAccountMenuOpen: prevIsAccountMenuOpen } = prevProps
      const { searchQuery: prevSearchQuery } = prevState
      const { isAccountMenuOpen } = this.props
      const { searchQuery } = this.state
  
      if (!prevIsAccountMenuOpen && isAccountMenuOpen) {
        this.setShouldShowScrollButton()
        this.resetSearchQuery()
      }
  
      // recalculate on each search query change
      // whether we can show scroll down button
      if (isAccountMenuOpen && prevSearchQuery !== searchQuery) {
        this.setShouldShowScrollButton()
      }
    }
  
    renderAccountsSearch () {
      const inputAdornment = (
        <InputAdornment
          position="start"
          style={{
            maxHeight: 'none',
            marginRight: 0,
            marginLeft: '8px',
          }}
        >
          <SearchIcon />
        </InputAdornment>
      )
  
      return [
        <TextField
          key="search-text-field"
          id="search-accounts"
          placeholder={this.context.t('searchAccounts')}
          type="text"
          value={this.state.searchQuery}
          onChange={e => this.setSearchQuery(e.target.value)}
          startAdornment={inputAdornment}
          fullWidth
          theme="material-white-padded"
        />,
        <Divider key="search-divider" />,
      ]
    }
  
    renderAccounts () {
      const {
        accounts,
        selectedAddress,
        keyrings,
        showAccountDetail,
        addressConnectedDomainMap,
        originOfCurrentTab,
      } = this.props
      const { searchQuery } = this.state
  
      let filteredIdentities = accounts
      if (searchQuery) {
        this.addressFuse.setCollection(accounts)
        filteredIdentities = this.addressFuse.search(searchQuery)
      }
  
      if (filteredIdentities.length === 0) {
        return <p className="account-menu__no-accounts">{this.context.t('noAccountsFound')}</p>
      }
  
      return filteredIdentities.map(identity => {
        const isSelected = identity.address === selectedAddress
  
        const simpleAddress = identity.address.substring(2).toLowerCase()
  
        const keyring = keyrings.find(kr => {
          return kr.accounts.includes(simpleAddress) || kr.accounts.includes(identity.address)
        })
        const addressDomains = addressConnectedDomainMap[identity.address] || {}
        const iconAndNameForOpenDomain = addressDomains[originOfCurrentTab]
  
        return (
          <div
            className="account-menu__account menu__item--clickable"
            onClick={() => {
              this.context.metricsEvent({
                eventOpts: {
                  category: 'Navigation',
                  action: 'Main Menu',
                  name: 'Switched Account',
                },
              })
              showAccountDetail(identity.address)
            }}
            key={identity.address}
          >
            <div className="account-menu__check-mark">
              { isSelected && <div className="account-menu__check-mark-icon" /> }
            </div>
            <Identicon
              address={identity.address}
              diameter={24}
            />
            <div className="account-menu__account-info">
              <div className="account-menu__name">
                { identity.name || '' }
              </div>
              <UserPreferencedCurrencyDisplay
                className="account-menu__balance"
                value={identity.balance}
                type={PRIMARY}
              />
            </div>
            { iconAndNameForOpenDomain
              ? (
                <div className="account-menu__icon-list">
                  <IconWithFallBack icon={iconAndNameForOpenDomain.icon} name={iconAndNameForOpenDomain.name} />
                </div>
              )
              : null
            }
            { this.renderKeyringType(keyring) }
            { this.renderRemoveAccount(keyring, identity) }
          </div>
        )
      })
    }
  
    renderRemoveAccount (keyring, identity) {
      const { t } = this.context
      // Any account that's not from the HD wallet Keyring can be removed
      const { type } = keyring
      const isRemovable = type !== 'HD Key Tree'
  
      return isRemovable && (
        <Tooltip
          title={t('removeAccount')}
          position="bottom"
        >
          <a
            className="remove-account-icon"
            onClick={e => this.removeAccount(e, identity)}
          />
        </Tooltip>
      )
    }
  
    removeAccount (e, identity) {
      e.preventDefault()
      e.stopPropagation()
      const { showRemoveAccountConfirmationModal } = this.props
      showRemoveAccountConfirmationModal(identity)
    }
  
    renderKeyringType (keyring) {
      const { t } = this.context
  
      // Sometimes keyrings aren't loaded yet
      if (!keyring) {
        return null
      }
  
      const { type } = keyring
      let label
  
      switch (type) {
        case 'Trezor Hardware':
        case 'Ledger Hardware':
          label = t('hardware')
          break
        case 'Simple Key Pair':
          label = t('imported')
          break
        default:
          return null
      }
  
      return (
        <div className="keyring-label allcaps">
          { label }
        </div>
      )
    }
  
    resetSearchQuery () {
      this.setSearchQuery('')
    }
  
    setSearchQuery (searchQuery) {
      this.setState({ searchQuery })
    }
  
    setShouldShowScrollButton = () => {
      const { scrollTop, offsetHeight, scrollHeight } = this.accountsRef
  
      const canScroll = scrollHeight > offsetHeight
  
      const atAccountListBottom = scrollTop + offsetHeight >= scrollHeight
  
      const shouldShowScrollButton = canScroll && !atAccountListBottom
  
      this.setState({ shouldShowScrollButton })
    }
  
    onScroll = debounce(this.setShouldShowScrollButton, 25)
  
    handleScrollDown = e => {
      e.stopPropagation()
  
      const { scrollHeight } = this.accountsRef
      this.accountsRef.scroll({ left: 0, top: scrollHeight, behavior: 'smooth' })
  
      this.setShouldShowScrollButton()
    }
  
    renderScrollButton () {
      const { shouldShowScrollButton } = this.state
  
      return shouldShowScrollButton && (
        <div
          className="account-menu__scroll-button"
          onClick={this.handleScrollDown}
        >
          <img
            src="./images/icons/down-arrow.svg"
            width={28}
            height={28}
            alt="scroll down"
          />
        </div>
      )
    }
  
    render () {
      const { t, metricsEvent } = this.context
      const {
        shouldShowAccountsSearch,
        isAccountMenuOpen,
        toggleAccountMenu,
        lockMetamask,
        history,
      } = this.props
  
      return (
        <Menu
          className="account-menu"
          isShowing={isAccountMenuOpen}
        >
          <CloseArea onClick={toggleAccountMenu} />
          <Item className="account-menu__header">
            { t('myAccounts') }
            <button
              className="account-menu__logout-button"
              onClick={() => {
                lockMetamask()
                history.push(DEFAULT_ROUTE)
              }}
            >
              { t('logout') }
            </button>
          </Item>
          <Divider />
          <div className="account-menu__accounts-container">
            {shouldShowAccountsSearch ? this.renderAccountsSearch() : null}
            <div
              className="account-menu__accounts"
              onScroll={this.onScroll}
              ref={ref => {
                this.accountsRef = ref
              }}
            >
              { this.renderAccounts() }
            </div>
            { this.renderScrollButton() }
          </div>
          <Divider />
          <Item
            onClick={() => {
              toggleAccountMenu()
              metricsEvent({
                eventOpts: {
                  category: 'Navigation',
                  action: 'Main Menu',
                  name: 'Clicked Create Account',
                },
              })
              history.push(NEW_ACCOUNT_ROUTE)
            }}
            icon={(
              <img
                className="account-menu__item-icon"
                src="images/plus-btn-white.svg"
              />
            )}
            text={t('createAccount')}
          />
          <Item
            onClick={() => {
              toggleAccountMenu()
              metricsEvent({
                eventOpts: {
                  category: 'Navigation',
                  action: 'Main Menu',
                  name: 'Clicked Import Account',
                },
              })
              history.push(IMPORT_ACCOUNT_ROUTE)
            }}
            icon={(
              <img
                className="account-menu__item-icon"
                src="images/import-account.svg"
              />
            )}
            text={t('importAccount')}
          />
          <Item
            onClick={() => {
              toggleAccountMenu()
              metricsEvent({
                eventOpts: {
                  category: 'Navigation',
                  action: 'Main Menu',
                  name: 'Clicked Connect Hardware',
                },
              })
              if (getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_POPUP) {
                global.platform.openExtensionInBrowser(CONNECT_HARDWARE_ROUTE)
              } else {
                history.push(CONNECT_HARDWARE_ROUTE)
              }
            }}
            icon={(
              <img
                className="account-menu__item-icon"
                src="images/connect-icon.svg"
              />
            )}
            text={t('connectHardwareWallet')}
          />
          <Divider />
          <Item
            onClick={() => {
              toggleAccountMenu()
              history.push(ABOUT_US_ROUTE)
            }}
            icon={
              <img src="images/mm-info-icon.svg" />
            }
            text={t('infoHelp')}
          />
          <Item
            onClick={() => {
              toggleAccountMenu()
              history.push(SETTINGS_ROUTE)
              this.context.metricsEvent({
                eventOpts: {
                  category: 'Navigation',
                  action: 'Main Menu',
                  name: 'Opened Settings',
                },
              })
            }}
            icon={(
              <img
                className="account-menu__item-icon"
                src="images/settings.svg"
              />
            )}
            text={t('settings')}
          />
        </Menu>
      )
    }
  }
  