import {Box, ButtonProps, Flex, Text} from '@sanity/ui'
import React, {createElement, isValidElement, useId} from 'react'
import {isValidElementType} from 'react-is'

import {FileButton} from './FileInputMenuItem.styled'

export interface FileInputMenuItemProps extends ButtonProps {
  accept?: string
  capture?: 'user' | 'environment'
  multiple?: boolean
  onSelect?: (files: File[]) => void
  disabled?: boolean
}

export const FileInputMenuItem = React.forwardRef(function FileInputMenuItem(
  props: FileInputMenuItemProps &
    Omit<React.HTMLProps<HTMLButtonElement>, 'as' | 'ref' | 'type' | 'value' | 'onSelect'>,
  forwardedRef: React.ForwardedRef<HTMLInputElement>
) {
  const {
    icon,
    id: idProp,
    accept,
    capture,
    fontSize,
    multiple,
    onSelect,
    space = 3,
    textAlign,
    text,
    disabled,
    ...rest
  } = props
  const idHook = useId()
  const id = idProp || idHook

  const handleChange = React.useCallback(
    (event: React.ChangeEvent<HTMLInputElement>) => {
      if (onSelect && event.target.files) {
        onSelect(Array.from(event.target.files))
      }
    },
    [onSelect]
  )

  const content = (
    <Flex align="center" justify="flex-start">
      {/* Icon */}
      {icon && (
        <Box marginRight={text ? space : undefined}>
          <Text size={fontSize}>
            {isValidElement(icon) && icon}
            {isValidElementType(icon) && createElement(icon)}
          </Text>
        </Box>
      )}

      {/* Text */}
      {text && (
        <Text align={textAlign} size={fontSize} textOverflow="ellipsis">
          {text}
        </Text>
      )}
    </Flex>
  )

  return (
    <FileButton {...rest} htmlFor={id} disabled={disabled} ref={forwardedRef}>
      {content}

      {/* Visibly hidden input */}
      <input
        data-testid="file-button-input"
        accept={accept}
        capture={capture}
        id={id}
        multiple={multiple}
        onChange={handleChange}
        type="file"
        value=""
        disabled={disabled}
      />
    </FileButton>
  )
})
