Source: charts.js

// CHART UTILITIES
// =============================================================================

/**
 * Generates a color palette for pie chart segments
 * 
 * @param {number} count - Number of colors needed
 * @returns {Array} Array of color strings
 */
const generateColors = (count) => {
  const colors = [
    '#3b82f6', // Primary blue
    '#ef4444', // Red
    '#10b981', // Green
    '#f59e0b', // Yellow
    '#8b5cf6', // Purple
    '#06b6d4', // Cyan
    '#f97316', // Orange
    '#84cc16', // Lime
    '#ec4899', // Pink
    '#6b7280', // Gray
    '#14b8a6', // Teal
    '#f43f5e', // Rose
  ];

  // If we need more colors than predefined, generate them
  if (count > colors.length) {
    for (let i = colors.length; i < count; i++) {
      const hue = (i * 137.508) % 360; // Golden ratio for good distribution
      colors.push(`hsl(${hue}, 70%, 50%)`);
    }
  }

  return colors.slice(0, count);
};

/**
 * Gets appropriate background color for charts based on current theme
 * 
 * @returns {string} Background color
 */
const getChartBackgroundColor = () => {
  const theme = document.documentElement.getAttribute('data-theme') || 'light';
  switch (theme) {
    case 'dark':  return '#1e293b';
    case 'sepia': return '#e9ddc8';
    default:      return '#f8fafc';
  }
};

/**
 * Gets appropriate text color for charts based on current theme
 *
 * @returns {string} Text color
 */
const getChartTextColor = () => {
  const theme = document.documentElement.getAttribute('data-theme') || 'light';
  switch (theme) {
    case 'dark':  return '#f8fafc';
    case 'sepia': return '#3e2f1e';
    default:      return '#1e293b';
  }
};

/**
 * Creates a pie chart with the given data
 * 
 * @param {HTMLCanvasElement} canvas - Canvas element to render chart on
 * @param {Object} data - Chart data with labels and values
 * @param {string} title - Chart title
 * @returns {Chart} Chart.js instance
 */
const createPieChart = (canvas, data, title, metric = 'purchase') => {
  const labels = Object.keys(data);
  const values = Object.values(data).map(item => {
    const raw = item[metric] ?? item.purchase ?? item.value ?? 0;
    return metric === 'gainLoss' ? Math.abs(raw) : raw;
  });
  const colors = generateColors(labels.length);

  const ctx = canvas.getContext('2d');

  // STACK-71: per-chart datalabels plugin (graceful if CDN unavailable)
  const piePlugins = typeof ChartDataLabels !== 'undefined' ? [ChartDataLabels] : [];

  return new Chart(ctx, {
    type: 'pie',
    plugins: piePlugins,
    data: {
      labels: labels,
      datasets: [{
        data: values,
        backgroundColor: colors,
        borderColor: colors.map(color => color + '80'), // Add transparency
        borderWidth: 2,
        hoverOffset: 8
      }]
    },
    options: {
      responsive: true,
      maintainAspectRatio: false,
      plugins: {
        legend: {
          display: false,
          position: 'bottom',
          labels: {
            color: getChartTextColor(),
            padding: 15,
            usePointStyle: true,
            font: {
              size: 12
            },
            generateLabels: function(chart) {
              const data = chart.data;
              if (data.labels.length && data.datasets.length) {
                return data.labels.map((label, i) => {
                  const value = data.datasets[0].data[i];
                  const total = data.datasets[0].data.reduce((a, b) => a + b, 0);
                  const percentage = ((value / total) * 100).toFixed(1);

                  return {
                    text: `${label} (${formatCurrency(value)} - ${percentage}%)`,
                    fillStyle: data.datasets[0].backgroundColor[i],
                    strokeStyle: data.datasets[0].borderColor[i],
                    lineWidth: data.datasets[0].borderWidth,
                    hidden: false,
                    index: i
                  };
                });
              }
              return [];
            }
          }
        },
        tooltip: {
          backgroundColor: getChartBackgroundColor(),
          titleColor: getChartTextColor(),
          bodyColor: getChartTextColor(),
          borderColor: getChartTextColor(),
          borderWidth: 1,
          callbacks: {
            label: function(context) {
              const label = context.label || '';
              const value = context.parsed;
              const total = context.dataset.data.reduce((a, b) => a + b, 0);
              const percentage = ((value / total) * 100).toFixed(1);

              const b = data[label];
              const lines = [
                `${label} (${percentage}%)`,
                `Items: ${b ? b.count : 0} \u00B7 Weight: ${b ? b.weight.toFixed(2) : '0.00'} oz`,
                `Purchase: ${formatCurrency(value)}`
              ];
              if (b && b.melt !== undefined) {
                lines.push(`Melt: ${formatCurrency(b.melt)}`);
                lines.push(`Retail: ${formatCurrency(b.retail)}`);
                const gl = b.gainLoss;
                lines.push(`Gain/Loss: ${gl > 0 ? '+' : ''}${formatCurrency(gl)}`);
              }
              return lines;
            }
          }
        },
        datalabels: {
          display: function(context) {
            const total = context.dataset.data.reduce((a, b) => a + b, 0);
            if (total === 0) return false;
            return ((context.dataset.data[context.dataIndex] / total) * 100) >= 5;
          },
          formatter: function(value, context) {
            const total = context.dataset.data.reduce((a, b) => a + b, 0);
            return ((value / total) * 100).toFixed(0) + '%';
          },
          color: '#fff',
          font: { weight: 'bold', size: 12 },
          textStrokeColor: 'rgba(0,0,0,0.5)',
          textStrokeWidth: 2,
          anchor: 'center',
          align: 'center'
        }
      },
      animation: {
        animateRotate: true,
        animateScale: false,
        duration: 1000,
        easing: 'easeOutQuart'
      }
    }
  });
};

/**
 * Destroys existing chart instances to prevent memory leaks
 */
const destroyCharts = () => {
  Object.keys(chartInstances).forEach(key => {
    if (chartInstances[key]) {
      chartInstances[key].destroy();
      chartInstances[key] = null;
    }
  });
};

// Expose generateColors globally for breakdown color-keying
window.generateColors = generateColors;

// =============================================================================