/**
 * GradeHistogram — Histogramme SVG de distribution des notes
 *
 * Props:
 *   grades    : array of { score: number, max_score: number }
 *   stats     : { average: number, median: number }  (optionnel, pour les marqueurs)
 *   maxScore  : number (barème de l'évaluation, ex: 20)
 *
 * Rendu 100% SVG natif, 0 dépendance externe.
 * Les tranches sont calculées dynamiquement (6 buckets de largeur égale).
 */
window.CC = window.CC || {};

const { useMemo } = React;

/* ── Couleur d'une barre selon le % du barème ─────────────────────────────── */
function bucketColor(midPct) {
  if (midPct >= 70) return { fill: '#16A34A', label: '#15803d' };
  if (midPct >= 50) return { fill: '#D97706', label: '#b45309' };
  return { fill: '#DC2626', label: '#b91c1c' };
}

/* ── Calcul des buckets ───────────────────────────────────────────────────── */
function computeBuckets(grades, maxScore, numBuckets = 6) {
  const width = maxScore / numBuckets;

  const buckets = Array.from({ length: numBuckets }, (_, i) => {
    const lo = i * width;
    const hi = (i + 1) * width;
    const midPct = ((lo + hi) / 2 / maxScore) * 100;
    const loLabel = Number.isInteger(lo) ? lo : lo.toFixed(1);
    const hiLabel = Number.isInteger(hi) ? hi : hi.toFixed(1);
    return {
      lo, hi,
      label: i === numBuckets - 1 ? `${loLabel}-${hiLabel}` : `${loLabel}-${hiLabel}`,
      count: 0,
      midPct,
      colors: bucketColor(midPct),
    };
  });

  for (const g of grades) {
    const score = parseFloat(g.score);
    if (isNaN(score)) continue;
    // Clamp score to [0, maxScore]
    const clamped = Math.max(0, Math.min(maxScore, score));
    let idx = Math.floor(clamped / width);
    if (idx >= numBuckets) idx = numBuckets - 1; // score == maxScore → last bucket
    buckets[idx].count += 1;
  }

  return buckets;
}

/* ── Composant principal ─────────────────────────────────────────────────── */
window.CC.GradeHistogram = function GradeHistogram({ grades = [], stats = {}, maxScore = 20 }) {
  const buckets = useMemo(
    () => computeBuckets(grades, maxScore),
    [grades, maxScore]
  );

  const totalCount = grades.length;
  const maxCount   = Math.max(...buckets.map(b => b.count), 1);

  // ── État vide ──────────────────────────────────────────────────────────────
  if (totalCount === 0) {
    return (
      <div className="text-center py-8 text-slate-400 text-sm">
        Aucune copie corrigée — l'histogramme sera disponible après la correction.
      </div>
    );
  }

  // ── SVG dimensions ─────────────────────────────────────────────────────────
  const W = 600;         // viewBox width
  const H = 200;         // viewBox height
  const PAD_L = 32;      // left padding (for y axis)
  const PAD_R = 16;
  const PAD_T = 36;      // top padding (for count labels)
  const PAD_B = 40;      // bottom padding (for range labels)
  const chartW = W - PAD_L - PAD_R;
  const chartH = H - PAD_T - PAD_B;

  const n = buckets.length;
  const GAP = 6;
  const barW = (chartW - GAP * (n - 1)) / n;

  // ── Calcul position X d'un score (pour les marqueurs) ─────────────────────
  const scoreToX = (score) => {
    const clamped = Math.max(0, Math.min(maxScore, score));
    return PAD_L + (clamped / maxScore) * chartW;
  };

  const avg    = parseFloat(stats.average);
  const median = parseFloat(stats.median);
  const hasAvg    = !isNaN(avg);
  const hasMedian = !isNaN(median);

  return (
    <div>
      {/* Légende */}
      <div className="flex flex-wrap items-center gap-4 mb-3 text-xs text-slate-500">
        <div className="flex items-center gap-1.5">
          <span className="inline-block w-3 h-3 rounded-sm" style={{ background: '#DC2626' }} />
          <span>&lt; 50 %</span>
        </div>
        <div className="flex items-center gap-1.5">
          <span className="inline-block w-3 h-3 rounded-sm" style={{ background: '#D97706' }} />
          <span>50–69 %</span>
        </div>
        <div className="flex items-center gap-1.5">
          <span className="inline-block w-3 h-3 rounded-sm" style={{ background: '#16A34A' }} />
          <span>≥ 70 %</span>
        </div>
        {hasAvg && (
          <div className="flex items-center gap-1.5">
            <svg width="20" height="12" viewBox="0 0 20 12">
              <line x1="10" y1="0" x2="10" y2="12" stroke="#4F46E5" strokeWidth="2" strokeDasharray="3,2" />
            </svg>
            <span>Moyenne ({avg})</span>
          </div>
        )}
        {hasMedian && (
          <div className="flex items-center gap-1.5">
            <svg width="20" height="12" viewBox="0 0 20 12">
              <line x1="10" y1="0" x2="10" y2="12" stroke="#7C3AED" strokeWidth="2" strokeDasharray="3,2" />
            </svg>
            <span>Médiane ({median})</span>
          </div>
        )}
      </div>

      {/* Histogramme SVG */}
      <svg
        viewBox={`0 0 ${W} ${H}`}
        style={{ width: '100%', height: 'auto', display: 'block' }}
        aria-label="Distribution des notes"
        role="img"
      >
        {/* Fond grille horizontale (optionnel, subtil) */}
        {[0, 0.25, 0.5, 0.75, 1].map((t, i) => {
          const y = PAD_T + chartH * (1 - t);
          return (
            <line
              key={i}
              x1={PAD_L} y1={y}
              x2={PAD_L + chartW} y2={y}
              stroke="#e2e8f0"
              strokeWidth="1"
            />
          );
        })}

        {/* Barres */}
        {buckets.map((b, i) => {
          const barH = (b.count / maxCount) * chartH;
          const x = PAD_L + i * (barW + GAP);
          const y = PAD_T + chartH - barH;

          return (
            <g key={i}>
              {/* Barre */}
              <rect
                x={x}
                y={y}
                width={barW}
                height={Math.max(barH, b.count > 0 ? 4 : 0)}
                rx="3"
                fill={b.colors.fill}
                opacity={b.count > 0 ? 0.85 : 0.1}
              />

              {/* Label count au-dessus de la barre */}
              {b.count > 0 && (
                <text
                  x={x + barW / 2}
                  y={y - 5}
                  textAnchor="middle"
                  fontSize="12"
                  fontWeight="600"
                  fill={b.colors.label}
                >
                  {b.count}
                </text>
              )}

              {/* Label de plage en dessous */}
              <text
                x={x + barW / 2}
                y={PAD_T + chartH + 16}
                textAnchor="middle"
                fontSize="10"
                fill="#94a3b8"
              >
                {b.lo % 1 === 0 ? b.lo : b.lo.toFixed(1)}
              </text>
            </g>
          );
        })}

        {/* Dernier label de plage (valeur max) */}
        <text
          x={PAD_L + chartW}
          y={PAD_T + chartH + 16}
          textAnchor="middle"
          fontSize="10"
          fill="#94a3b8"
        >
          {maxScore}
        </text>

        {/* Marqueur Moyenne */}
        {hasAvg && (() => {
          const x = scoreToX(avg);
          return (
            <g>
              <line
                x1={x} y1={PAD_T - 8}
                x2={x} y2={PAD_T + chartH}
                stroke="#4F46E5"
                strokeWidth="1.5"
                strokeDasharray="4,3"
                opacity="0.9"
              />
              <text
                x={x}
                y={PAD_T - 12}
                textAnchor="middle"
                fontSize="10"
                fill="#4F46E5"
                fontWeight="600"
              >
                {avg}
              </text>
            </g>
          );
        })()}

        {/* Marqueur Médiane */}
        {hasMedian && median !== avg && (() => {
          const x = scoreToX(median);
          return (
            <g>
              <line
                x1={x} y1={PAD_T - 8}
                x2={x} y2={PAD_T + chartH}
                stroke="#7C3AED"
                strokeWidth="1.5"
                strokeDasharray="4,3"
                opacity="0.9"
              />
              <text
                x={x}
                y={PAD_T - 12}
                textAnchor="middle"
                fontSize="10"
                fill="#7C3AED"
                fontWeight="600"
              >
                {median}
              </text>
            </g>
          );
        })()}

        {/* Axe X */}
        <line
          x1={PAD_L} y1={PAD_T + chartH}
          x2={PAD_L + chartW} y2={PAD_T + chartH}
          stroke="#cbd5e1"
          strokeWidth="1"
        />
      </svg>

      {/* Résumé texte */}
      <div className="mt-2 text-xs text-slate-400 text-right">
        {totalCount} copie{totalCount > 1 ? 's' : ''} · /{maxScore}
      </div>
    </div>
  );
};
