import { Upload, PlusCircle } from '@transferwise/icons';
import { clsx } from 'clsx';
import { forwardRef, useRef, useImperativeHandle, useState } from 'react';
import { useIntl } from 'react-intl';
import Body from '../../body/Body.mjs';
import MESSAGES from './UploadButton.messages.mjs';
import { imageFileTypes, DEFAULT_SIZE_LIMIT } from './defaults.mjs';
import getAllowedFileTypes from './getAllowedFileTypes.mjs';
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
import { Typography } from '../../common/propsValues/typography.mjs';

var TEST_IDS;
(function (TEST_IDS) {
  TEST_IDS["uploadInput"] = "uploadInput";
  TEST_IDS["mediaBody"] = "mediaBody";
})(TEST_IDS || (TEST_IDS = {}));
const onDragOver = event => {
  event.preventDefault();
};
const DEFAULT_FILE_INPUT_ID = 'np-upload-button';
const UploadButton = /*#__PURE__*/forwardRef(({
  disabled,
  withEntries,
  multiple,
  description,
  fileTypes = imageFileTypes,
  sizeLimit = DEFAULT_SIZE_LIMIT,
  maxFiles,
  onChange,
  id = DEFAULT_FILE_INPUT_ID,
  uploadButtonTitle
}, ref) => {
  const {
    formatMessage
  } = useIntl();
  const inputRef = useRef(null);
  useImperativeHandle(ref, () => {
    if (!inputRef.current) {
      throw new Error('inputRef.current is null');
    }
    return inputRef.current;
  }, []);
  const [isDropping, setIsDropping] = useState(false);
  const dragCounter = useRef(0);
  const reset = () => {
    dragCounter.current = 0;
    setIsDropping(false);
  };
  const onDragLeave = event => {
    event.preventDefault();
    dragCounter.current -= 1;
    if (dragCounter.current === 0) {
      setIsDropping(false);
    }
  };
  const onDragEnter = event => {
    event.preventDefault();
    dragCounter.current += 1;
    if (dragCounter.current === 1) {
      setIsDropping(true);
    }
  };
  const onDrop = event => {
    event.preventDefault();
    reset();
    if (event.dataTransfer && event.dataTransfer.files && event.dataTransfer.files[0]) {
      onChange(event.dataTransfer.files);
    }
  };
  const filesSelected = event => {
    const {
      files
    } = event.target;
    if (files) {
      onChange(files);
      if (inputRef.current) {
        inputRef.current.value = '';
      }
    }
  };
  const getFileTypesDescription = () => {
    if (fileTypes === '*') {
      return fileTypes;
    }
    return getAllowedFileTypes(Array.isArray(fileTypes) ? fileTypes : [fileTypes]).join(', ');
  };
  function getDescription() {
    if (description) {
      return description;
    }
    const fileTypesDescription = getFileTypesDescription();
    const derivedFileDescription = fileTypesDescription === '*' ? formatMessage(MESSAGES.allFileTypes) : fileTypesDescription;
    return formatMessage(MESSAGES.instructions, {
      fileTypes: derivedFileDescription,
      size: Math.round(sizeLimit / 1000)
    });
  }
  function getAcceptedTypes() {
    const areAllFilesAllowed = getFileTypesDescription() === '*';
    if (areAllFilesAllowed) {
      return {}; // file input by default allows all files
    }
    if (Array.isArray(fileTypes)) {
      return {
        accept: fileTypes.join(',')
      };
    }
    return {
      accept: fileTypes
    };
  }
  function renderDescription() {
    return /*#__PURE__*/jsxs(Body, {
      className: "np-upload-input__text",
      children: [getDescription(), maxFiles && /*#__PURE__*/jsxs(Fragment, {
        children: [/*#__PURE__*/jsx("br", {}), `Maximum ${maxFiles} files.`]
      })]
    });
  }
  function renderButtonTitle() {
    if (uploadButtonTitle) {
      return uploadButtonTitle;
    }
    return formatMessage(multiple ? MESSAGES.uploadFiles : MESSAGES.uploadFile);
  }
  return /*#__PURE__*/jsxs("label", {
    className: clsx('np-upload-input__upload-button', `np-upload-input__upload-button--${disabled ? 'disabled' : 'enabled'}`, `np-upload-input__upload-button--${withEntries ? 'with-entries' : 'without-entries'}`, {
      'is-dropping': isDropping
    }),
    htmlFor: id,
    ...(!disabled && {
      onDragEnter,
      onDragLeave,
      onDrop,
      onDragOver
    }),
    children: [/*#__PURE__*/jsx("span", {
      className: "np-upload-input__icon",
      children: /*#__PURE__*/jsx(Upload, {
        size: 24,
        className: "text-link"
      })
    }), /*#__PURE__*/jsxs("div", {
      className: "np-upload-input__item-content",
      "data-testid": TEST_IDS.mediaBody,
      children: [/*#__PURE__*/jsx(Body, {
        type: Typography.BODY_LARGE_BOLD,
        className: "np-upload-input__title",
        children: renderButtonTitle()
      }), renderDescription()]
    }), /*#__PURE__*/jsx("input", {
      className: "np-upload-input__upload-button-input sr-only",
      type: "file",
      id: id,
      ...getAcceptedTypes(),
      ...(multiple && {
        multiple: true
      }),
      ref: inputRef,
      disabled: disabled,
      name: "file-upload",
      "data-testid": TEST_IDS.uploadInput,
      onChange: filesSelected
    }), isDropping && /*#__PURE__*/jsxs("div", {
      className: clsx('np-upload-input__drop-file-overlay', 'droppable-card', 'droppable-dropping-card', 'droppable-card-content'),
      children: [/*#__PURE__*/jsx(PlusCircle, {
        className: "m-x-1",
        size: 24
      }), /*#__PURE__*/jsx("div", {
        children: formatMessage(MESSAGES.dropFile)
      })]
    })]
  });
});
UploadButton.displayName = 'UploadButton';

export { TEST_IDS, UploadButton as default };
//# sourceMappingURL=UploadButton.mjs.map
