import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import * as echarts from 'echarts';
import ReactECharts from 'echarts-for-react';
import { Box, Text, Label } from '@primer/react';
// ── Gradient palette ────────────────────────────────────────────────
const SERIES_COLORS = [
    {
        line: '#5470C6',
        gradientStart: 'rgba(84,112,198,0.7)',
        gradientEnd: 'rgba(84,112,198,0.02)',
    },
    {
        line: '#91CC75',
        gradientStart: 'rgba(145,204,117,0.7)',
        gradientEnd: 'rgba(145,204,117,0.02)',
    },
    {
        line: '#EE6666',
        gradientStart: 'rgba(238,102,102,0.7)',
        gradientEnd: 'rgba(238,102,102,0.02)',
    },
    {
        line: '#FAC858',
        gradientStart: 'rgba(250,200,88,0.7)',
        gradientEnd: 'rgba(250,200,88,0.02)',
    },
    {
        line: '#73C0DE',
        gradientStart: 'rgba(115,192,222,0.7)',
        gradientEnd: 'rgba(115,192,222,0.02)',
    },
    {
        line: '#FC8452',
        gradientStart: 'rgba(252,132,82,0.7)',
        gradientEnd: 'rgba(252,132,82,0.02)',
    },
    {
        line: '#9A60B4',
        gradientStart: 'rgba(154,96,180,0.7)',
        gradientEnd: 'rgba(154,96,180,0.02)',
    },
    {
        line: '#EA7CCC',
        gradientStart: 'rgba(234,124,204,0.7)',
        gradientEnd: 'rgba(234,124,204,0.02)',
    },
];
// ── Helpers ─────────────────────────────────────────────────────────
/** Group metrics by metric_type, then by metric_name within each type. */
function groupByType(metrics) {
    const byType = new Map();
    for (const m of metrics) {
        const mtype = m.metric_type || 'other';
        if (!byType.has(mtype))
            byType.set(mtype, new Map());
        const nameMap = byType.get(mtype);
        const key = m.metric_name || '(unnamed)';
        if (!nameMap.has(key))
            nameMap.set(key, []);
        nameMap.get(key).push({
            ts: new Date(m.timestamp).getTime(),
            value: m.value,
        });
    }
    // Sort points chronologically within each name group.
    for (const nameMap of byType.values()) {
        for (const points of nameMap.values()) {
            points.sort((a, b) => a.ts - b.ts);
        }
    }
    return byType;
}
/** Human-friendly label for a metric type. */
function typeTitle(mtype) {
    switch (mtype) {
        case 'sum':
            return 'Counters (sum)';
        case 'histogram':
            return 'Histograms';
        case 'gauge':
            return 'Gauges';
        case 'exponentialHistogram':
            return 'Exponential Histograms';
        default:
            return mtype.charAt(0).toUpperCase() + mtype.slice(1);
    }
}
/** Label variant for the type badge. */
function typeVariant(mtype) {
    switch (mtype) {
        case 'gauge':
            return 'accent';
        case 'sum':
            return 'attention';
        case 'histogram':
            return 'secondary';
        case 'exponentialHistogram':
            return 'success';
        default:
            return 'primary';
    }
}
/** Preferred display order. Types not listed appear at the end. */
const TYPE_ORDER = {
    sum: 0,
    histogram: 1,
    gauge: 2,
    exponentialHistogram: 3,
};
// ── Build ECharts option per type ──────────────────────────────────
function buildOption(mtype, nameMap) {
    const names = [...nameMap.keys()];
    const baseLegend = {
        data: names,
        top: 6,
        textStyle: { fontSize: 11 },
    };
    const baseGrid = { left: 50, right: 20, top: 40, bottom: 30 };
    const baseTooltip = {
        trigger: 'axis',
        axisPointer: { type: 'cross', label: { backgroundColor: '#6a7985' } },
    };
    const baseXAxis = {
        type: 'time',
        boundaryGap: false,
        axisLine: { lineStyle: { color: '#ccc' } },
        axisLabel: { fontSize: 10 },
    };
    const baseYAxis = {
        type: 'value',
        splitLine: { lineStyle: { type: 'dashed', color: '#e8e8e8' } },
        axisLine: { show: false },
        axisLabel: { fontSize: 10 },
    };
    if (mtype === 'histogram' || mtype === 'exponentialHistogram') {
        // ── Bar chart ──
        const series = names.map((name, idx) => {
            const palette = SERIES_COLORS[idx % SERIES_COLORS.length];
            const points = nameMap.get(name) ?? [];
            return {
                name,
                type: 'bar',
                barMaxWidth: 20,
                itemStyle: {
                    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                        { offset: 0, color: palette.gradientStart },
                        { offset: 1, color: palette.line },
                    ]),
                    borderRadius: [2, 2, 0, 0],
                },
                emphasis: { focus: 'series' },
                data: points.map(p => [p.ts, p.value]),
            };
        });
        return {
            tooltip: baseTooltip,
            legend: baseLegend,
            grid: baseGrid,
            xAxis: { ...baseXAxis, boundaryGap: true },
            yAxis: baseYAxis,
            series,
        };
    }
    if (mtype === 'gauge') {
        // ── Simple line chart (no area) ──
        const series = names.map((name, idx) => {
            const palette = SERIES_COLORS[idx % SERIES_COLORS.length];
            const points = nameMap.get(name) ?? [];
            return {
                name,
                type: 'line',
                smooth: true,
                symbol: 'circle',
                symbolSize: 5,
                showSymbol: true,
                lineStyle: { width: 2, color: palette.line },
                itemStyle: { color: palette.line },
                emphasis: { focus: 'series' },
                data: points.map(p => [p.ts, p.value]),
            };
        });
        return {
            tooltip: baseTooltip,
            legend: baseLegend,
            grid: baseGrid,
            xAxis: baseXAxis,
            yAxis: baseYAxis,
            series,
        };
    }
    // ── Default (sum / other): area-line with gradient ──
    const series = names.map((name, idx) => {
        const palette = SERIES_COLORS[idx % SERIES_COLORS.length];
        const points = nameMap.get(name) ?? [];
        return {
            name,
            type: 'line',
            smooth: true,
            symbol: 'circle',
            symbolSize: 5,
            showSymbol: false,
            lineStyle: { width: 2, color: palette.line },
            itemStyle: { color: palette.line },
            areaStyle: {
                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                    { offset: 0, color: palette.gradientStart },
                    { offset: 1, color: palette.gradientEnd },
                ]),
            },
            emphasis: { focus: 'series' },
            data: points.map(p => [p.ts, p.value]),
        };
    });
    return {
        tooltip: baseTooltip,
        legend: baseLegend,
        grid: baseGrid,
        xAxis: baseXAxis,
        yAxis: baseYAxis,
        series,
    };
}
function computeStats(nameMap) {
    let total = 0;
    let count = 0;
    let startTs = null;
    let endTs = null;
    for (const points of nameMap.values()) {
        for (const p of points) {
            total += p.value;
            count += 1;
            if (startTs === null || p.ts < startTs)
                startTs = p.ts;
            if (endTs === null || p.ts > endTs)
                endTs = p.ts;
        }
    }
    return { total, count, startTs, endTs };
}
function formatTs(ts) {
    return new Date(ts).toLocaleTimeString(undefined, {
        hour: '2-digit',
        minute: '2-digit',
        second: '2-digit',
    });
}
function formatDuration(ms) {
    if (ms < 1000)
        return `${ms}ms`;
    const s = Math.round(ms / 1000);
    if (s < 60)
        return `${s}s`;
    const m = Math.floor(s / 60);
    const rem = s % 60;
    return rem > 0 ? `${m}m ${rem}s` : `${m}m`;
}
// ── Component ───────────────────────────────────────────────────────
export const OtelMetricsChart = ({ metrics, height = 240, }) => {
    if (!metrics || metrics.length === 0) {
        return (_jsx(ReactECharts, { echarts: echarts, option: {
                title: {
                    text: 'No metrics data',
                    left: 'center',
                    top: 'center',
                    textStyle: { color: '#999', fontSize: 14, fontWeight: 'normal' },
                },
            }, style: { width: '100%', height: `${height}px` }, notMerge: true }));
    }
    const byType = groupByType(metrics);
    // Sort types in a stable, user-friendly order.
    const sortedTypes = [...byType.keys()].sort((a, b) => (TYPE_ORDER[a] ?? 99) - (TYPE_ORDER[b] ?? 99));
    return (_jsx(Box, { sx: {
            display: 'grid',
            gridTemplateColumns: '1fr 1fr',
            gap: 2,
        }, children: sortedTypes.map(mtype => {
            const nameMap = byType.get(mtype);
            const option = buildOption(mtype, nameMap);
            const stats = computeStats(nameMap);
            const durationMs = stats.startTs !== null && stats.endTs !== null
                ? stats.endTs - stats.startTs
                : null;
            return (_jsxs(Box, { children: [_jsxs(Box, { sx: {
                            display: 'flex',
                            alignItems: 'center',
                            gap: 2,
                            px: 1,
                            mb: 1,
                        }, children: [_jsx(Label, { size: "small", variant: typeVariant(mtype), children: mtype }), _jsx(Text, { sx: { fontSize: 1, fontWeight: 'bold', color: 'fg.muted' }, children: typeTitle(mtype) }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.subtle' }, children: ["(", [...nameMap.keys()].join(', '), ")"] })] }), _jsxs(Box, { sx: {
                            display: 'flex',
                            alignItems: 'center',
                            gap: 3,
                            px: 1,
                            mb: 1,
                        }, children: [_jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: [_jsx(Text, { as: "span", sx: { fontWeight: 'bold', color: 'fg.default' }, children: "Sum:" }), ' ', stats.total.toLocaleString(undefined, {
                                        maximumFractionDigits: 4,
                                    })] }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: [_jsx(Text, { as: "span", sx: { fontWeight: 'bold', color: 'fg.default' }, children: "Points:" }), ' ', stats.count] }), stats.startTs !== null && stats.endTs !== null && (_jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: [_jsx(Text, { as: "span", sx: { fontWeight: 'bold', color: 'fg.default' }, children: "Interval:" }), ' ', formatTs(stats.startTs), " \u2192 ", formatTs(stats.endTs), durationMs !== null && durationMs > 0 && (_jsxs(Text, { as: "span", sx: { color: 'fg.subtle' }, children: [' ', "(", formatDuration(durationMs), ")"] }))] }))] }), _jsx(ReactECharts, { echarts: echarts, option: option, style: { width: '100%', height: `${height}px` }, notMerge: true })] }, mtype));
        }) }));
};
export default OtelMetricsChart;
