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;
};
import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
import { useEmotion, useGlobal, useStyles } from '../../lib/renderEnvironment/index.js';
import { CommonWrapper } from '../../internal/CommonWrapper/index.js';
import { forwardRefAndName } from '../../lib/forwardRefAndName.js';
import { formatBytes } from '../../lib/utils.js';
import { TextWidthHelper } from '../../internal/TextWidthHelper/TextWidthHelper.js';
import { truncate } from '../../lib/stringUtils.js';
import { ThemeContext } from '../../lib/theming/ThemeContext.js';
import { useKeyListener } from '../../lib/events/keyListener.js';
import { isKeyEnter } from '../../lib/events/keyboard/identifiers.js';
import { Hint } from '../Hint/index.js';
import { Tooltip } from '../Tooltip/index.js';
import { getDOMRect } from '../../lib/dom/getDOMRect.js';
import { LoadingIcon } from '../../internal/icons2022/LoadingIcon.js';
import { useFileUploaderSize } from './hooks/useFileUploaderSize.js';
import { FileUploaderFileStatus, getFileUploaderTypeIcon } from './fileUtils.js';
import { FileUploaderFileStatusIcon } from './FileUploaderFileStatusIcon.js';
import { FileUploaderFileTypeIcon } from './FileUploaderFileTypeIcon.js';
import { getJsRowStyles, getJsStyles, getJsTileStyles } from './FileUploaderFile.styles.js';
var splitFileNameAndExtension = function (filename) {
    var lastDotIndex = filename.lastIndexOf('.');
    if (lastDotIndex === -1) {
        return { name: filename, extension: '' };
    }
    var name = filename.substring(0, lastDotIndex);
    var extension = filename.substring(lastDotIndex + 1);
    return { name: name, extension: extension };
};
var getTruncatedName = function (fileNameWidth, fileNameElementWidth, name, isTileView) {
    if (isTileView === void 0) { isTileView = false; }
    if (!fileNameWidth && !fileNameElementWidth) {
        return null;
    }
    if (fileNameWidth <= fileNameElementWidth) {
        return name;
    }
    var charWidth = Math.ceil(fileNameWidth / name.length);
    var maxCharsCountInSpan = Math.ceil(fileNameElementWidth / charWidth);
    if (isTileView) {
        var splitFileName = splitFileNameAndExtension(name);
        return "".concat(truncate(splitFileName.name, maxCharsCountInSpan), ".").concat(splitFileName.extension);
    }
    return truncate(name, maxCharsCountInSpan);
};
var calcTruncatedName = function (textHelperRef, fileNameElementRef, name, isTileView) {
    var _a;
    if (isTileView === void 0) { isTileView = false; }
    var fileNameWidth = ((_a = textHelperRef.current) === null || _a === void 0 ? void 0 : _a.getTextWidth()) || 0;
    var fileNameElementWidth = isTileView
        ? // даем возможность занять 2 строки с погрешностью в 50%
            getDOMRect(fileNameElementRef.current).width * 1.5
        : getDOMRect(fileNameElementRef.current).width;
    return getTruncatedName(fileNameWidth, fileNameElementWidth, name, isTileView);
};
export var FileUploaderFileDataTids = {
    file: 'FileUploader__file',
    fileTooltip: 'FileUploader__fileTooltip',
    fileName: 'FileUploader__fileName',
    fileSize: 'FileUploader__fileSize',
    fileIcon: 'FileUploader__fileIcon',
    fileTypeIcon: 'FileUploader__fileTypeIcon',
};
/**
 * Компонент файла `FileUploaderFile` из FileUploader для отрисовки загруженного файла.
 */
export var FileUploaderFile = forwardRefAndName('FileUploaderFile', function (props, ref) {
    var _a, _b, _c;
    var file = props.file, _d = props.showSize, showSize = _d === void 0 ? false : _d, previewImg = props.previewImg, error = props.error, warning = props.warning, multiple = props.multiple, _e = props.disabled, disabled = _e === void 0 ? false : _e, _f = props.hovered, hovered = _f === void 0 ? false : _f, _g = props.focused, focused = _g === void 0 ? false : _g, size = props.size, _h = props.view, view = _h === void 0 ? 'row' : _h, withValidationTooltip = props.withValidationTooltip, validationTooltipPosition = props.validationTooltipPosition, withWarningIcon = props.withWarningIcon, onRemove = props.onRemove, _j = props.showFilenameHint, showFullFilename = _j === void 0 ? true : _j, fileTypeIcon = props.fileTypeIcon, rest = __rest(props, ["file", "showSize", "previewImg", "error", "warning", "multiple", "disabled", "hovered", "focused", "size", "view", "withValidationTooltip", "validationTooltipPosition", "withWarningIcon", "onRemove", "showFilenameHint", "fileTypeIcon"]);
    var id = file.id, originalFile = file.originalFile, status = file.status, validationResult = file.validationResult;
    var name = originalFile.name, fileSize = originalFile.size;
    var _k = useState(hovered || false), hoveredFile = _k[0], setHoveredFile = _k[1];
    var _l = useState(focused || false), focusedByTab = _l[0], setFocusedByTab = _l[1];
    var _m = useState(null), truncatedFileName = _m[0], setTruncatedFileName = _m[1];
    var textHelperRef = useRef(null);
    var fileNameElementRef = useRef(null);
    var theme = useContext(ThemeContext);
    var globalObject = useGlobal();
    var cx = useEmotion().cx;
    var keyListener = useKeyListener();
    var jsStyles = useStyles(getJsStyles);
    var jsRowStyles = useStyles(getJsRowStyles);
    var jsTileStyles = useStyles(getJsTileStyles);
    var isLoading = status === FileUploaderFileStatus.Loading;
    var isTileView = view === 'tile';
    var jsViewStyles = isTileView ? jsTileStyles : jsRowStyles;
    var validationTooltipPositionByView = validationTooltipPosition || (isTileView ? 'top center' : 'top left');
    var formattedSize = useMemo(function () { return formatBytes(fileSize, 1); }, [fileSize]);
    useEffect(function () {
        var truncatedName = calcTruncatedName(textHelperRef, fileNameElementRef, name, isTileView);
        setTruncatedFileName(truncatedName);
    });
    var handleRemove = useCallback(function (event) {
        event.preventDefault();
        event.stopPropagation();
        onRemove(id);
    }, [id, onRemove]);
    var isValid = validationResult.isValid, message = validationResult.message;
    var isError = file.status === FileUploaderFileStatus.Error || error;
    var isWarning = file.status === FileUploaderFileStatus.Warning || warning;
    var isInvalid = isError || !isValid;
    var sizeIconClass = useFileUploaderSize(size, {
        small: jsViewStyles.iconSmall(theme),
        medium: jsViewStyles.iconMedium(theme),
        large: jsViewStyles.iconLarge(theme),
    });
    var renderTooltipContent = useCallback(function () {
        return !isValid && !error && message ? message : null;
    }, [isValid, error, message]);
    var sizeNameBlockClass = useFileUploaderSize(size, {
        small: jsStyles.contentSmall(theme),
        medium: jsStyles.contentMedium(theme),
        large: jsStyles.contentLarge(theme),
    });
    var sizeViewNameBlockClass = useFileUploaderSize(size, {
        small: jsViewStyles.contentSmall(theme),
        medium: jsViewStyles.contentMedium(theme),
        large: jsViewStyles.contentLarge(theme),
    });
    var validationTextClassName = cx((_a = {},
        _a[jsStyles.validationTextWarning(theme)] = isWarning,
        _a[jsStyles.validationTextError(theme)] = isError,
        _a));
    var contentClassNames = cx(jsStyles.content(), jsViewStyles.content());
    var nameTextClassNames = cx(jsViewStyles.name(), isTileView && !disabled && validationTextClassName);
    var handleMouseEnter = useCallback(function () {
        setHoveredFile(true);
    }, []);
    var handleMouseLeave = useCallback(function () {
        setHoveredFile(false);
    }, []);
    var handleFocus = useCallback(function () {
        var _a;
        // focus event fires before keyDown eventlistener
        // so we should check tabPressed in async way
        (_a = globalObject.requestAnimationFrame) === null || _a === void 0 ? void 0 : _a.call(globalObject, function () {
            if (keyListener.isTabPressed) {
                setFocusedByTab(true);
            }
        });
    }, []);
    var handleBlur = useCallback(function () {
        setFocusedByTab(false);
    }, []);
    var handleIconKeyDown = useCallback(function (e) {
        if (isKeyEnter(e)) {
            onRemove(id);
        }
    }, [onRemove, id]);
    var iconClassNames = cx(jsStyles.icon(theme), (_b = {},
        _b[sizeIconClass] = true,
        _b[jsTileStyles.iconAction(theme)] = isTileView,
        _b[jsTileStyles.iconActionShow()] = isTileView && !disabled && (hovered || hoveredFile || focused || focusedByTab),
        _b));
    var sizeClassName = useFileUploaderSize(size, {
        small: jsStyles.sizeSmall(theme),
        medium: jsStyles.sizeMedium(theme),
        large: jsStyles.sizeLarge(theme),
    });
    var sizeClassNames = cx(jsStyles.size(theme), sizeClassName, jsViewStyles.size(theme), isTileView && disabled && jsTileStyles.sizeDisabled(theme));
    var sizeFileTypeIconClass = useFileUploaderSize(size, {
        small: jsViewStyles.fileTypeIconSmall(theme),
        medium: jsViewStyles.fileTypeIconMedium(theme),
        large: jsViewStyles.fileTypeIconLarge(theme),
    });
    var isTruncated = truncatedFileName !== name;
    var fileTypeIconClassName = cx(sizeFileTypeIconClass, disabled && jsStyles.disabledFileTypeIconSvg(theme), isTileView && (_c = {},
        _c[jsTileStyles.fileTypeIcon(theme)] = true,
        _c[jsTileStyles.fileTypeIconPreview()] = !!previewImg,
        _c[jsTileStyles.disabledFileTypeIcon(theme)] = disabled,
        _c[jsTileStyles.warningFileTypeIcon(theme)] = isWarning,
        _c[jsTileStyles.errorFileTypeIcon(theme)] = isError,
        _c), multiple && jsStyles.fileTypeIconMultiple());
    var nameBlockClassNames = cx(sizeNameBlockClass, sizeViewNameBlockClass, jsStyles.nameBlock(), disabled && jsViewStyles.disabled(theme), jsViewStyles.nameBlock());
    var fileType = getFileUploaderTypeIcon(file.originalFile, isError, isWarning && !!withWarningIcon);
    var icon = isTileView && isLoading ? (React.createElement(LoadingIcon, { size: size })) : (fileTypeIcon !== null && fileTypeIcon !== void 0 ? fileTypeIcon : React.createElement(FileUploaderFileTypeIcon, { type: fileType, size: size, view: view }));
    var splitTruncatedFileName = truncatedFileName && splitFileNameAndExtension(truncatedFileName);
    return (React.createElement(CommonWrapper, __assign({}, rest),
        React.createElement("div", { "data-tid": FileUploaderFileDataTids.file, className: jsStyles.root(), onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, ref: ref },
            React.createElement(Tooltip, { "data-tid": FileUploaderFileDataTids.fileTooltip, pos: validationTooltipPositionByView, render: function () { return (withValidationTooltip || isTileView ? renderTooltipContent() : null); } },
                React.createElement("div", { className: contentClassNames },
                    React.createElement("div", { "data-tid": FileUploaderFileDataTids.fileTypeIcon, className: fileTypeIconClassName, style: previewImg ? { backgroundImage: "url(".concat(previewImg, ")") } : undefined }, (!isTileView || !previewImg) && icon),
                    React.createElement("div", { className: nameBlockClassNames },
                        React.createElement(TextWidthHelper, { ref: textHelperRef, text: name }),
                        React.createElement(Hint, { maxWidth: '100%', text: showFullFilename && isTruncated ? name : null },
                            React.createElement("span", { "data-tid": FileUploaderFileDataTids.fileName, ref: fileNameElementRef, className: nameTextClassNames }, splitTruncatedFileName && (React.createElement(React.Fragment, null,
                                splitTruncatedFileName.name,
                                splitTruncatedFileName.extension && React.createElement("span", null,
                                    ".",
                                    splitTruncatedFileName.extension))))),
                        !(withValidationTooltip || isTileView) && (React.createElement("span", { className: validationTextClassName }, renderTooltipContent()))),
                    showSize && formattedSize && (React.createElement("span", { "data-tid": FileUploaderFileDataTids.fileSize, className: sizeClassNames }, formattedSize)),
                    React.createElement("div", { className: iconClassNames, "data-tid": FileUploaderFileDataTids.fileIcon, tabIndex: 0, onClick: handleRemove, onFocus: handleFocus, onBlur: handleBlur, onKeyDown: handleIconKeyDown },
                        React.createElement(FileUploaderFileStatusIcon, { isTileView: isTileView, status: status, disabled: disabled, hovered: hovered || hoveredFile, focusedByTab: focused || focusedByTab, isInvalid: isInvalid, hasValidation: isError || isWarning, size: size })))))));
});
//# sourceMappingURL=FileUploaderFile.js.map