<script lang="ts">
import { onMount } from "svelte";
import { formatDataVolume, formatDuration, formatNumber } from "./Formatting";
import { color_by_name } from "./Util";
import {
	Chart,
	PointElement,
	LineElement,
	LinearScale,
	CategoryScale,
	LineController,
	Filler,
	Tooltip,
	Legend,
    type Tick,
} from "chart.js"
Chart.register(
	PointElement,
	LineElement,
	LinearScale,
	CategoryScale,
	LineController,
	Filler,
	Tooltip,
	Legend,
)

let chart_element: HTMLCanvasElement = $state()
let chart_object: Chart

let {
	data_type = "",
	legend = true,
	tooltips = true,
	ticks = true,
	animations = true,
	height = "300px"
}: {
	data_type?: string;
	legend?: boolean;
	tooltips?: boolean;
	ticks?: boolean;
	animations?: boolean;
	height?: string;
} = $props();

export const chart = () => {
	return chart_object
}
export const data = () => {
	return chart_object.data
}
export const update = () => {
	return chart_object.update()
}

Chart.defaults.color = color_by_name("body_text_color");
Chart.defaults.font.size = 15;
Chart.defaults.font.family = "system-ui, sans-serif";
Chart.defaults.maintainAspectRatio = false;
Chart.defaults.plugins.tooltip.mode = "index";
Chart.defaults.plugins.tooltip.axis = "x";
Chart.defaults.plugins.tooltip.intersect = false;

onMount(() => {
	chart_object = new Chart(
		chart_element.getContext("2d"),
		{
			type: 'line',
			data: {
				labels: [],
				datasets: [],
			},
			options: {
				responsive: true,
				// Only update the chart 100ms after the last time the container
				// is resized. This fixes the stuttering that happens when the
				// chart updates each frame
				resizeDelay: 100,
				plugins: {
					legend: {
						display: legend,
						labels: {
							boxWidth: 12,
							boxHeight: 12,
						}
					},
					tooltip: {
						enabled: tooltips,
						itemSort: (a, b): number => {
							return <number>b.raw - <number>a.raw
						},
					},
				},
				layout: {
					padding: {
						left: 4,
						right: 4,
					}
				},
				scales: {
					y: {
						type: "linear",
						display: true,
						position: "left",
						ticks: {
							callback: function (value: number, index: number, values: Tick[]) {
								if (data_type == "bytes") {
									return formatDataVolume(value, 3);
								} else if (data_type === "duration") {
									return formatDuration(value, 2);
								}
								return formatNumber(value, 3);
							},
						},
						beginAtZero: true,
						grid: {
							display: true,
							color: color_by_name("separator"),
						},
					},
					x: {
						display: true,
						ticks: {
							display: ticks,
							sampleSize: 1,
							padding: 4,
							minRotation: 0,
							maxRotation: 0
						},
						grid: {
							display: false,
						}
					}
				},
			}
		}
	);

	if (!animations) {
		chart_object.options.animation = false
		chart_object.options.transitions.active.animation.duration = 0
	}
})
</script>

<div class="chart-container" style="height: {height};">
	<canvas bind:this={chart_element}></canvas>
</div>

<style>
.chart-container {
	position: relative;
	width: 100%;
}
</style>
