const Charts = (() => {
    function makeCurve(pts, stroke, fill, w, h) {
        if (!pts || pts.length < 2) return '';
        const xs = pts.map((_, i) => (i / (pts.length - 1)) * w);
        const ys = pts.map(v => h - (v / 100) * (h - 6) - 3);
        const wy = h - (70 / 100) * (h - 6) - 3;
        let d = `M${xs[0]} ${ys[0]}`;
        for (let i = 1; i < pts.length; i++) {
            const cx = (xs[i - 1] + xs[i]) / 2;
            d += ` C${cx} ${ys[i - 1]},${cx} ${ys[i]},${xs[i]} ${ys[i]}`;
        }
        const uid = Math.random().toString(36).slice(2);
        return `<defs>
            <linearGradient id="g${uid}" x1="0" y1="0" x2="0" y2="1">
                <stop offset="0%" stop-color="${fill}" stop-opacity=".4"/>
                <stop offset="100%" stop-color="${fill}" stop-opacity=".02"/>
            </linearGradient>
        </defs>
        <line x1="0" y1="${wy}" x2="${w}" y2="${wy}"
              stroke="var(--warn)" stroke-width=".8" stroke-dasharray="3,3" opacity=".5"/>
        <path d="${d} L${xs.at(-1)} ${h} L${xs[0]} ${h}Z" fill="url(#g${uid})"/>
        <path d="${d}" fill="none" stroke="${stroke}" stroke-width="1.6"
              stroke-linecap="round" stroke-linejoin="round"/>
        <circle cx="${xs.at(-1)}" cy="${ys.at(-1)}" r="2.5" fill="${stroke}"/>`;
    }

    function historyToCpuPts(history) {
        return history.map(h => h.cpu_percent ?? 0);
    }

    function historyToMemPts(history) {
        return history.map(h => {
            if (!h.memory_total || h.memory_total === 0) return 0;
            return (h.memory_used / h.memory_total) * 100;
        });
    }

    function renderChart(svgEl, pts, color) {
        if (!svgEl) return;
        const cs = getComputedStyle(document.documentElement);
        const c = cs.getPropertyValue(color).trim() || color;
        svgEl.innerHTML = makeCurve(pts, c, c, 200, 52);
    }

    return { makeCurve, historyToCpuPts, historyToMemPts, renderChart };
})();
