'use client';
import * as React from 'react';
import { mergeClasses } from '@griffel/react';
import { applyOpacityToColor, DEFAULT_ANNOTATION_BACKGROUND_OPACITY, DEFAULT_CONNECTOR_ARROW, DEFAULT_CONNECTOR_END_PADDING, DEFAULT_CONNECTOR_START_PADDING, DEFAULT_CONNECTOR_STROKE_WIDTH, getDefaultConnectorStrokeColor, useChartAnnotationLayerStyles } from './useChartAnnotationLayer.styles';
import { useId } from '@fluentui/react-utilities';
import { tokens } from '@fluentui/react-theme';
const DEFAULT_HORIZONTAL_ALIGN = 'center';
const DEFAULT_VERTICAL_ALIGN = 'middle';
const DEFAULT_FOREIGN_OBJECT_WIDTH = 180;
const DEFAULT_FOREIGN_OBJECT_HEIGHT = 60;
const MIN_ARROW_SIZE = 6;
const MAX_ARROW_SIZE = 24;
const ARROW_SIZE_SCALE = 0.35;
const MAX_SIMPLE_MARKUP_DEPTH = 5;
const CHAR_CODE_LESS_THAN = '<'.codePointAt(0);
const CHAR_CODE_GREATER_THAN = '>'.codePointAt(0);
const decodeSimpleMarkupInput = (input)=>{
    const namedEntities = {
        amp: '&',
        quot: '"',
        apos: "'",
        nbsp: '\u00a0'
    };
    const withBasicEntitiesDecoded = input.replace(/&(#x?[0-9a-f]+|#\d+|[a-z][\w-]*);/gi, (match, entity)=>{
        const lower = entity.toLowerCase();
        if (lower === 'lt' || lower === 'gt') {
            return `&${lower};`;
        }
        if (lower.startsWith('#')) {
            const isHex = lower[1] === 'x';
            const digits = lower.slice(isHex ? 2 : 1);
            const codePoint = Number.parseInt(digits, isHex ? 16 : 10);
            if (Number.isNaN(codePoint)) {
                return match;
            }
            if (codePoint === CHAR_CODE_LESS_THAN) {
                return '&lt;';
            }
            if (codePoint === CHAR_CODE_GREATER_THAN) {
                return '&gt;';
            }
            return String.fromCodePoint(codePoint);
        }
        var _namedEntities_lower;
        return (_namedEntities_lower = namedEntities[lower]) !== null && _namedEntities_lower !== void 0 ? _namedEntities_lower : match;
    });
    return withBasicEntitiesDecoded.replace(/&lt;([^;]+)&gt;/gi, (match, inner)=>{
        const normalized = inner.trim().replace(/\s+/g, ' ');
        const lower = normalized.toLowerCase();
        switch(lower){
            case 'b':
                return '<b>';
            case '/b':
                return '</b>';
            case 'i':
                return '<i>';
            case '/i':
                return '</i>';
            case 'br':
            case 'br/':
            case 'br /':
                return '<br />';
            default:
                return match;
        }
    });
};
const appendTextNode = (nodes, text)=>{
    if (text.length === 0) {
        return;
    }
    const last = nodes[nodes.length - 1];
    if (last && last.type === 'text') {
        last.content += text;
    } else {
        nodes.push({
            type: 'text',
            content: text
        });
    }
};
const serializeSimpleMarkup = (nodes)=>nodes.map((node)=>{
        if (node.type === 'text') {
            return node.content;
        }
        if (node.type === 'br') {
            return '<br />';
        }
        return `<${node.tag}>${serializeSimpleMarkup(node.children)}</${node.tag}>`;
    }).join('');
const parseSimpleMarkup = (input)=>{
    if (!input) {
        return [];
    }
    const decodedInput = decodeSimpleMarkupInput(input);
    const rootChildren = [];
    const stack = [
        {
            node: null
        }
    ];
    const currentChildren = ()=>{
        var _stack__node;
        var _stack__node_children;
        return (_stack__node_children = (_stack__node = stack[stack.length - 1].node) === null || _stack__node === void 0 ? void 0 : _stack__node.children) !== null && _stack__node_children !== void 0 ? _stack__node_children : rootChildren;
    };
    const tagRegex = /<\/?([a-z]+)\s*\/?\s*>/gi;
    let lastIndex = 0;
    let match;
    while((match = tagRegex.exec(decodedInput)) !== null){
        const [fullMatch, rawTagName] = match;
        const tagName = rawTagName.toLowerCase();
        const isClosing = fullMatch.startsWith('</');
        const isSelfClosing = /\/\s*>$/.test(fullMatch);
        appendTextNode(currentChildren(), decodedInput.slice(lastIndex, match.index));
        lastIndex = match.index + fullMatch.length;
        if (tagName === 'br' && !isClosing) {
            currentChildren().push({
                type: 'br'
            });
            continue;
        }
        if ((tagName === 'b' || tagName === 'i') && !isSelfClosing) {
            if (isClosing) {
                const top = stack[stack.length - 1].node;
                if (stack.length > 1 && (top === null || top === void 0 ? void 0 : top.tag) === tagName) {
                    stack.pop();
                } else {
                    appendTextNode(currentChildren(), fullMatch);
                }
            } else {
                if (stack.length - 1 >= MAX_SIMPLE_MARKUP_DEPTH) {
                    appendTextNode(currentChildren(), fullMatch);
                    continue;
                }
                const elementNode = {
                    type: 'element',
                    tag: tagName,
                    children: []
                };
                currentChildren().push(elementNode);
                stack.push({
                    node: elementNode
                });
            }
            continue;
        }
        appendTextNode(currentChildren(), fullMatch);
    }
    appendTextNode(currentChildren(), decodedInput.slice(lastIndex));
    while(stack.length > 1){
        var _stack__node;
        const unclosed = stack.pop();
        const elementNode = unclosed.node;
        if (!elementNode) {
            continue;
        }
        var _stack__node_children;
        const parentChildren = (_stack__node_children = (_stack__node = stack[stack.length - 1].node) === null || _stack__node === void 0 ? void 0 : _stack__node.children) !== null && _stack__node_children !== void 0 ? _stack__node_children : rootChildren;
        const lastChild = parentChildren[parentChildren.length - 1];
        if (lastChild === elementNode) {
            parentChildren.pop();
        } else {
            const nodeIndex = parentChildren.indexOf(elementNode);
            if (nodeIndex !== -1) {
                parentChildren.splice(nodeIndex, 1);
            }
        }
        appendTextNode(parentChildren, `<${elementNode.tag}>${serializeSimpleMarkup(elementNode.children)}</${elementNode.tag}>`);
    }
    return rootChildren;
};
const simpleMarkupNodesToPlainText = (nodes)=>nodes.map((node)=>{
        if (node.type === 'text') {
            return node.content;
        }
        if (node.type === 'br') {
            return '\n';
        }
        return simpleMarkupNodesToPlainText(node.children);
    }).join('');
const renderSimpleMarkupNodeList = (nodes, keyPrefix)=>nodes.map((node, index)=>{
        const key = `${keyPrefix}-${index}`;
        if (node.type === 'text') {
            return /*#__PURE__*/ React.createElement(React.Fragment, {
                key: key
            }, node.content);
        }
        if (node.type === 'br') {
            return /*#__PURE__*/ React.createElement("br", {
                key: key
            });
        }
        const Tag = node.tag === 'b' ? 'strong' : 'em';
        return /*#__PURE__*/ React.createElement(Tag, {
            key
        }, ...renderSimpleMarkupNodeList(node.children, key));
    });
const renderSimpleMarkup = (nodes, keyPrefix)=>{
    const rendered = renderSimpleMarkupNodeList(nodes, keyPrefix);
    var _rendered_;
    return rendered.length <= 1 ? (_rendered_ = rendered[0]) !== null && _rendered_ !== void 0 ? _rendered_ : null : rendered;
};
const normalizeBandOffset = (scale, value)=>{
    const position = scale === null || scale === void 0 ? void 0 : scale(value);
    if (typeof position !== 'number' || Number.isNaN(position)) {
        return undefined;
    }
    if (scale && typeof scale.bandwidth === 'function') {
        return position + scale.bandwidth() / 2;
    }
    return position;
};
const clamp = (value, min, max)=>Math.max(min, Math.min(max, value));
const resolveDataCoordinate = (axis, value, context, yAxis = 'primary')=>{
    if (axis === 'x') {
        const xScale = context.xScale;
        if (!xScale) {
            return undefined;
        }
        const parsedValue = value instanceof Date ? value.getTime() : value;
        return normalizeBandOffset(xScale, parsedValue);
    }
    const yScale = yAxis === 'secondary' ? context.yScaleSecondary : context.yScalePrimary;
    if (!yScale) {
        return undefined;
    }
    const parsedValue = value instanceof Date ? value.getTime() : value;
    return normalizeBandOffset(yScale, parsedValue);
};
const resolveAxisCoordinate = (axis, coordinateType, value, context, options = {})=>{
    switch(coordinateType){
        case 'data':
            return resolveDataCoordinate(axis, value, context, options.yAxis);
        case 'relative':
            if (typeof value !== 'number' || Number.isNaN(value)) {
                return undefined;
            }
            return axis === 'x' ? context.plotRect.x + context.plotRect.width * value : context.plotRect.y + context.plotRect.height * value;
        case 'pixel':
            if (typeof value !== 'number' || Number.isNaN(value)) {
                return undefined;
            }
            return axis === 'x' ? context.plotRect.x + value : context.plotRect.y + value;
        default:
            return undefined;
    }
};
const createMeasurementSignature = (annotationContentSignature, containerStyle, contentStyle, layoutClassName, styleClassName)=>JSON.stringify({
        annotationContentSignature,
        containerStyle,
        contentStyle,
        layoutClassName: layoutClassName !== null && layoutClassName !== void 0 ? layoutClassName : '',
        styleClassName: styleClassName !== null && styleClassName !== void 0 ? styleClassName : ''
    });
const getCoordinateDescriptor = (coordinates)=>{
    switch(coordinates.type){
        case 'data':
            return {
                xType: 'data',
                yType: 'data',
                yAxis: coordinates.yAxis
            };
        case 'relative':
            return {
                xType: 'relative',
                yType: 'relative'
            };
        case 'pixel':
            return {
                xType: 'pixel',
                yType: 'pixel'
            };
        case 'mixed':
            return {
                xType: coordinates.xCoordinateType,
                yType: coordinates.yCoordinateType,
                yAxis: coordinates.yAxis
            };
        default:
            return undefined;
    }
};
const resolveCoordinates = (annotation, context)=>{
    const { coordinates, layout } = annotation;
    if (!coordinates) {
        return undefined;
    }
    const descriptor = getCoordinateDescriptor(coordinates);
    if (!descriptor) {
        return undefined;
    }
    var _layout_offsetX;
    const offsetX = (_layout_offsetX = layout === null || layout === void 0 ? void 0 : layout.offsetX) !== null && _layout_offsetX !== void 0 ? _layout_offsetX : 0;
    var _layout_offsetY;
    const offsetY = (_layout_offsetY = layout === null || layout === void 0 ? void 0 : layout.offsetY) !== null && _layout_offsetY !== void 0 ? _layout_offsetY : 0;
    const anchorX = resolveAxisCoordinate('x', descriptor.xType, coordinates.x, context);
    const anchorY = resolveAxisCoordinate('y', descriptor.yType, coordinates.y, context, {
        yAxis: descriptor.yAxis
    });
    if (anchorX === undefined || anchorY === undefined) {
        return undefined;
    }
    const anchor = {
        x: anchorX,
        y: anchorY
    };
    let left = anchor.x + offsetX;
    let top = anchor.y + offsetY;
    if (layout === null || layout === void 0 ? void 0 : layout.clipToBounds) {
        left = clamp(left, context.plotRect.x, context.plotRect.x + context.plotRect.width);
        top = clamp(top, context.plotRect.y, context.plotRect.y + context.plotRect.height);
    }
    return {
        anchor,
        point: {
            x: left,
            y: top
        }
    };
};
export const ChartAnnotationLayer = /*#__PURE__*/ React.memo((props)=>{
    const { annotations: annotationsProp, context, hideDefaultStyles } = props;
    const classes = useChartAnnotationLayerStyles(props);
    const idPrefix = useId('chart-annotation');
    const autoKeyPrefix = useId('chart-annotation-item');
    const [measurements, setMeasurements] = React.useState({});
    const resolvedAnnotations = React.useMemo(()=>{
        let fallbackIndex = 0;
        return (annotationsProp !== null && annotationsProp !== void 0 ? annotationsProp : []).map((annotation)=>{
            var _annotation_id;
            return {
                annotation,
                key: (_annotation_id = annotation.id) !== null && _annotation_id !== void 0 ? _annotation_id : `${autoKeyPrefix}-${fallbackIndex++}`
            };
        });
    }, [
        annotationsProp,
        autoKeyPrefix
    ]);
    React.useEffect(()=>{
        setMeasurements((prev)=>{
            if (resolvedAnnotations.length === 0) {
                if (Object.keys(prev).length === 0) {
                    return prev;
                }
                return {};
            }
            const next = {};
            resolvedAnnotations.forEach(({ key })=>{
                if (prev[key]) {
                    next[key] = prev[key];
                }
            });
            if (Object.keys(next).length === Object.keys(prev).length) {
                let identical = true;
                for (const key of Object.keys(next)){
                    if (next[key] !== prev[key]) {
                        identical = false;
                        break;
                    }
                }
                if (identical) {
                    return prev;
                }
            }
            return next;
        });
    }, [
        resolvedAnnotations
    ]);
    const updateMeasurement = React.useCallback((key, width, height, signature)=>{
        setMeasurements((prev)=>{
            const prevEntry = prev[key];
            if (prevEntry && prevEntry.signature === signature && Math.abs(prevEntry.width - width) < 0.5 && Math.abs(prevEntry.height - height) < 0.5) {
                return prev;
            }
            if (width === 0 && height === 0) {
                return prev;
            }
            return {
                ...prev,
                [key]: {
                    width,
                    height,
                    signature
                }
            };
        });
    }, []);
    const annotationForeignObjects = [];
    const measurementElements = [];
    const connectors = [];
    resolvedAnnotations.forEach(({ annotation, key })=>{
        var _annotation_style, _annotation_style1, _annotation_style2, _annotation_style3, _annotation_style4, _annotation_style5, _annotation_style6, _annotation_style7, _annotation_style8, _annotation_style9, _annotation_style10, _annotation_style11, _annotation_style12, _annotation_style13, _annotation_style14, _annotation_style15, _annotation_style16, _annotation_style17, _annotation_style18, _annotation_accessibility, _annotation_accessibility1, _annotation_accessibility2;
        const resolved = resolveCoordinates(annotation, context);
        if (!resolved) {
            return;
        }
        const rawAnnotationText = annotation.text === undefined || annotation.text === null ? '' : String(annotation.text);
        const annotationMarkupNodes = parseSimpleMarkup(rawAnnotationText);
        const annotationMarkupSignature = JSON.stringify(annotationMarkupNodes);
        const annotationPlainText = simpleMarkupNodesToPlainText(annotationMarkupNodes);
        const layout = annotation.layout;
        var _layout_align;
        const horizontalAlign = (_layout_align = layout === null || layout === void 0 ? void 0 : layout.align) !== null && _layout_align !== void 0 ? _layout_align : DEFAULT_HORIZONTAL_ALIGN;
        var _layout_verticalAlign;
        const verticalAlign = (_layout_verticalAlign = layout === null || layout === void 0 ? void 0 : layout.verticalAlign) !== null && _layout_verticalAlign !== void 0 ? _layout_verticalAlign : DEFAULT_VERTICAL_ALIGN;
        var _annotation_style_opacity;
        const backgroundOpacity = (_annotation_style_opacity = (_annotation_style = annotation.style) === null || _annotation_style === void 0 ? void 0 : _annotation_style.opacity) !== null && _annotation_style_opacity !== void 0 ? _annotation_style_opacity : DEFAULT_ANNOTATION_BACKGROUND_OPACITY;
        const baseBackgroundColor = (_annotation_style1 = annotation.style) === null || _annotation_style1 === void 0 ? void 0 : _annotation_style1.backgroundColor;
        const hasCustomBackground = ((_annotation_style2 = annotation.style) === null || _annotation_style2 === void 0 ? void 0 : _annotation_style2.backgroundColor) !== undefined || ((_annotation_style3 = annotation.style) === null || _annotation_style3 === void 0 ? void 0 : _annotation_style3.opacity) !== undefined;
        var _annotation_style_borderStyle;
        const containerStyle = {
            maxWidth: layout === null || layout === void 0 ? void 0 : layout.maxWidth,
            ...hasCustomBackground ? {
                backgroundColor: applyOpacityToColor(baseBackgroundColor, backgroundOpacity, {
                    preserveOriginalOpacity: ((_annotation_style4 = annotation.style) === null || _annotation_style4 === void 0 ? void 0 : _annotation_style4.opacity) === undefined
                })
            } : hideDefaultStyles ? {} : {
                backgroundColor: applyOpacityToColor(tokens.colorNeutralBackground1, DEFAULT_ANNOTATION_BACKGROUND_OPACITY)
            },
            borderColor: (_annotation_style5 = annotation.style) === null || _annotation_style5 === void 0 ? void 0 : _annotation_style5.borderColor,
            borderWidth: (_annotation_style6 = annotation.style) === null || _annotation_style6 === void 0 ? void 0 : _annotation_style6.borderWidth,
            borderStyle: (_annotation_style_borderStyle = (_annotation_style7 = annotation.style) === null || _annotation_style7 === void 0 ? void 0 : _annotation_style7.borderStyle) !== null && _annotation_style_borderStyle !== void 0 ? _annotation_style_borderStyle : ((_annotation_style8 = annotation.style) === null || _annotation_style8 === void 0 ? void 0 : _annotation_style8.borderColor) ? 'solid' : undefined,
            borderRadius: (_annotation_style9 = annotation.style) === null || _annotation_style9 === void 0 ? void 0 : _annotation_style9.borderRadius,
            padding: (_annotation_style10 = annotation.style) === null || _annotation_style10 === void 0 ? void 0 : _annotation_style10.padding,
            boxShadow: (_annotation_style11 = annotation.style) === null || _annotation_style11 === void 0 ? void 0 : _annotation_style11.boxShadow
        };
        const contentStyle = {
            color: (_annotation_style12 = annotation.style) === null || _annotation_style12 === void 0 ? void 0 : _annotation_style12.textColor,
            fontSize: (_annotation_style13 = annotation.style) === null || _annotation_style13 === void 0 ? void 0 : _annotation_style13.fontSize,
            fontWeight: (_annotation_style14 = annotation.style) === null || _annotation_style14 === void 0 ? void 0 : _annotation_style14.fontWeight,
            opacity: 1
        };
        if (typeof ((_annotation_style15 = annotation.style) === null || _annotation_style15 === void 0 ? void 0 : _annotation_style15.rotation) === 'number' && !Number.isNaN(annotation.style.rotation)) {
            containerStyle.transform = `rotate(${annotation.style.rotation}deg)`;
            containerStyle.transformOrigin = '50% 50%';
        }
        const measurementSignature = createMeasurementSignature(annotationMarkupSignature, containerStyle, contentStyle, layout === null || layout === void 0 ? void 0 : layout.className, (_annotation_style16 = annotation.style) === null || _annotation_style16 === void 0 ? void 0 : _annotation_style16.className);
        const measurementEntry = measurements[key];
        const isMeasurementValid = (measurementEntry === null || measurementEntry === void 0 ? void 0 : measurementEntry.signature) === measurementSignature;
        const measuredSize = isMeasurementValid ? measurementEntry : undefined;
        var _measuredSize_width, _ref;
        const width = Math.max((_ref = (_measuredSize_width = measuredSize === null || measuredSize === void 0 ? void 0 : measuredSize.width) !== null && _measuredSize_width !== void 0 ? _measuredSize_width : layout === null || layout === void 0 ? void 0 : layout.maxWidth) !== null && _ref !== void 0 ? _ref : DEFAULT_FOREIGN_OBJECT_WIDTH, 1);
        var _measuredSize_height;
        const height = Math.max((_measuredSize_height = measuredSize === null || measuredSize === void 0 ? void 0 : measuredSize.height) !== null && _measuredSize_height !== void 0 ? _measuredSize_height : DEFAULT_FOREIGN_OBJECT_HEIGHT, 1);
        const offsetX = horizontalAlign === 'center' ? -width / 2 : horizontalAlign === 'end' ? -width : 0;
        const offsetY = verticalAlign === 'middle' ? -height / 2 : verticalAlign === 'bottom' ? -height : 0;
        const baseTopLeftX = resolved.point.x + offsetX;
        const baseTopLeftY = resolved.point.y + offsetY;
        const usePlotBounds = (layout === null || layout === void 0 ? void 0 : layout.clipToBounds) !== false;
        const viewportX = usePlotBounds ? context.plotRect.x : 0;
        const viewportY = usePlotBounds ? context.plotRect.y : 0;
        var _context_svgRect_width;
        const viewportWidth = usePlotBounds ? context.plotRect.width : (_context_svgRect_width = context.svgRect.width) !== null && _context_svgRect_width !== void 0 ? _context_svgRect_width : 0;
        var _context_svgRect_height;
        const viewportHeight = usePlotBounds ? context.plotRect.height : (_context_svgRect_height = context.svgRect.height) !== null && _context_svgRect_height !== void 0 ? _context_svgRect_height : 0;
        const maxTopLeftX = viewportWidth > 0 ? viewportX + viewportWidth - width : baseTopLeftX;
        const maxTopLeftY = viewportHeight > 0 ? viewportY + viewportHeight - height : baseTopLeftY;
        let topLeftX = viewportWidth > 0 ? clamp(baseTopLeftX, viewportX, Math.max(viewportX, maxTopLeftX)) : baseTopLeftX;
        let topLeftY = viewportHeight > 0 ? clamp(baseTopLeftY, viewportY, Math.max(viewportY, maxTopLeftY)) : baseTopLeftY;
        let displayPoint = {
            x: topLeftX - offsetX,
            y: topLeftY - offsetY
        };
        if (annotation.connector) {
            var _annotation_connector_startPadding;
            const startPadding = (_annotation_connector_startPadding = annotation.connector.startPadding) !== null && _annotation_connector_startPadding !== void 0 ? _annotation_connector_startPadding : 12;
            var _annotation_connector_endPadding;
            const endPadding = (_annotation_connector_endPadding = annotation.connector.endPadding) !== null && _annotation_connector_endPadding !== void 0 ? _annotation_connector_endPadding : 0;
            const minArrowClearance = 6;
            const minDistance = Math.max(startPadding + endPadding + minArrowClearance, startPadding);
            const dx = displayPoint.x - resolved.anchor.x;
            const dy = displayPoint.y - resolved.anchor.y;
            const distance = Math.sqrt(dx * dx + dy * dy);
            if (distance < minDistance) {
                const fallbackDirection = {
                    x: 0,
                    y: -1
                };
                const ux = distance === 0 ? fallbackDirection.x : dx / distance;
                const uy = distance === 0 ? fallbackDirection.y : dy / distance;
                const desiredDisplayX = resolved.anchor.x + ux * minDistance;
                const desiredDisplayY = resolved.anchor.y + uy * minDistance;
                let desiredTopLeftX = desiredDisplayX + offsetX;
                let desiredTopLeftY = desiredDisplayY + offsetY;
                desiredTopLeftX = viewportWidth > 0 ? clamp(desiredTopLeftX, viewportX, Math.max(viewportX, maxTopLeftX)) : desiredTopLeftX;
                desiredTopLeftY = viewportHeight > 0 ? clamp(desiredTopLeftY, viewportY, Math.max(viewportY, maxTopLeftY)) : desiredTopLeftY;
                topLeftX = desiredTopLeftX;
                topLeftY = desiredTopLeftY;
                displayPoint = {
                    x: topLeftX - offsetX,
                    y: topLeftY - offsetY
                };
            }
        }
        const measurementStyle = {
            position: 'absolute',
            left: topLeftX,
            top: topLeftY,
            pointerEvents: 'none',
            visibility: 'hidden',
            ...containerStyle
        };
        const annotationClass = hideDefaultStyles ? classes.annotationNoDefaults : classes.annotation;
        if (!isMeasurementValid) {
            var _annotation_style19, _annotation_style20;
            measurementElements.push(/*#__PURE__*/ React.createElement("div", {
                key: `${key}-measurement`,
                ref: (node)=>{
                    if (node) {
                        const rect = node.getBoundingClientRect();
                        if (rect.width !== 0 || rect.height !== 0) {
                            updateMeasurement(key, rect.width, rect.height, measurementSignature);
                        }
                    }
                },
                className: mergeClasses(annotationClass, classes.measurement, layout === null || layout === void 0 ? void 0 : layout.className, (_annotation_style19 = annotation.style) === null || _annotation_style19 === void 0 ? void 0 : _annotation_style19.className),
                style: measurementStyle,
                "aria-hidden": true,
                "data-annotation-key": key,
                "data-chart-annotation-measurement": "true"
            }, /*#__PURE__*/ React.createElement("div", {
                className: mergeClasses(classes.annotationContent, layout === null || layout === void 0 ? void 0 : layout.className, (_annotation_style20 = annotation.style) === null || _annotation_style20 === void 0 ? void 0 : _annotation_style20.className),
                style: contentStyle
            }, renderSimpleMarkup(annotationMarkupNodes, `${key}-measurement`))));
        }
        var _annotation_accessibility_role, _annotation_accessibility_ariaLabel;
        annotationForeignObjects.push(/*#__PURE__*/ React.createElement("foreignObject", {
            key: `${key}-annotation`,
            x: topLeftX,
            y: topLeftY,
            width: width,
            height: height,
            className: mergeClasses(classes.annotationForeignObject),
            "data-annotation-key": key
        }, /*#__PURE__*/ React.createElement("div", {
            className: mergeClasses(annotationClass, layout === null || layout === void 0 ? void 0 : layout.className, (_annotation_style17 = annotation.style) === null || _annotation_style17 === void 0 ? void 0 : _annotation_style17.className),
            style: containerStyle,
            "data-annotation-key": key
        }, /*#__PURE__*/ React.createElement("div", {
            className: mergeClasses(classes.annotationContent, classes.annotationContentInteractive, (_annotation_style18 = annotation.style) === null || _annotation_style18 === void 0 ? void 0 : _annotation_style18.className),
            style: contentStyle,
            role: (_annotation_accessibility_role = (_annotation_accessibility = annotation.accessibility) === null || _annotation_accessibility === void 0 ? void 0 : _annotation_accessibility.role) !== null && _annotation_accessibility_role !== void 0 ? _annotation_accessibility_role : 'note',
            "aria-label": (_annotation_accessibility_ariaLabel = (_annotation_accessibility1 = annotation.accessibility) === null || _annotation_accessibility1 === void 0 ? void 0 : _annotation_accessibility1.ariaLabel) !== null && _annotation_accessibility_ariaLabel !== void 0 ? _annotation_accessibility_ariaLabel : annotationPlainText ? annotationPlainText : undefined,
            "aria-describedby": (_annotation_accessibility2 = annotation.accessibility) === null || _annotation_accessibility2 === void 0 ? void 0 : _annotation_accessibility2.ariaDescribedBy,
            tabIndex: 0,
            "data-chart-annotation": "true",
            "data-annotation-key": key
        }, renderSimpleMarkup(annotationMarkupNodes, `${key}-content`)))));
        if (annotation.connector) {
            const { startPadding = DEFAULT_CONNECTOR_START_PADDING, endPadding = DEFAULT_CONNECTOR_END_PADDING, strokeColor = getDefaultConnectorStrokeColor(), strokeWidth = DEFAULT_CONNECTOR_STROKE_WIDTH, dashArray, arrow = DEFAULT_CONNECTOR_ARROW } = annotation.connector;
            const dx = resolved.anchor.x - displayPoint.x;
            const dy = resolved.anchor.y - displayPoint.y;
            const distance = Math.sqrt(dx * dx + dy * dy) || 1;
            const ux = dx / distance;
            const uy = dy / distance;
            const sizeBasis = Math.max(1, Math.min(width, height));
            const proportionalSize = sizeBasis * ARROW_SIZE_SCALE;
            const maxByPadding = startPadding > 0 ? startPadding * 1.25 : MAX_ARROW_SIZE;
            const maxByDistance = distance * 0.6;
            const markerSize = clamp(proportionalSize, MIN_ARROW_SIZE, Math.min(MAX_ARROW_SIZE, maxByPadding, maxByDistance));
            const markerStrokeWidth = clamp(strokeWidth, 1, markerSize / 2);
            const start = {
                x: displayPoint.x + ux * startPadding,
                y: displayPoint.y + uy * startPadding
            };
            const end = {
                x: resolved.anchor.x - ux * endPadding,
                y: resolved.anchor.y - uy * endPadding
            };
            connectors.push({
                key: `${key}-connector`,
                start,
                end,
                strokeColor,
                strokeWidth,
                dashArray,
                arrow,
                markerSize,
                markerStrokeWidth
            });
        }
    });
    if (annotationForeignObjects.length === 0 && connectors.length === 0) {
        return null;
    }
    const viewBoxWidth = context.svgRect.width || 1;
    const viewBoxHeight = context.svgRect.height || 1;
    const markerDefs = [];
    const createMarkerId = (color, position, size, markerStrokeWidth)=>{
        const id = `${idPrefix}-${position}-${markerDefs.length}`;
        const refY = size / 2;
        const refX = position === 'end' ? size : 0;
        const pathEnd = `M0 0 L ${size} ${refY} L0 ${size} Z`;
        const pathStart = `M ${size} 0 L0 ${refY} L ${size} ${size} Z`;
        const path = position === 'end' ? pathEnd : pathStart;
        markerDefs.push(/*#__PURE__*/ React.createElement("marker", {
            key: id,
            id: id,
            markerWidth: size,
            markerHeight: size,
            viewBox: `0 0 ${size} ${size}`,
            refX: refX,
            refY: refY,
            orient: "auto",
            markerUnits: "userSpaceOnUse"
        }, /*#__PURE__*/ React.createElement("path", {
            d: path,
            fill: color,
            stroke: color,
            strokeWidth: markerStrokeWidth,
            strokeLinecap: "round",
            strokeLinejoin: "round"
        })));
        return id;
    };
    const connectorElements = connectors.map((connector)=>{
        let markerStart;
        let markerEnd;
        if (connector.arrow === 'start' || connector.arrow === 'both') {
            markerStart = createMarkerId(connector.strokeColor, 'start', connector.markerSize, connector.markerStrokeWidth);
        }
        if (connector.arrow === 'end' || connector.arrow === 'both') {
            markerEnd = createMarkerId(connector.strokeColor, 'end', connector.markerSize, connector.markerStrokeWidth);
        }
        return /*#__PURE__*/ React.createElement("line", {
            key: connector.key,
            x1: connector.start.x,
            y1: connector.start.y,
            x2: connector.end.x,
            y2: connector.end.y,
            stroke: connector.strokeColor,
            strokeWidth: connector.strokeWidth,
            strokeDasharray: connector.dashArray,
            strokeLinecap: "round",
            markerStart: markerStart ? `url(#${markerStart})` : undefined,
            markerEnd: markerEnd ? `url(#${markerEnd})` : undefined
        });
    });
    const shouldRenderSvg = connectors.length > 0 || annotationForeignObjects.length > 0;
    return /*#__PURE__*/ React.createElement("div", {
        className: classes.root,
        role: "presentation",
        "data-chart-annotation-layer": "true"
    }, shouldRenderSvg && /*#__PURE__*/ React.createElement("svg", {
        className: classes.connectorLayer,
        width: "100%",
        height: "100%",
        viewBox: `0 0 ${viewBoxWidth} ${viewBoxHeight}`,
        preserveAspectRatio: "none",
        "data-chart-annotation-svg": "true"
    }, markerDefs.length > 0 && /*#__PURE__*/ React.createElement("defs", null, markerDefs), connectorElements.length > 0 && /*#__PURE__*/ React.createElement("g", {
        "aria-hidden": "true",
        className: classes.connectorGroup
    }, connectorElements), annotationForeignObjects), measurementElements);
});
ChartAnnotationLayer.displayName = 'ChartAnnotationLayer';
