import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useState, useRef } from 'react';
import { Bar, BarChart, CartesianGrid, ResponsiveContainer, Tooltip, XAxis, YAxis, } from 'recharts';
import styled, { useTheme } from 'styled-components';
import { spacing, Stack, Wrap } from '../../spacing';
import { chartColors, fontSize } from '../../style/theme';
import { Box } from '../box/Box';
import { useChartLegend } from '../chartlegend/ChartLegendWrapper';
import { ConstrainedText } from '../constrainedtext/Constrainedtext.component';
import { FormattedDateTime } from '../date/FormattedDateTime';
import { IconHelp } from '../iconhelper/IconHelper';
import { Loader } from '../loader/Loader.component';
import { Text } from '../text/Text.component';
import { BarchartTooltip } from './BarchartTooltip';
import { getTicks, useChartData } from './utils';
const CHART_CONSTANTS = {
    TICK_WIDTH_OFFSET: 4,
    BAR_SIZE: 12,
    MIN_POINT_SIZE: 3,
    DEFAULT_HEIGHT: 200,
    CHART_MARGIN: {
        left: 0,
        right: -10,
        top: 0,
        bottom: 0,
    },
};
const maxWidthTooltip = { maxWidth: '20rem' };
/* ---------------------------------- COMPONENTS ---------------------------------- */
/**
 * Get the format of the date based on the duration
 * @param duration - Duration in seconds
 * @returns Formatted string
 */
export const formatDate = (duration) => {
    if (duration <= 24 * 60 * 60) {
        return 'time';
    }
    else if (duration <= 7 * 24 * 60 * 60) {
        return 'day-month-abbreviated';
    }
    else {
        return 'chart-long-term-date';
    }
};
export const CustomTick = ({ x, y, payload, visibleTicksCount, width, type, }) => {
    const theme = useTheme();
    const tickWidth = width / visibleTicksCount - CHART_CONSTANTS.TICK_WIDTH_OFFSET;
    const centerX = x - tickWidth / 2;
    const duration = type.type === 'time'
        ? (type.timeRange.endDate.getTime() -
            type.timeRange.startDate.getTime()) /
            1000
        : 0;
    return (_jsx("foreignObject", { x: centerX, y: y - 8, width: tickWidth, color: theme.textSecondary, overflow: "visible", children: _jsx(ConstrainedText, { color: "textSecondary", text: _jsx(Text, { variant: "Smaller", children: type.type === 'time' ? (_jsx(FormattedDateTime, { format: formatDate(duration), value: new Date(payload.value) })) : (String(payload.value)) }), centered: true, tooltipStyle: {
                backgroundColor: theme.backgroundLevel1,
                padding: spacing.r10,
                borderRadius: spacing.r8,
                border: `1px solid ${theme.border}`,
                position: 'absolute',
            } }) }));
};
export const StyledResponsiveContainer = styled(ResponsiveContainer) `
  // Avoid tooltip over constrained text to be cut off
  & .recharts-surface {
    outline: none;
    overflow: visible;
  }
`;
const ChartHeader = ({ title, secondaryTitle, helpTooltip, rightTitle, }) => {
    return (_jsxs(Wrap, { children: [_jsxs(Stack, { gap: "r4", children: [_jsx(Text, { variant: "ChartTitle", children: title }), helpTooltip && (_jsx(IconHelp, { tooltipMessage: helpTooltip, overlayStyle: maxWidthTooltip })), secondaryTitle && (_jsx(Text, { color: "textSecondary", style: {
                            marginLeft: spacing.r8,
                        }, children: secondaryTitle }))] }), rightTitle && _jsx(Text, { children: rightTitle })] }));
};
const Error = ({ height }) => {
    return (_jsx(Box, { height: height, style: {
            alignItems: 'center',
            justifyContent: 'center',
            display: 'flex',
        }, children: _jsx(Text, { children: "Chart data is not available" }) }));
};
const Loading = ({ height }) => {
    return (_jsx(Box, { height: height, style: {
            alignItems: 'center',
            justifyContent: 'center',
            display: 'flex',
        }, children: _jsx(Loader, { size: "larger", children: _jsx(Text, { children: "Loading Chart Data..." }) }) }));
};
/* ---------------------------------- MAIN COMPONENT ---------------------------------- */
export const Barchart = (props) => {
    const theme = useTheme();
    const { getColor } = useChartLegend();
    const [hoveredValue, setHoveredValue] = useState();
    const chartRef = useRef(null);
    const { height = CHART_CONSTANTS.DEFAULT_HEIGHT, bars, type = { type: 'category' }, unitRange, stacked, stackedBarSort = 'default', defaultSort, tooltip, title, secondaryTitle, helpTooltip, rightTitle, isLoading, isError, } = props;
    // Create colorSet from ChartLegendWrapper
    const colorSet = bars === null || bars === void 0 ? void 0 : bars.reduce((acc, bar) => {
        const color = getColor(bar.label);
        if (color) {
            acc[bar.label] = color;
        }
        return acc;
    }, {});
    const { rechartsBars, unitLabel, roundReferenceValue, rechartsData } = useChartData(bars || [], type, colorSet || {}, stacked, defaultSort, unitRange, stackedBarSort);
    const titleWithUnit = unitLabel ? `${title} (${unitLabel})` : title;
    return (_jsxs(Stack, { direction: "vertical", style: { gap: '0' }, children: [_jsx(ChartHeader, { title: titleWithUnit, secondaryTitle: secondaryTitle, helpTooltip: helpTooltip, rightTitle: rightTitle }), isError || (!bars && !isLoading) ? (_jsx(Error, { height: height })) : isLoading ? (_jsx(Loading, { height: height })) : (_jsx(StyledResponsiveContainer, { ref: chartRef, width: "100%", height: height, children: _jsxs(BarChart, { data: rechartsData, accessibilityLayer: true, barSize: type.type === 'category'
                        ? type.gap === 0
                            ? undefined
                            : CHART_CONSTANTS.BAR_SIZE
                        : CHART_CONSTANTS.BAR_SIZE, height: height, margin: CHART_CONSTANTS.CHART_MARGIN, barCategoryGap: type.type === 'category' ? type.gap : undefined, children: [_jsx(CartesianGrid, { vertical: true, horizontal: true, verticalPoints: [0], horizontalPoints: [0], stroke: theme.border, fill: theme.backgroundLevel4, strokeWidth: 1 }), rechartsBars.map((bar) => {
                            const { fill, dataKey, stackId } = bar;
                            return (_jsx(Bar, { dataKey: dataKey, fill: chartColors[fill] || fill, minPointSize: stacked ? 0 : CHART_CONSTANTS.MIN_POINT_SIZE, stackId: stackId, isAnimationActive: false, onMouseOver: () => setHoveredValue(dataKey), onMouseLeave: () => setHoveredValue(undefined) }, dataKey));
                        }), _jsx(YAxis, { interval: 0, domain: [0, roundReferenceValue], ticks: getTicks(roundReferenceValue, false), tickFormatter: (value) => new Intl.NumberFormat('fr-FR').format(value) // Add a space as thousand separator
                            , axisLine: { stroke: theme.border }, tick: {
                                fill: theme.textSecondary,
                                fontSize: fontSize.smaller,
                            }, orientation: "right" }), _jsx(XAxis, { dataKey: "category", tick: (props) => _jsx(CustomTick, { ...props, type: type }), type: "category", interval: 0, allowDataOverflow: true, tickLine: {
                                stroke: theme.border,
                            }, axisLine: {
                                stroke: theme.border,
                            } }), _jsx(Tooltip, { content: (props) => (_jsx(BarchartTooltip, { type: type, colorSet: colorSet, tooltipProps: props, hoveredValue: hoveredValue, tooltip: tooltip, unitLabel: unitLabel, chartContainerRef: chartRef })), cursor: false })] }) }))] }));
};
