const chartInstances = {};

async function loadPieChart(endpoint, canvasId, legendId) {
    try {
        const res = await fetch(endpoint);
        if (!res.ok) throw new Error(`HTTP ${res.status}`);
        const json = await res.json();

        const canvas = document.getElementById(canvasId);
        const legend = document.getElementById(legendId);

        if (!json.top || json.top.length === 0) {
            legend.innerHTML = "<p>No data received.</p>";
            return;
        }

        const totalPercent = json.top.reduce((sum, item) => sum + item.percent, 0);
        let topData = [...json.top];
        if (totalPercent < 100) {
            topData.push({ name: "Other", percent: 100 - totalPercent });
        }

        const labels = topData.map(item => item.name);
        const data = topData.map(item => item.percent);
        const baseColors = labels.map((label, i) =>
            label === "Other" ? "#888888" : `hsl(${(i * 57) % 360}, 70%, 60%)`
        );

        if (!chartInstances[canvasId]) {
            const ctx = canvas.getContext("2d");
            chartInstances[canvasId] = new Chart(ctx, {
                type: "pie",
                data: {
                    labels,
                    datasets: [{
                        data,
                        backgroundColor: baseColors,
                        borderColor: "#fff",
                        borderWidth: 2,
                        hoverOffset: 15
                    }]
                },
                options: {
                    responsive: true,
                    plugins: {
                        legend: { display: false },
                        tooltip: {
                            enabled: true,
                            callbacks: {
                                label: ctx => `${ctx.label}: ${ctx.parsed.toFixed(2)}%`
                            }
                        }
                    }
                }
            });
            chartInstances[canvasId].hiddenSlices = new Set();
        } else {
            const chart = chartInstances[canvasId];
            chart.data.labels = labels;
            chart.data.datasets[0].data = data;
            chart.data.datasets[0].backgroundColor = baseColors;
            chart.update();
        }

        const chart = chartInstances[canvasId];

        const hiddenSlices = chart.hiddenSlices;

        legend.innerHTML = "";
        const ul = document.createElement("ul");
        ul.style.listStyle = "none";
        ul.style.padding = "0";
        ul.style.margin = "0";

        topData.forEach((item, i) => {
            const li = document.createElement("li");
            li.style.cursor = "pointer";
            li.style.display = "flex";
            li.style.alignItems = "center";
            li.style.marginBottom = "6px";
            li.style.userSelect = "none";

            const colorBox = document.createElement("span");
            colorBox.style.display = "inline-block";
            colorBox.style.width = "16px";
            colorBox.style.height = "16px";
            colorBox.style.marginRight = "8px";
            colorBox.style.borderRadius = "3px";

            const labelText = item.name === "Other" ? "Other" : item.name.split(":")[0].trim();
            li.appendChild(colorBox);
            li.appendChild(document.createTextNode(labelText));

            if (hiddenSlices.has(i)) {
                colorBox.style.backgroundColor = "#bbb";
                li.style.opacity = "0.5";
            } else {
                colorBox.style.backgroundColor = baseColors[i];
                li.style.opacity = "1";
            }

            li.addEventListener("mouseenter", () => {
                if (hiddenSlices.has(i)) return;
                chart.setActiveElements([{ datasetIndex: 0, index: i }]);
                chart.update();
            });

            li.addEventListener("mouseleave", () => {
                chart.setActiveElements([]);
                chart.update();
            });

            li.addEventListener("click", () => {
                if (hiddenSlices.has(i)) {
                    hiddenSlices.delete(i);
                } else {
                    hiddenSlices.add(i);
                }

                chart.getDatasetMeta(0).data[i].hidden = hiddenSlices.has(i);

                if (hiddenSlices.has(i)) {
                    colorBox.style.backgroundColor = "#bbb";
                    li.style.opacity = "0.5";
                } else {
                    colorBox.style.backgroundColor = baseColors[i];
                    li.style.opacity = "1";
                }

                chart.update();
            });

            ul.appendChild(li);
        });

        legend.appendChild(ul);

    } catch (err) {
        console.error(err);
        document.getElementById(legendId).innerHTML = `<p style="color:red">Error retrieving data: ${err.message}</p>`;
    }
}

function loadAllCharts() {
    loadPieChart("/stats/src-as", "pieChart1", "legend1");
    loadPieChart("/stats/src-ports", "pieChart2", "legend2");
    loadPieChart("/stats/protocol", "pieChart3", "legend3");
    loadPieChart("/stats/src-country", "pieChart4", "legend4");
    loadPieChart("/stats/etype", "pieChart5", "legend5");
}

window.addEventListener("DOMContentLoaded", () => {
    loadAllCharts();
    setInterval(loadAllCharts, 60000);
});

let chart;

async function fetchData() {
  const response = await fetch('/stats/graph');
  const jsonData = await response.json();

  const rawData = jsonData.data.map(item => {
    const date = new Date(item.t);
    return {
      x: date,
      y: item.gbps
    };
  });

  const maxVal = Math.max(...rawData.map(p => p.y));
  const scaleFactor = maxVal < 1 ? 1000 : 1;
  const unitLabel = maxVal < 1 ? 'Mbit/s' : 'Gbit/s';

  const data = rawData.map(p => ({
    x: p.x,
    y: p.y * scaleFactor
  }));

  return { data, unitLabel };
}

async function initChart() {
  const canvas = document.getElementById('liveChart');
  const ctx = canvas.getContext('2d');

  const dpr = window.devicePixelRatio || 1;
  const rect = canvas.getBoundingClientRect();
  canvas.width = rect.width * dpr;
  canvas.height = rect.height * dpr;
  ctx.scale(dpr, dpr);

  const { data, unitLabel } = await fetchData();

  chart = new Chart(ctx, {
    type: 'line',
    data: {
      datasets: [{
        label: `Network traffic (${unitLabel})`,
        data,
        borderColor: 'blue',
        backgroundColor: 'rgba(0, 0, 255, 0.1)',
        fill: true,
        pointRadius: 0,
        pointHoverRadius: 5
      }]
    },
    options: {
      responsive: true,
      maintainAspectRatio: false,
      interaction: {
        mode: 'index',
        intersect: false
      },
      scales: {
        x: {
          type: 'time',
          time: {
            unit: 'hour',
            displayFormats: {
              hour: 'HH:mm'
            }
          },
          ticks: {
            autoSkip: false,
            callback: function(value, index, ticks) {
              const current = new Date(value);
              const prev = index > 0 ? new Date(ticks[index - 1].value) : null;

              const hours = current.getHours().toString().padStart(2, '0');
              const minutes = current.getMinutes().toString().padStart(2, '0');
              const day = current.getDate().toString().padStart(2, '0');

              const isEvery4Hours = current.getHours() % 4 === 0 && minutes === '00';
              const isNewDay = !prev || current.getDate() !== prev.getDate();

              if (isNewDay) return `${day}`;
              if (isEvery4Hours) return `${hours}:${minutes}`;
              return '';
            }
          },
          title: {
            display: true,
            text: 'Time'
          }
        },
        y: {
          beginAtZero: true,
          title: {
            display: true,
            text: unitLabel
          }
        }
      },
      plugins: {
        tooltip: {
          enabled: true,
          callbacks: {
            label: function(context) {
              const label = context.dataset.label || '';
              const value = context.parsed.y;
              return `${label}: ${value.toFixed(2)}`;
            }
          }
        },
        legend: {
          display: true
        }
      }
    }
  });
}

async function updateChart() {
  const { data, unitLabel } = await fetchData();
  chart.data.datasets[0].data = data;
  chart.data.datasets[0].label = `Network traffic (${unitLabel})`;
  chart.options.scales.y.title.text = unitLabel;
  chart.update();
}

window.addEventListener("DOMContentLoaded", () => {
  loadAllCharts?.();
  initChart();
  setInterval(() => {
    loadAllCharts?.();
    updateChart();
  }, 60000);
});

document.addEventListener('DOMContentLoaded', () => {
  async function fetchData() {
	try {
	  const flowResp = await fetch('/stats/flow-rate');
	  const flowData = await flowResp.json();

	  const exportersResp = await fetch('/stats/exporters');
	  const exportersData = await exportersResp.json();

	  const flowRateRounded = Math.round(flowData.rate);
	  const exportersCount = exportersData.exporters.length;

	  document.getElementById('flowRate').textContent = flowRateRounded;
	  document.getElementById('exporterCount').textContent = exportersCount;

	} catch (error) {
	  console.error('Error fetching stats:', error);
	  document.getElementById('flowRate').textContent = 'Error';
	  document.getElementById('exporterCount').textContent = 'Error';
	}
  }

  fetchData();
  setInterval(fetchData, 10000);
});