import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { useRef, useMemo, useCallback } from 'react';
import { css } from '@patternfly/react-styles';
import styles from '../../../css/topology-pipelines';
import topologyStyles from '../../../css/topology-components';
import { Popover, Tooltip } from '@patternfly/react-core';
import { observer } from '../../../mobx-exports';
import { ScaleDetailsLevel } from '../../../types';
import { RunStatus } from '../../types';
import { truncateMiddle } from '../../../utils/truncate-middle';
import { createSvgIdUrl, useCombineRefs, useHover, useSize } from '../../../utils';
import { getRunStatusModifier, nonShadowModifiers } from '../../utils';
import StatusIcon from '../../utils/StatusIcon';
import LabelActionIcon from '../../../components/nodes/labels/LabelActionIcon';
import LabelContextMenu from '../../../components/nodes/labels/LabelContextMenu';
import NodeShadows, { NODE_SHADOW_FILTER_ID_DANGER, NODE_SHADOW_FILTER_ID_HOVER } from '../../../components/nodes/NodeShadows';
import LabelBadge from '../../../components/nodes/labels/LabelBadge';
import LabelIcon from '../../../components/nodes/labels/LabelIcon';
import { TOP_TO_BOTTOM } from '../../../layouts';
const STATUS_ICON_SIZE = 16;
const TaskPill = observer(({ element, taskRef, pillRef, className, width = 0, paddingX = 8, paddingY = 8, status, statusIconSize = STATUS_ICON_SIZE, showStatusState = true, scaleNode, hideDetailsAtMedium, hiddenDetailsShownStatuses = [RunStatus.Failed, RunStatus.FailedToStart, RunStatus.Cancelled], leadIcon, badge, badgeColor, badgeTextColor, badgeBorderColor, badgeClassName = styles.topologyPipelinesPillBadge, badgeTooltip, badgePopoverParams, customStatusIcon, nameLabelClass, taskIconClass, taskIcon, taskIconTooltip, taskIconPadding = 4, hover, truncateLength = 14, disableTooltip = false, selected, onSelect, onContextMenu, contextMenuOpen, hideContextMenuKebab, actionIcon, actionIconClassName, onActionIconClick, shadowCount = 0, shadowOffset = 8, children, x, y }) => {
    var _a, _b, _c, _d, _e, _f, _g;
    const [hovered] = useHover();
    const taskIconComponentRef = useRef(null);
    const isHover = hover !== undefined ? hover : hovered;
    const label = truncateMiddle(element.getLabel(), { length: truncateLength, omission: '...' });
    const [textSize, textRef] = useSize([label, className]);
    const nameLabelTriggerRef = useRef(null);
    const nameLabelRef = useCombineRefs(textRef, nameLabelTriggerRef);
    const [statusSize, statusRef] = useSize([status, showStatusState, statusIconSize]);
    const [leadSize, leadIconRef] = useSize([leadIcon]);
    const [badgeSize, badgeRef] = useSize([badge]);
    const badgeLabelTriggerRef = useRef(null);
    const [actionSize, actionRef] = useSize([actionIcon, paddingX]);
    const [contextSize, contextRef] = useSize([onContextMenu, paddingX]);
    const detailsLevel = element.getGraph().getDetailsLevel();
    const verticalLayout = ((_c = (_b = (_a = element.getGraph()).getLayoutOptions) === null || _b === void 0 ? void 0 : _b.call(_a)) === null || _c === void 0 ? void 0 : _c.rankdir) === TOP_TO_BOTTOM;
    const textWidth = (_d = textSize === null || textSize === void 0 ? void 0 : textSize.width) !== null && _d !== void 0 ? _d : 0;
    const textHeight = (_e = textSize === null || textSize === void 0 ? void 0 : textSize.height) !== null && _e !== void 0 ? _e : 0;
    const { height, statusStartX, textStartX, actionStartX, contextStartX, pillWidth, badgeStartX, iconWidth, iconStartX, leadIconStartX, offsetX } = useMemo(() => {
        if (!textSize) {
            return {
                height: 0,
                statusStartX: 0,
                textStartX: 0,
                actionStartX: 0,
                contextStartX: 0,
                pillWidth: 0,
                badgeStartX: 0,
                iconWidth: 0,
                iconStartX: 0,
                leadIconStartX: 0,
                offsetX: 0
            };
        }
        const height = textHeight + 2 * paddingY;
        const startX = paddingX + paddingX / 2;
        const iconWidth = taskIconClass || taskIcon ? height - taskIconPadding : 0;
        const iconStartX = -(iconWidth * 0.75);
        const statusStartX = startX - statusIconSize / 4; // Adjust for icon padding
        const statusSpace = status && showStatusState && statusSize ? statusSize.width + paddingX : 0;
        const leadIconStartX = startX + statusSpace;
        const leadIconSpace = leadIcon ? leadSize.width + paddingX : 0;
        const textStartX = leadIconStartX + leadIconSpace;
        const textSpace = textWidth + paddingX;
        const badgeStartX = textStartX + textSpace;
        const badgeSpace = badge && badgeSize ? badgeSize.width + paddingX : 0;
        const actionStartX = badgeStartX + badgeSpace;
        const actionSpace = actionIcon && actionSize ? actionSize.width + paddingX : 0;
        const contextStartX = actionStartX + actionSpace;
        const contextSpace = !hideContextMenuKebab && onContextMenu && contextSize ? contextSize.width + paddingX / 2 : 0;
        const pillWidth = contextStartX + contextSpace + paddingX / 2;
        const offsetX = verticalLayout ? (width - pillWidth) / 2 : 0;
        return {
            height,
            statusStartX,
            textStartX,
            actionStartX,
            contextStartX,
            badgeStartX,
            iconWidth,
            iconStartX,
            leadIconStartX,
            pillWidth,
            offsetX
        };
    }, [
        textSize,
        textHeight,
        textWidth,
        paddingY,
        paddingX,
        taskIconClass,
        taskIcon,
        taskIconPadding,
        statusIconSize,
        status,
        showStatusState,
        leadSize,
        leadIcon,
        statusSize,
        badgeSize,
        badge,
        actionIcon,
        actionSize,
        hideContextMenuKebab,
        onContextMenu,
        contextSize,
        verticalLayout,
        width
    ]);
    const scale = element.getGraph().getScale();
    const nameLabel = (_jsx("text", Object.assign({ x: offsetX, ref: nameLabelRef, className: css(nameLabelClass, styles.topologyPipelinesPillText), dominantBaseline: "middle" }, { children: label })));
    const runStatusModifier = getRunStatusModifier(status);
    const pillClasses = css(styles.topologyPipelinesPill, className, isHover && styles.modifiers.hover, runStatusModifier, selected && styles.modifiers.selected, onSelect && styles.modifiers.selectable);
    // Force an update of the given pillRef when dependencies change
    const pillUpdatedRef = useCallback((node) => {
        pillRef(node);
    }, 
    // dependencies causing the pill rect to resize
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [pillClasses, width, height]);
    let filter;
    if (runStatusModifier === styles.modifiers.danger) {
        filter = createSvgIdUrl(NODE_SHADOW_FILTER_ID_DANGER);
    }
    else if (isHover && !nonShadowModifiers.includes(runStatusModifier)) {
        filter = createSvgIdUrl(NODE_SHADOW_FILTER_ID_HOVER);
    }
    const taskIconComponent = (taskIconClass || taskIcon) && (_jsx(LabelIcon, { x: offsetX + iconStartX + iconWidth, y: (height - iconWidth) / 2, width: iconWidth, height: iconWidth, iconClass: taskIconClass, icon: taskIcon, padding: taskIconPadding, innerRef: taskIconComponentRef }));
    const badgeLabel = badge ? (_jsx(LabelBadge, { ref: badgeRef, innerRef: badgeLabelTriggerRef, x: offsetX + badgeStartX, y: (height - ((_f = badgeSize === null || badgeSize === void 0 ? void 0 : badgeSize.height) !== null && _f !== void 0 ? _f : 0)) / 2, badge: badge, badgeClassName: badgeClassName, badgeColor: badgeColor, badgeTextColor: badgeTextColor, badgeBorderColor: badgeBorderColor })) : null;
    let badgeComponent;
    if (badgeLabel && badgeTooltip) {
        badgeComponent = (_jsx(Tooltip, Object.assign({ triggerRef: badgeLabelTriggerRef, content: badgeTooltip }, { children: badgeLabel })));
    }
    else if (badgeLabel && badgePopoverParams) {
        badgeComponent = (_jsx("g", Object.assign({ onClick: (e) => e.stopPropagation() }, { children: _jsx(Popover, Object.assign({ triggerRef: badgeLabelTriggerRef }, badgePopoverParams, { children: badgeLabel })) })));
    }
    else {
        badgeComponent = badgeLabel;
    }
    if (showStatusState && !scaleNode && hideDetailsAtMedium && detailsLevel !== ScaleDetailsLevel.high) {
        const statusBackgroundRadius = statusIconSize / 2 + 4;
        const upScale = 1 / scale;
        const { height: boundsHeight } = element.getBounds();
        const translateX = verticalLayout ? width / 2 - statusBackgroundRadius * upScale : 0;
        const translateY = verticalLayout ? 0 : (boundsHeight - statusBackgroundRadius * 2 * upScale) / 2;
        return (_jsxs("g", Object.assign({ transform: `translate(${translateX}, ${translateY}) scale(${upScale})`, ref: taskRef }, { children: [_jsx("circle", { className: css(styles.topologyPipelinesStatusIconBackground, styles.topologyPipelinesPillStatus, runStatusModifier, selected && 'pf-m-selected'), cx: statusBackgroundRadius, cy: statusBackgroundRadius, r: statusBackgroundRadius }), status && (!hiddenDetailsShownStatuses || hiddenDetailsShownStatuses.includes(status)) ? (_jsx("g", Object.assign({ transform: `translate(4, 4)` }, { children: _jsx("g", Object.assign({ className: css(styles.topologyPipelinesStatusIcon, runStatusModifier, selected && 'pf-m-selected', (status === RunStatus.Running || status === RunStatus.InProgress) && styles.modifiers.spin) }, { children: customStatusIcon !== null && customStatusIcon !== void 0 ? customStatusIcon : _jsx(StatusIcon, { status: status }) })) }))) : null] })));
    }
    const shadows = [];
    for (let i = shadowCount; i > 0; i--) {
        shadows.push(_jsx("rect", { x: offsetX + shadowOffset * i, y: 0, width: pillWidth, height: height, rx: height / 2, className: css(topologyStyles.topologyNodeBackground, 'pf-m-disabled'), filter: filter }, `shadow-offset-${i}`));
    }
    return (_jsxs("g", Object.assign({ className: pillClasses, transform: `translate(${x},${y})`, onClick: onSelect, onContextMenu: onContextMenu, ref: taskRef }, { children: [_jsx(NodeShadows, {}), shadows, _jsx("rect", { x: offsetX, y: 0, width: pillWidth, ref: pillUpdatedRef, height: height, rx: height / 2, className: css(styles.topologyPipelinesPillBackground), filter: filter }), _jsx("g", Object.assign({ transform: `translate(${textStartX}, ${paddingY + textHeight / 2 + 1})` }, { children: element.getLabel() !== label && !disableTooltip ? (_jsx(Tooltip, Object.assign({ triggerRef: nameLabelTriggerRef, content: element.getLabel() }, { children: _jsx("g", { children: nameLabel }) }))) : (nameLabel) })), status && showStatusState && (_jsx("g", Object.assign({ transform: `translate(${offsetX + statusStartX + paddingX / 2}, ${(height - statusIconSize) / 2})`, ref: statusRef }, { children: _jsx("g", Object.assign({ className: css(styles.topologyPipelinesPillStatus, runStatusModifier, selected && 'pf-m-selected', (status === RunStatus.Running || status === RunStatus.InProgress) && styles.modifiers.spin) }, { children: customStatusIcon !== null && customStatusIcon !== void 0 ? customStatusIcon : _jsx(StatusIcon, { status: status }) })) }))), leadIcon && (_jsx("g", Object.assign({ transform: `translate(${offsetX + leadIconStartX}, ${((_g = height - (leadSize === null || leadSize === void 0 ? void 0 : leadSize.height)) !== null && _g !== void 0 ? _g : 0) / 2})`, ref: leadIconRef }, { children: leadIcon }))), taskIconComponent &&
                (taskIconTooltip ? (_jsx(Tooltip, Object.assign({ triggerRef: taskIconComponentRef, content: taskIconTooltip }, { children: taskIconComponent }))) : (taskIconComponent)), badgeComponent, actionIcon && (_jsxs(_Fragment, { children: [_jsx("line", { className: css(topologyStyles.topologyNodeSeparator), x1: offsetX + actionStartX, y1: 0, x2: offsetX + actionStartX, y2: height, shapeRendering: "crispEdges" }), _jsx(LabelActionIcon, { ref: actionRef, x: offsetX + actionStartX, y: 0, height: height, paddingX: paddingX, paddingY: 0, icon: actionIcon, className: actionIconClassName, onClick: onActionIconClick })] })), textSize && onContextMenu && !hideContextMenuKebab && (_jsxs(_Fragment, { children: [_jsx("line", { className: css(topologyStyles.topologyNodeSeparator), x1: offsetX + contextStartX, y1: 0, x2: offsetX + contextStartX, y2: height, shapeRendering: "crispEdges" }), _jsx(LabelContextMenu, { ref: contextRef, x: offsetX + contextStartX, y: 0, height: height, paddingX: paddingX, paddingY: 0, onContextMenu: onContextMenu, contextMenuOpen: contextMenuOpen })] })), children] })));
});
export default TaskPill;
//# sourceMappingURL=TaskPill.js.map