import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import { useRef, useState, useEffect } from 'react';
import './BarChart.scss';
import Typography from '../../Typography';
import Icon from '../../Icon';
import { truncateText } from '../../../utils/truncateText/truncateText';
import { convertToBytes } from '../../../utils/convertToBytes/convertToBytes';
import { convertToGB } from '../../../utils/convertToGB/convertToGB';
import { convertToKB } from '../../../utils/convertToKB/convertToKB';
import { convertToTB } from '../../../utils/convertToTB/convertToTB';
import { convertToMB } from '../../../utils/convertToMB/convertToMB';
const BarChart = ({ data, isYaxisSticky = false, barWidth, height, barGap = 20, colors = [], xAxisLabel, isTruncateText = true, yAxisLabel, padding = 20, yAxisDivisions = 5, barBorderRadius = 0, legend = true, showXAxisLabels = true, icons = [], iconSize, legendPosition = 'bottom', legendGap = 5, extendBarChartRightWidth = 0, isYAxisValuePercentage = false, selectedBar, setSelectedBar, onSelectedBar, totalLabel = 'Total Execution', customToolTip = false, isOnclick = false, isDashboardVersions, type = '', isMemory, tooltipWidth = 'fit-content', }) => {
    const tooltipRef = useRef(null);
    const [hoveredLegendIndex, setHoveredLegendIndex] = useState(null);
    const [isHoveringBar, setIsHoveringBar] = useState(false);
    useEffect(() => {
        const handleScroll = () => {
            const tooltip = tooltipRef.current;
            if (tooltip && isHoveringBar) {
                tooltip.style.display = 'none';
            }
        };
        window.addEventListener('scroll', handleScroll, true);
        return () => window.removeEventListener('scroll', handleScroll, true);
    }, [isHoveringBar]);
    const getHighestPriorityMemoryUnit = (data) => {
        const priority = ['TB', 'GB', 'MB', 'KB'];
        for (const unit of priority) {
            const found = data.some((item) => typeof item.value === 'string' &&
                item.value.toLowerCase().includes(unit.toLowerCase()));
            if (found) {
                return unit;
            }
        }
        return null;
    };
    const unit = getHighestPriorityMemoryUnit(data);
    const normalizedData = data.map((item) => {
        if (typeof item.value === 'string') {
            let normalizedValue = 0;
            if (type === 'memory') {
                normalizedValue = convertToGB(item.value);
            }
            else if (isMemory) {
                switch (unit) {
                    case 'TB':
                        normalizedValue = convertToTB(item.value);
                        break;
                    case 'GB':
                        normalizedValue = convertToGB(item.value);
                        break;
                    case 'MB':
                        normalizedValue = convertToMB(item.value);
                        break;
                    case 'KB':
                        normalizedValue = convertToKB(item.value);
                        break;
                }
            }
            else {
                normalizedValue = parseFloat(item.value);
            }
            return {
                ...item,
                normalizedValue,
            };
        }
        return {
            ...item,
            normalizedValue: item.value,
        };
    });
    let totalBytes = 0;
    if (type === 'memory') {
        totalBytes = data.reduce((acc, item) => {
            if (typeof item.value === 'string') {
                return acc + convertToBytes(item.value);
            }
            else {
                return acc + Number(item.value) * 1024 * 1024 * 1024;
            }
        }, 0);
    }
    const totalMB = totalBytes / (1024 * 1024);
    const totalMemoryDisplay = totalMB < 1024
        ? `${Math.round(totalMB)} mb`
        : `${(totalMB / 1024).toFixed(1)} gb`;
    let maxValue = Math.max(...normalizedData.map((item) => item.normalizedValue));
    if (type === 'memory') {
        maxValue = Math.max(maxValue, 1);
    }
    else {
        maxValue = Math.max(maxValue, yAxisDivisions);
    }
    const topPadding = 40;
    const leftPadding = 40;
    const totalBarWidth = normalizedData.length * barWidth + (normalizedData.length - 1) * barGap;
    const chartWidth = totalBarWidth +
        (isYaxisSticky ? leftPadding : leftPadding * 2 + 10) +
        extendBarChartRightWidth;
    const id = Date.now();
    const renderGradients = (gradients) => {
        return gradients
            .filter((gradient) => gradient.length > 1)
            .map((gradient, index) => (_jsx("defs", { children: _jsx("linearGradient", { id: `gradient-${id}-${type}-${index}`, x1: "0%", y1: "0%", x2: "0%", y2: "100%", children: gradient.map((color, i) => (_jsx("stop", { offset: `${(i / (gradient.length - 1)) * 100}%`, stopColor: color }, `${index}-${i}`))) }) }, index)));
    };
    const getFillColor = (index) => {
        if (!colors.length)
            return 'grey';
        const colorGroup = colors[index % colors.length];
        return colorGroup?.length === 1
            ? colorGroup[0]
            : `url(#gradient-${id}-${type}-${index % colors.length})`;
    };
    const handleMouseEnter = (label, value, id, percent, versions) => {
        setIsHoveringBar(true);
        const tooltip = tooltipRef.current;
        if (tooltip) {
            tooltip.style.display = 'block';
            if (customToolTip) {
                tooltip.innerHTML = `<div>
          <div><Typography fontWeight='semi-bold'>${label}</Typography></div>
          <div><Typography>${id ? id : ''}</Typography></div>
          <div><Typography>${totalLabel} : ${value} ${percent ? '(' + percent + '%)' : ''}</Typography></div>
        </div>`;
            }
            else if (isDashboardVersions) {
                const versionsList = versions ? versions.join(', ') : '';
                tooltip.innerHTML = `
        <div>
          <div><Typography>${totalLabel} : ${value}</Typography></div>
          ${versionsList
                    ? `<div><Typography>Versions : ${versionsList}</Typography></div>`
                    : ''}
        </div>`;
            }
            else {
                if (type === 'memory') {
                    tooltip.innerHTML = `<strong>${label}</strong>: ${value} / ${totalMemoryDisplay}`;
                }
                else {
                    tooltip.innerHTML = `<strong>${label}</strong>: ${value} ${isYAxisValuePercentage ? '%' : ''}`;
                }
            }
        }
    };
    const handleMouseMove = (e, isLastBar = false) => {
        const tooltip = tooltipRef.current;
        if (tooltip) {
            const rect = tooltip.parentElement?.getBoundingClientRect();
            const xOffset = window.scrollX;
            const yOffset = window.scrollY;
            const isSingleBar = normalizedData?.length === 1;
            const tooltipX = isSingleBar || !isLastBar
                ? e.clientX - (rect?.left || 0) + xOffset + 10
                : e.clientX - (rect?.left || 0) + xOffset - tooltip?.offsetWidth - 10;
            const tooltipY = e.clientY - (rect?.top || 0) + yOffset - 20;
            tooltip.style.left = `${tooltipX}px`;
            tooltip.style.top = `${tooltipY}px`;
        }
    };
    const handleMouseLeave = () => {
        setIsHoveringBar(false);
        const tooltip = tooltipRef.current;
        if (tooltip) {
            tooltip.style.display = 'none';
        }
    };
    const handleSelectLabel = (label, item) => {
        if (setSelectedBar) {
            setSelectedBar(label);
        }
        if (isOnclick) {
            onSelectedBar?.(label, item);
        }
    };
    const handleXaxisMouseEnter = (item) => {
        if (isTruncateText) {
            const displayedText = truncateText(item, 10);
            const isActuallyTruncated = displayedText.endsWith('...');
            if (isActuallyTruncated) {
                const tooltip = tooltipRef.current;
                if (tooltip) {
                    tooltip.style.display = 'block';
                    tooltip.innerHTML = item;
                }
            }
        }
    };
    const handleXaxisMouseMove = (e, item, index) => {
        if (isTruncateText) {
            const displayedText = truncateText(item, 10);
            const isActuallyTruncated = displayedText.endsWith('...');
            if (isActuallyTruncated) {
                handleMouseMove(e, index === normalizedData.length - 1);
            }
        }
    };
    const renderYAxis = () => (_jsxs(_Fragment, { children: [Array.from({ length: yAxisDivisions + 1 }).map((_, i) => {
                const yAxisLabelYPosition = height - (i / yAxisDivisions) * height + topPadding + 4;
                const yAxisValue = (i * maxValue) / yAxisDivisions;
                const formattedValue = type === 'memory'
                    ? yAxisValue.toFixed(1)
                    : isYAxisValuePercentage
                        ? `${yAxisValue.toFixed(0).padStart(2, '0')}%`
                        : yAxisValue.toFixed(0).padStart(2, '0');
                return (_jsx("text", { x: 50, y: yAxisLabelYPosition, fill: "black", textAnchor: "middle", className: "ff-bar-chart-labels", children: formattedValue }, i));
            }), yAxisLabel && (_jsx("text", { x: -(height / 2 + 35), y: isYaxisSticky ? 20 : leftPadding - 30, transform: "rotate(-90)", fill: "black", textAnchor: "middle", alignmentBaseline: "middle", className: "ff-bar-chart-labels", children: yAxisLabel }))] }));
    return (_jsxs("div", { className: "ff-bar-chart-container", children: [_jsx("div", { ref: tooltipRef, className: "ff-bar-chart-tooltip", style: { width: tooltipWidth } }), legend && legendPosition === 'top' && (_jsx("div", { className: "ff-legend-container", children: _jsx("div", { className: "ff-bar-chart-legend", style: { gap: `${legendGap}px` }, children: normalizedData.map((item, index) => (_jsxs("div", { className: "ff-bar-chart-legend-item", onMouseEnter: () => setHoveredLegendIndex(index), onMouseLeave: () => setHoveredLegendIndex(null), children: [icons[index] && typeof icons[index] === 'string' ? (_jsx(Icon, { name: String(icons[index]), width: iconSize, height: iconSize })) : (_jsx("span", { className: "ff-bar-chart-legend-item-circle", style: {
                                    backgroundColor: colors[index % colors.length]?.[0] || 'grey',
                                } })), _jsx(Typography, { as: "div", fontSize: 10, fontWeight: "regular", className: "ff-legend-label", children: item.label })] }, item.label))) }) })), isYaxisSticky ? (_jsxs("div", { className: "ff-bar-chart-wrapper", children: [_jsx("div", { className: "ff-y-axis", children: _jsx("svg", { width: 60, height: height + topPadding + (xAxisLabel ? 20 : 0), children: renderYAxis() }) }), _jsx("div", { className: "ff-chart-scrollable", children: _jsxs("svg", { width: chartWidth, height: height +
                                topPadding +
                                5 +
                                (showXAxisLabels ? 20 : 0) +
                                (xAxisLabel ? 20 : 0), children: [Array.isArray(colors) &&
                                    colors.length > 0 &&
                                    renderGradients(colors), normalizedData.map((item, index) => {
                                    const computedBarHeight = (item.normalizedValue / maxValue) * height;
                                    const minBarHeight = 2;
                                    const barHeight = item.normalizedValue < 1 ? minBarHeight : computedBarHeight;
                                    const barX = index * (barWidth + barGap) + padding;
                                    const barY = height - barHeight + topPadding;
                                    const iconWidth = iconSize || 20;
                                    const iconX = barX + barWidth / 2 - iconWidth / 2;
                                    const iconY = barY - iconWidth;
                                    const isSelected = selectedBar === item.label;
                                    const isHovered = hoveredLegendIndex === index;
                                    return (_jsxs("g", { children: [icons[index] && typeof icons[index] === 'string' && (_jsx("g", { onMouseEnter: () => handleMouseEnter(item.label, type === 'memory'
                                                    ? item.value
                                                    : item.normalizedValue, item.id, item.percent, item.versions), onMouseMove: (e) => handleMouseMove(e, index === normalizedData.length - 1), onMouseLeave: handleMouseLeave, children: _jsx(Icon, { name: String(icons[index]), x: String(iconX), y: String(iconY), width: iconWidth, height: iconWidth, chartIcon: true }) })), _jsx("rect", { x: barX, y: barY, width: barWidth, height: barHeight, fill: getFillColor(index), rx: barBorderRadius, ry: barBorderRadius, style: {
                                                    strokeWidth: isSelected ? 3 : 0,
                                                    opacity: hoveredLegendIndex === null || isHovered ? 1 : 0.3,
                                                    cursor: isOnclick ? 'pointer' : 'default',
                                                    transition: 'opacity 0.5s ease',
                                                }, onMouseEnter: () => handleMouseEnter(item.label, type === 'memory' || isMemory
                                                    ? item.value
                                                    : item.normalizedValue, item.id, item.percent, item.versions), onMouseMove: (e) => handleMouseMove(e, index === normalizedData.length - 1), onMouseLeave: handleMouseLeave, onClick: () => handleSelectLabel(item.label, item) }), isSelected && isOnclick && (_jsx("rect", { x: barX, y: barY, width: barWidth, height: barHeight, fill: "var(--select-chart-highlight-color)", rx: barBorderRadius, ry: barBorderRadius, onMouseEnter: () => handleMouseEnter(item.label, type === 'memory'
                                                    ? item.value
                                                    : item.normalizedValue, item.id, item.percent, item.versions), onMouseMove: (e) => handleMouseMove(e, index === normalizedData.length - 1), onMouseLeave: handleMouseLeave })), showXAxisLabels && (_jsx("text", { onMouseEnter: () => handleXaxisMouseEnter(item.label), onMouseMove: (e) => handleXaxisMouseMove(e, item.label, index), onMouseLeave: handleMouseLeave, x: index === 0
                                                    ? barX
                                                    : index === normalizedData.length - 1
                                                        ? barX + barWidth
                                                        : barX + barWidth / 2, y: height + topPadding + 15, className: "ff-bar-chart-labels", fill: isSelected ? 'var(--brand-color)' : 'black', fontWeight: isSelected ? 'bold' : 'normal', textAnchor: index === 0 ? 'start' : 'middle', children: isTruncateText
                                                    ? truncateText(item.label, 10)
                                                    : item.label }))] }, index));
                                }), _jsx("line", { x1: isYaxisSticky ? 0 : padding, y1: height + topPadding, x2: chartWidth, y2: height + topPadding, stroke: "#D9D9D9", strokeWidth: "1" }), !isYaxisSticky && xAxisLabel && (_jsx("text", { x: chartWidth / 2, y: height + topPadding + (showXAxisLabels ? 40 : 20), fontSize: "12", fill: "black", textAnchor: "middle", className: "ff-bar-chart-labels", children: xAxisLabel }))] }) }), _jsx("div", { className: "ff-bar-chart-x-axis-label", children: xAxisLabel })] })) : (_jsx("div", { children: _jsxs("svg", { width: chartWidth, height: height +
                        topPadding +
                        5 +
                        (showXAxisLabels ? 20 : 0) +
                        (xAxisLabel ? 20 : 0), children: [Array.isArray(colors) &&
                            colors.length > 0 &&
                            renderGradients(colors), Array.from({ length: yAxisDivisions + 1 }).map((_, i) => {
                            const yAxisLabelYPosition = height - (i / yAxisDivisions) * height + topPadding + 4;
                            const yAxisValue = (i * maxValue) / yAxisDivisions;
                            const formattedValue = type === 'memory'
                                ? yAxisValue.toFixed(1)
                                : isYAxisValuePercentage
                                    ? `${yAxisValue.toFixed(0).padStart(2, '0')}%`
                                    : yAxisValue.toFixed(0).padStart(2, '0');
                            return (_jsx("text", { x: leftPadding, y: yAxisLabelYPosition, fill: "black", textAnchor: "middle", className: "ff-bar-chart-labels", children: formattedValue }, i));
                        }), normalizedData.map((item, index) => {
                            const computedBarHeight = (item.normalizedValue / maxValue) * height;
                            const minBarHeight = 2;
                            const barHeight = item.normalizedValue < 1 ? minBarHeight : computedBarHeight;
                            const barX = index * (barWidth + barGap) + leftPadding + padding;
                            const barY = height - barHeight + topPadding;
                            const iconWidth = iconSize || 20;
                            const iconX = barX + barWidth / 2 - iconWidth / 2;
                            const iconY = barY - iconWidth;
                            const isSelected = selectedBar === item.label;
                            const isHovered = hoveredLegendIndex === index;
                            return (_jsxs("g", { children: [icons[index] && typeof icons[index] === 'string' && (_jsx("g", { onMouseEnter: () => handleMouseEnter(item.label, type === 'memory' ? item.value : item.normalizedValue, item.id, item.percent, item.versions), onMouseMove: (e) => handleMouseMove(e, index === normalizedData.length - 1), onMouseLeave: handleMouseLeave, onClick: () => handleSelectLabel(item.label, item), children: _jsx(Icon, { name: String(icons[index]), x: String(iconX), y: String(iconY), width: iconWidth, height: iconWidth, chartIcon: true }) })), _jsx("rect", { x: barX, y: barY, width: barWidth, height: barHeight, fill: getFillColor(index), rx: barBorderRadius, ry: barBorderRadius, style: {
                                            strokeWidth: isSelected ? 3 : 0,
                                            opacity: hoveredLegendIndex === null || isHovered ? 1 : 0.3,
                                            cursor: isOnclick ? 'pointer' : 'default',
                                            transition: 'opacity 0.5s ease',
                                        }, onMouseEnter: () => handleMouseEnter(item.label, type === 'memory' || isMemory
                                            ? item.value
                                            : item.normalizedValue, item.id, item.percent, item.versions), onMouseMove: (e) => handleMouseMove(e, index === normalizedData.length - 1), onMouseLeave: handleMouseLeave, onClick: () => handleSelectLabel(item.label, item) }), isSelected && isOnclick && (_jsx("rect", { x: barX, y: barY, width: barWidth, height: barHeight, fill: "var(--select-chart-highlight-color)", rx: barBorderRadius, ry: barBorderRadius, onMouseEnter: () => handleMouseEnter(item.label, type === 'memory' ? item.value : item.normalizedValue, item.id, item.percent, item.versions), onMouseMove: (e) => handleMouseMove(e, index === normalizedData.length - 1), onMouseLeave: handleMouseLeave })), showXAxisLabels && (_jsx("g", { children: _jsx("text", { x: index === 0
                                                ? barX
                                                : index === normalizedData.length - 1
                                                    ? barX + barWidth
                                                    : barX + barWidth / 2, y: height + topPadding + 15, className: "ff-bar-chart-labels", fill: isSelected ? 'var(--brand-color)' : 'black', fontWeight: isSelected ? 'bold' : 'normal', textAnchor: index === 0 ? 'start' : 'middle', onMouseEnter: () => handleXaxisMouseEnter(item.label), onMouseMove: (e) => handleXaxisMouseMove(e, item.label, index), onMouseLeave: handleMouseLeave, children: isTruncateText
                                                ? truncateText(item.label, 10)
                                                : item.label }) }))] }, index));
                        }), _jsx("line", { x1: 60, y1: height + topPadding, x2: chartWidth, y2: height + topPadding, stroke: "#D9D9D9", strokeWidth: "1" }), xAxisLabel && (_jsx("text", { x: chartWidth / 2, y: height + topPadding + (showXAxisLabels ? 40 : 20), fontSize: "12", fill: "black", textAnchor: "middle", className: "ff-bar-chart-labels", children: xAxisLabel })), yAxisLabel && (_jsx("text", { x: -(height / 2 + 35), y: leftPadding - 30, transform: "rotate(-90)", fill: "black", textAnchor: "middle", alignmentBaseline: "middle", className: "ff-bar-chart-labels", children: yAxisLabel }))] }) })), legend && legendPosition === 'bottom' && (_jsx("div", { className: "ff-legend-container", children: _jsx("div", { className: "ff-bar-chart-legend", style: { gap: `${legendGap}px` }, children: data.map((item, index) => (_jsxs("div", { className: "ff-bar-chart-legend-item", onMouseEnter: () => setHoveredLegendIndex(index), onMouseLeave: () => setHoveredLegendIndex(null), children: [icons[index] && typeof icons[index] === 'string' ? (_jsx(Icon, { name: String(icons[index]), width: iconSize, height: iconSize })) : (_jsx("span", { className: "ff-bar-chart-legend-item-circle", style: {
                                    backgroundColor: colors[index % colors.length]?.[0] || 'grey',
                                } })), _jsx("div", { children: _jsx(Typography, { as: "div", fontSize: 10, fontWeight: "regular", className: "ff-legend-label", children: item.label }) })] }, item.label))) }) }))] }));
};
export default BarChart;
//# sourceMappingURL=BarChart.js.map