import Description from '@/components/Description'
import { InputGroup, MenuItem } from '@blueprintjs/core'
import type { ItemRenderer } from '@blueprintjs/select'
import { Select } from '@blueprintjs/select'
import type { EmailParticipant } from '@inject/graphql/fragment-types'
import type { Dispatch, SetStateAction, SyntheticEvent } from 'react'
import { useCallback, type FC } from 'react'
import type { ExtendedItemRenderer } from '../typing'

type SenderSelectorProps = {
  emailContacts: EmailParticipant[]
  senderList: string[]
  senderAddress: string
} & (
  | {
      setSenderAddress: Dispatch<SetStateAction<string>>
      onItemSelect?: never
    }
  | {
      setSenderAddress?: never
      onItemSelect: (
        item: string,
        event?: SyntheticEvent<HTMLElement, Event>
      ) => void
    }
)

const SenderSelector: FC<SenderSelectorProps> = ({
  emailContacts,
  senderList,
  senderAddress,
  setSenderAddress,
  onItemSelect,
}) => {
  const itemRenderer: ExtendedItemRenderer<string> = useCallback(
    (address, { handleClick, handleFocus, modifiers, description }) => (
      <MenuItem
        active={modifiers.active}
        disabled={modifiers.disabled}
        onClick={handleClick}
        onFocus={handleFocus}
        roleStructure='listoption'
        selected={senderAddress === address}
        shouldDismissPopover={false}
        text={
          <Description description={description} hideDescription={!description}>
            {address}
          </Description>
        }
        key={address}
      />
    ),
    [senderAddress]
  )

  const tooltipRenderer: ItemRenderer<string> = useCallback(
    (address, props) => {
      const description = emailContacts.find(
        contact => contact.address === address
      )?.definitionAddress?.description

      return itemRenderer(address, { ...props, description })
    },
    [emailContacts, itemRenderer]
  )

  return (
    <Select<string>
      itemRenderer={tooltipRenderer}
      items={senderList}
      onItemSelect={onItemSelect || setSenderAddress}
      popoverProps={{
        minimal: true,
      }}
      filterable={false}
      popoverContentProps={{
        style: { maxHeight: '50vh', overflowY: 'auto', overflowX: 'hidden' },
      }}
    >
      {/* placeholder can't be used, because it doesn't update dynamically */}
      <InputGroup
        value={
          senderList.length > 0
            ? senderAddress || 'Select a sender...'
            : 'Select at least one non-team participant'
        }
        fill
        disabled={senderList.length === 0}
      />
    </Select>
  )
}

export default SenderSelector
