import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import { useEffect, useLayoutEffect, useMemo, useRef, useState, } from "react";
import Styles from "./Chart.module.scss";
import { ChartDataTestIds } from "./Chart.e2e";
import AnchoredTooltip from "../AnchoredTooltip";
const DEFAULT_STYLE = {
    lineColor: "#000",
    pointColor: "#000",
    textColor: "#fff",
};
function FloatingTooltip({ children, x, y, hoverOnly, height, style, }) {
    const [ope, setOpen] = useState(() => (hoverOnly ? false : true));
    const ref = useRef(null);
    const circleRef = useRef(null);
    useEffect(() => {
        const animateEl = circleRef.current.children.item(0);
        let interval;
        animateEl.addEventListener("beginEvent", () => {
            interval = setInterval(() => ref.current.updatePosition(), 1000 / 24);
        });
        animateEl.addEventListener("endEvent", () => {
            clearInterval(interval);
            ref.current.updatePosition();
        });
    }, []);
    const actions = useMemo(() => hoverOnly
        ? {
            onMouseEnter: () => setOpen(true),
            onMouseOut: () => setOpen(false),
        }
        : {}, [hoverOnly]);
    return (_jsxs(_Fragment, { children: [_jsx("circle", { ref: circleRef, r: height * 0.01, cx: x, cy: y, style: {
                    "--point-color": style.pointColor,
                }, ...actions, children: _jsx("animate", { attributeName: "cy", values: `${height};${y}`, dur: "1s" }) }), _jsx(AnchoredTooltip, { ref: ref, containInViewport: false, anchorRef: circleRef, open: ope, className: Styles.tooltipContainer, style: {
                    "--line-color": style.lineColor,
                    "--text-color": style.textColor,
                }, children: children })] }));
}
/**
 * Displays a line chart that visualizes data over time with animated points and labels.
 */
export default function ChartView({ bounds: [[startX, endX, stepsX], [startY, endY, stepsY]], data = [], points = [], label, style: groupStyle = [], }) {
    const [dim, setDIm] = useState();
    const chartRef = useRef(null);
    useLayoutEffect(() => {
        setDIm({
            width: chartRef.current.clientWidth,
            height: chartRef.current.clientHeight,
        });
    }, []);
    const { width, height } = dim || {};
    const howMuchStepsY = useMemo(() => (endY - startY) / stepsY + 1, [endY, startY, stepsY]);
    const yAxis = useMemo(() => {
        return new Array(howMuchStepsY).fill(undefined).map((_, i) => {
            return _jsx("span", { children: label.y(endY - i * stepsY) });
        });
    }, [startY, endY, stepsY, howMuchStepsY]);
    const howMuchStepsX = useMemo(() => (endX - startX) / stepsX + 1, [endX, startX, stepsX]);
    const xAxis = useMemo(() => {
        return new Array(howMuchStepsX).fill(undefined).map((_, i) => {
            return _jsx("span", { children: label.x(startX + i * stepsX) });
        });
    }, [startX, endX, stepsX]);
    const { polylines, tooltips } = useMemo(() => {
        const calculate = (end, start, overrideScale = 100) => (point) => {
            const max = end - start;
            const current = point - start;
            return (current * overrideScale) / max;
        };
        const calculateX = calculate(endX, startX, width);
        const calculateY = calculate(endY, startY, height);
        return {
            tooltips: points.map((pointsCategory, i) => {
                const style = groupStyle[i] || DEFAULT_STYLE;
                return pointsCategory.map(([x, y, label, onlyOnHover = false]) => {
                    return (_jsx(FloatingTooltip, { x: calculateX(x), y: height - calculateY(y), height: height, style: style, hoverOnly: onlyOnHover, children: label }));
                });
            }),
            polylines: data.map((lineData, i) => {
                const style = groupStyle[i] || DEFAULT_STYLE;
                const calculateLines = (yOverride) => {
                    return lineData
                        .map(([x, y]) => `${calculateX(x)},${yOverride === undefined ? height - calculateY(y) : yOverride}`)
                        .join(" ");
                };
                return (_jsx("polyline", { strokeLinejoin: "round", strokeLinecap: "round", points: calculateLines(), fill: "none", strokeWidth: 5, style: {
                        "--line-color": style.lineColor,
                    }, children: _jsx("animate", { attributeName: "points", attributeType: "XML", values: [calculateLines(height), calculateLines()].join("; "), dur: "1s" }) }));
            }),
        };
    }, [data, width, height]);
    const paddingY = useMemo(() => {
        const stepSizeY = height / (howMuchStepsY - 1);
        return stepSizeY / 2;
    }, [howMuchStepsY, height]);
    const paddingX = useMemo(() => {
        const stepSizeX = width / (howMuchStepsX - 1);
        return stepSizeX / 2;
    }, [howMuchStepsX, width]);
    return (_jsxs("div", { className: Styles.chartRoot, children: [_jsx("div", { className: Styles.yAxis, "data-testid": ChartDataTestIds.Y_AXIS, children: yAxis }), _jsx("div", { ref: chartRef, className: Styles.chartContainer, children: width && (_jsxs("svg", { className: Styles.chart, viewBox: `${-paddingX} ${-paddingY} ${width + paddingX * 2} ${height + paddingY * 2}`, preserveAspectRatio: "none", children: [polylines, tooltips] })) }), "\u00A0", _jsx("div", { className: Styles.xAxis, "data-testid": ChartDataTestIds.X_AXIS, children: xAxis })] }));
}
//# sourceMappingURL=Chart.view.js.map