import { ReactNode, useEffect, useState } from 'react'
import { IconProps } from '../Icon/index.js'
import { Menu } from '../Menu/index.js'
import { TextInput } from '../TextInput/index.js'
import { Separator } from '../Separator/index.js'
import { Dropdown } from '../Dropdown/index.js'
import { Badge } from '../Badge/index.js'

type MultiSelectInputOption = {
  value: string | number | boolean
  label: string
  labelFilterText?: string
}

type MultiSelectInputProps = {
  values?: (string | number | boolean)[]
  onChange: (values: (string | number | boolean)[]) => void
  leadIcon?: IconProps['variant']
  error?: boolean
  disabled?: boolean
  placeholder?: string
  options: MultiSelectInputOption[]
  filterable?: boolean
}

function MultiSelectInput({
  disabled,
  error,
  leadIcon,
  options,
  values,
  onChange,
  placeholder,
  filterable = false,
}: MultiSelectInputProps) {
  const [filter, setFilter] = useState<string>()

  if (!values) {
    values = []
  }

  return (
    <Menu
      onOpenChange={() => {
        setFilter('')
      }}
    >
      <Menu.Trigger>
        {({ open }) => (
          <Dropdown
            open={open}
            error={error}
            leadIcon={leadIcon}
            disabled={disabled}
            placeholder={placeholder}
            value={
              values.length > 0
                ? options
                    .filter((v) => values.includes(v.value))
                    .map((v) => (
                      <div
                        key={v.value.toString()}
                        style={{ display: 'inline-block', paddingRight: 4 }}
                      >
                        <Badge color="neutral-subtle">{v.label}</Badge>
                      </div>
                    ))
                : undefined
            }
          />
        )}
      </Menu.Trigger>
      <Menu.Items>
        {filterable && (
          <>
            <TextInput
              value={filter}
              onChange={(value) => {
                setFilter(value)
              }}
              variant="ghost"
              leadIcon="search"
              placeholder="Find..."
              size="small"
            />
            <Separator />
          </>
        )}
        {options
          .filter((option) => {
            if (filter && option.labelFilterText) {
              return option.labelFilterText
                .toLowerCase()
                .includes(filter.toLocaleLowerCase())
            }

            if (filter && typeof option.label === 'string') {
              return option.label
                .toLowerCase()
                .includes(filter.toLocaleLowerCase())
            }

            return true
          })
          .map((option) => (
            <Menu.Item
              key={option.value.toString()}
              indentContent
              leadIcon={values.includes(option.value) ? 'checkmark' : undefined}
              onClick={() => {
                if (values.includes(option.value)) {
                  onChange(values.filter((v) => v !== option.value))
                } else {
                  onChange([...values, option.value])
                }
              }}
            >
              {option.label}
            </Menu.Item>
          ))}
      </Menu.Items>
    </Menu>
  )
}

export { MultiSelectInput }
export type { MultiSelectInputProps }
