import React, { useState } from 'react'

import Button from '../Button/Button'
import EmptyState from '../EmptyState/EmptyState'
import Icon from '../Icons/Icon'
import { type IconStringList } from '../Icons/Icon.models'
import ListLoading from '../Loaders/ListLoading'
import SearchBar from '../SearchBar/SearchBar'
import SelectDisplay from '../Selects/SelectDisplay/SelectDisplay'
import { SideDrawer } from '../SideDrawer/SideDrawer'
import styles from './_drawer-select.module.scss'
import {
  type SelectDisplayOption,
  type SelectDisplayProps,
} from '../Selects/SelectDisplay/SelectDisplay'
import { c } from '../../translations/LibraryTranslationService'

export type DrawerSelectProps<OptionItem extends SelectDisplayOption> = {
  /** Array of options to be displayed in the SelectDisplay */
  options: SelectDisplayProps<OptionItem[]>['options']
  /** Header text for the drawer */
  header: string
  /** Function to set the active option */
  setActive: SelectDisplayProps<OptionItem[]>['callout']
  /** Placeholder text when no option is selected */
  placeholder: string
  /** Currently active option */
  active?: SelectDisplayProps<OptionItem[]>['options'][number]
  /** Optional Icon to be displayed in the button */
  buttonIcon?: IconStringList
  /** Optionally set a loading state */
  loading?: boolean
  /** Optional disabled state */
  disabled?: boolean
  /** Optional test id for the drawer select */
  qaTestId?: string
}

const DrawerSelect = <OptionItem extends SelectDisplayOption>({
  options,
  active,
  setActive,
  buttonIcon,
  header,
  placeholder,
  loading,
  disabled,
  qaTestId = 'drawer-select',
}: DrawerSelectProps<OptionItem>): React.JSX.Element => {
  const [isDrawerOpen, setIsDrawerOpen] = useState(false)
  const [search, setSearch] = useState('')

  const openDrawer = () => {
    setIsDrawerOpen(true)
  }

  const closeDrawer = () => {
    setIsDrawerOpen(false)
  }

  const filteredOptions = options.filter((option) =>
    option.label.toLowerCase().includes(search.toLowerCase()),
  )

  return (
    <>
      <Button
        onClick={openDrawer}
        className={styles.button}
        disabled={disabled}
        qaTestId={`${qaTestId}-button`}
      >
        {buttonIcon ? <Icon icon={buttonIcon} iconSize='16px' /> : null}
        {active?.label ?? placeholder}
      </Button>
      <SideDrawer
        isOpen={isDrawerOpen}
        closeCallout={closeDrawer}
        headerContent={header}
        noGradient={loading}
        qaTestId={`${qaTestId}-side-drawer`}
      >
        {({ close }) => (
          <div className={styles.drawerContainer}>
            {options.length > 10 ? (
              <div className={styles.searchBarContainer}>
                <SearchBar
                  value={search}
                  onChange={(newSearch) => {
                    setSearch(newSearch)
                  }}
                />
                <div className={styles.gradient} />
              </div>
            ) : null}
            {loading ? (
              <ListLoading longList customHeight='32px' />
            ) : filteredOptions.length > 0 ? (
              <SelectDisplay
                options={filteredOptions}
                callout={(option) => {
                  setActive(option)
                  close()
                }}
                active={active?.name}
              />
            ) : (
              <EmptyState
                primaryText={c('noResultsFound')}
                secondaryText={c('updateSearchField')}
              />
            )}
          </div>
        )}
      </SideDrawer>
    </>
  )
}

export default DrawerSelect
