var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
    if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
    return cooked;
};
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
var _a;
import { Ban, Image } from '@procore/core-icons/dist';
import { equals, omit } from 'ramda';
import React from 'react';
import styled from 'styled-components';
import { useResizeObserver } from '../../effects/ResizeObserver';
import { useFocusWithin } from '../../effects/useFocusWithin';
import { useI18nContext } from '../../state/I18n';
import { Banner } from '../Banner';
import { Button } from '../Button';
import { Tooltip } from '../Tooltip';
import { Typography } from '../Typography/Typography';
import { StyledDropzoneCaption, StyledDropzoneContainer, StyledDropzoneFocusDetector, StyledDropzoneIcon, StyledDropzoneMessage, StyledDropzoneWrapper, StyledErrorBanner, StyledErrorBannerDetails, StyledUploadButton, } from './Dropzone.styles';
import { dropErrors, fileRejectionReason, } from './Dropzone.types';
var extendedViewHeightBreakpoint = 172;
var DropzoneErrorBannerBase = React.forwardRef(function (_a, ref) {
    var error = _a.error, onDismiss = _a.onDismiss, qa = _a.qa, props = __rest(_a, ["error", "onDismiss", "qa"]);
    var I18n = useI18nContext();
    var _b = React.useState(false), isExpanded = _b[0], setExpanded = _b[1];
    React.useEffect(function () {
        setExpanded(false);
    }, [error.title, error.body, error.message]);
    if (error.type === dropErrors.reset) {
        return null;
    }
    return (React.createElement(StyledErrorBanner, __assign({}, props, { ref: ref }),
        React.createElement(Banner.Content, null,
            React.createElement(Banner.Title, null, error.title),
            React.createElement(Banner.Body, null, error.message)),
        error.body ? (React.createElement(Banner.Action, null,
            React.createElement(Button, { "data-qa": qa === null || qa === void 0 ? void 0 : qa.showErrorDetails, onClick: function () { return setExpanded(function (prev) { return !prev; }); } }, isExpanded
                ? I18n.t('core.dropzone.hideDetails')
                : I18n.t('core.dropzone.showDetails')))) : null,
        React.createElement(Banner.Dismiss, { onClick: onDismiss, "data-qa": qa === null || qa === void 0 ? void 0 : qa.hideError }),
        error.body ? (React.createElement(Banner.ExpandableContent, { expanded: isExpanded }, error.body)) : null));
});
export function MultipleErrors(props) {
    var _a, _b;
    var I18n = useI18nContext();
    var filesByErrorType = props.fileRejections.reduce(function (acc, rejection) {
        rejection.errors.forEach(function (error) {
            var dropErrorType = dropErrorsByReason[error.code];
            acc[dropErrorType].push(rejection.file);
        });
        return acc;
    }, (_a = {},
        _a[dropErrors.fileAmount] = [],
        _a[dropErrors.minFileSize] = [],
        _a[dropErrors.maxFileSize] = [],
        _a[dropErrors.fileType] = [],
        _a[dropErrors.oneFileAtATime] = [],
        _a[dropErrors.reset] = [],
        _a[dropErrors.multipleErrors] = [],
        _a));
    var messages = (_b = {},
        _b[dropErrors.fileAmount] = I18n.t('core.dropzone.maxFileNumberErrorGroup', {
            count: props.maxFiles,
        }),
        _b[dropErrors.minFileSize] = I18n.t('core.dropzone.minFileSizeErrorGroup', {
            sizeInMegabytes: getSizeInMB(props.minSize),
        }),
        _b[dropErrors.maxFileSize] = I18n.t('core.dropzone.maxFileSizeErrorGroup', {
            sizeInMegabytes: getSizeInMB(props.maxSize),
        }),
        _b[dropErrors.fileType] = I18n.t('core.dropzone.wrongFileTypeErrorGroup'),
        _b[dropErrors.reset] = '',
        _b[dropErrors.multipleErrors] = '',
        _b[dropErrors.oneFileAtATime] = '',
        _b);
    return (React.createElement("div", null, [
        dropErrors.fileAmount,
        dropErrors.fileType,
        dropErrors.maxFileSize,
        dropErrors.minFileSize,
    ].map(function (errorType) {
        var files = filesByErrorType[errorType];
        return files.length ? (React.createElement("div", { key: errorType },
            React.createElement(Typography, { weight: "bold" }, messages[errorType]),
            React.createElement(StyledErrorBannerDetails, null, filesByErrorType[errorType].map(function (_a) {
                var name = _a.name;
                return (React.createElement("li", { key: name }, name));
            })))) : null;
    })));
}
// make error banner accessible as a styled-components selector
export var DropzoneErrorBanner = styled(DropzoneErrorBannerBase)(templateObject_1 || (templateObject_1 = __makeTemplateObject([""], [""])));
function DropzoneContainer(_a) {
    var active = _a.active, disabled = _a.disabled, getRootProps = _a.getRootProps, rootProps = _a.rootProps, children = _a.children;
    return (React.createElement(StyledDropzoneContainer, __assign({}, getRootProps(rootProps), { active: active, disabled: disabled }), children));
}
function DropzoneContent(_a) {
    var disabled = _a.disabled, isIconVisible = _a.isIconVisible, contentMessage = _a.contentMessage;
    return (React.createElement(StyledDropzoneMessage, null,
        isIconVisible && (React.createElement(StyledDropzoneIcon, { disabled: disabled }, disabled ? React.createElement(Ban, null) : React.createElement(Image, null))),
        contentMessage));
}
export function DefaultMessage(_a) {
    var open = _a.open, disabled = _a.disabled, multiple = _a.multiple, errorMessage = _a.errorMessage;
    var I18n = useI18nContext();
    return (React.createElement(React.Fragment, null,
        React.createElement(StyledUploadButton, { variant: "secondary", onClick: open, disabled: disabled }, I18n.t('core.dropzone.uploadFiles', {
            count: multiple ? Infinity : 1,
        })),
        React.createElement(StyledDropzoneCaption, { error: !!errorMessage }, errorMessage || I18n.t('core.dropzone.dragAndDrop'))));
}
var dropErrorsByReason = (_a = {},
    _a[fileRejectionReason.maxFiles] = dropErrors.fileAmount,
    _a[fileRejectionReason.maxFileSize] = dropErrors.maxFileSize,
    _a[fileRejectionReason.minFileSize] = dropErrors.minFileSize,
    _a[fileRejectionReason.fileType] = dropErrors.fileType,
    _a);
var getSizeInMB = function (maxSize) { return maxSize / 10e5; };
/**

 Dropzones allow users to quickly upload files from their computers, as well
 as optionally launch the file select component.

 @since 10.19.0

 @see [Storybook](https://procore.github.io/core/latest/?path=/story/demos-dropzone--demo)

 @see [Design Guidelines](https://design.procore.com/dropzone)

 */
var Dropzone_ = React.forwardRef(function Dropzone(_a, ref) {
    var forceIconVisibility = _a.isIconVisible, contentRenderer = _a.contentRenderer, disabled = _a.disabled, tooltip = _a.tooltip, rootRef = _a.rootRef, inputRef = _a.inputRef, dragError = _a.dragError, dropError = _a.dropError, dispatchDropError = _a.dispatchDropError, getRootProps = _a.getRootProps, getInputProps = _a.getInputProps, isDragActive = _a.isDragActive, multiple = _a.multiple, fileRejections = _a.fileRejections, open = _a.open, _b = _a.rootProps, rootProps = _b === void 0 ? {} : _b, _c = _a.inputProps, inputProps = _c === void 0 ? {} : _c, className = _a.className, qa = _a.qa;
    var _d = React.useState(false), isIconVisible = _d[0], setIsIconVisible = _d[1];
    var _e = useFocusWithin(), isFocusWithin = _e.isFocusWithin, containerProps = _e.containerProps;
    var toggleIconVisibility = React.useCallback(function (entries) {
        var height = entries[0].target.offsetHeight;
        setIsIconVisible(height >= extendedViewHeightBreakpoint);
    }, [setIsIconVisible]);
    var setResizeObserverTarget = useResizeObserver(toggleIconVisibility);
    React.useEffect(function () {
        setResizeObserverTarget(rootRef.current);
    }, [rootRef, setResizeObserverTarget]);
    React.useImperativeHandle(ref, function () { return ({
        rootRef: rootRef,
        inputRef: inputRef,
        open: open,
    }); });
    var isDropzoneDisabled = disabled || Boolean(dragError);
    var contentMessage = React.useMemo(function () {
        return contentRenderer ? (contentRenderer({
            open: open,
            disabled: isDropzoneDisabled,
            errorMessage: dragError,
        })) : (React.createElement(DefaultMessage, { open: open, disabled: isDropzoneDisabled, errorMessage: dragError, multiple: multiple }));
    }, [contentRenderer, open, isDropzoneDisabled, dragError, multiple]);
    var validRootProps = React.useMemo(function () { return omit(['disabled'], rootProps); }, [rootProps]);
    var validInputProps = React.useMemo(function () { return omit(['accept', 'multiple', 'type'], inputProps); }, [inputProps]);
    return (React.createElement(StyledDropzoneWrapper, { direction: "column", alignItems: "stretch", className: className },
        React.createElement(Tooltip, { trigger: Boolean(tooltip) ? 'hover' : 'none', overlay: tooltip || '' },
            React.createElement(StyledDropzoneFocusDetector, __assign({}, containerProps),
                React.createElement(DropzoneContainer, { rootProps: validRootProps, active: isDragActive || isFocusWithin, disabled: isDropzoneDisabled, getRootProps: getRootProps },
                    React.createElement("input", __assign({ type: "file" }, getInputProps(validInputProps))),
                    React.createElement(DropzoneContent, { disabled: isDropzoneDisabled, isIconVisible: typeof forceIconVisibility === 'undefined'
                            ? isIconVisible
                            : forceIconVisibility, contentMessage: contentMessage })))),
        React.createElement(DropzoneErrorBanner, { qa: qa, error: dropError, fileRejections: fileRejections, onDismiss: function () { return dispatchDropError(dropErrors.reset); } })));
});
DropzoneContainer.displayName = 'DropzoneContainer';
DropzoneContent.displayName = 'DropzoneContent';
Dropzone_.displayName = 'Dropzone';
export var Dropzone = React.memo(Dropzone_, equals);
var templateObject_1;
//# sourceMappingURL=Dropzone.js.map