// ===========================================================
// CollectionDashboard_v2 — gamified personal dashboard.
// All client-computed from the user's collection_items rows (no
// extra Discogs calls). Reuses globals: Bars, Sleeve, AnimatedMoney,
// BBR_buyUrl, BBR_trackClick.
//
// Props: { items, albums, total, canonOwned }
//   items = resolved collection rows (artist,title,year,genre,
//           media_condition,sleeve_condition,value,date_added,album,decade)
// ===========================================================
const { useMemo: useDashMemo } = React;

function dashGbp(n) { return "£" + Math.round(n || 0).toLocaleString("en-GB"); }
function dashGrade(code) { return code ? code.replace("_PLUS", "+") : "—"; }
function fmtMonth(iso) {
  if (!iso) return "";
  const d = String(iso).slice(0, 10).split("-");
  const mo = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"][parseInt(d[1], 10) - 1] || "";
  return mo + " '" + (d[0] || "").slice(2);
}

// Cumulative value-over-time line with £ (y) and date (x) axes. The plot SVG
// stretches (preserveAspectRatio none), so axis labels live in HTML around it
// to avoid text distortion.
function ValueOverTime({ points }) {
  if (!points || points.length < 2) return null;
  const W = 600, H = 150;
  const xs = points.map((_, i) => (i / (points.length - 1)) * W);
  const max = Math.max(...points.map(p => p.v)) || 1;
  const y = v => H - (v / max) * (H - 6) - 3;
  const line = points.map((p, i) => (i ? "L" : "M") + xs[i].toFixed(1) + "," + y(p.v).toFixed(1)).join(" ");
  const area = line + ` L${W},${H} L0,${H} Z`;
  return (
    <div className="v2-vot">
      <div className="v2-vot-yaxis">
        <span>{dashGbp(max)}</span>
        <span>{dashGbp(max / 2)}</span>
        <span>£0</span>
      </div>
      <div className="v2-vot-plot">
        <svg viewBox={`0 0 ${W} ${H}`} preserveAspectRatio="none" style={{ height: 150, width: "100%", display: "block" }}>
          <defs>
            <linearGradient id="v2Area" x1="0" y1="0" x2="0" y2="1">
              <stop offset="0%" stopColor="var(--accent)" stopOpacity="0.18" />
              <stop offset="100%" stopColor="var(--accent)" stopOpacity="0" />
            </linearGradient>
          </defs>
          {[0, 0.5, 1].map(f => <line key={f} x1="0" x2={W} y1={3 + f * (H - 6)} y2={3 + f * (H - 6)} stroke="var(--rule)" strokeWidth="1" />)}
          <path d={area} fill="url(#v2Area)" />
          <path d={line} fill="none" stroke="var(--accent)" strokeWidth="2" strokeLinejoin="round" strokeLinecap="round" vectorEffect="non-scaling-stroke" />
        </svg>
        <div className="v2-vot-xaxis">
          <span>{fmtMonth(points[0].date)}</span>
          <span>{fmtMonth(points[points.length - 1].date)}</span>
        </div>
      </div>
    </div>
  );
}

function CollectionDashboard_v2({ items, albums, total, canonOwned }) {
  const byGenre = useDashMemo(() => {
    const m = {};
    items.forEach(r => { m[r.genre] = (m[r.genre] || 0) + r.value; });
    return Object.entries(m).map(([k, v]) => ({ k, v })).sort((a, b) => b.v - a.v);
  }, [items]);

  const byDecade = useDashMemo(() => {
    const m = {};
    items.forEach(r => { if (r.decade && r.decade !== "—") m[r.decade] = (m[r.decade] || 0) + r.value; });
    return Object.entries(m).map(([k, v]) => ({ k, v })).sort((a, b) => a.k.localeCompare(b.k));
  }, [items]);

  const condDist = useDashMemo(() => {
    const order = ["M", "NM", "VG+", "VG", "G+", "G", "F", "P"];
    const m = {};
    items.forEach(r => { const c = dashGrade(r.media_condition); m[c] = (m[c] || 0) + 1; });
    return order.filter(c => m[c]).map(c => ({ k: c, n: m[c] }));
  }, [items]);

  const gaps = useDashMemo(() => {
    const owned = new Set(items.filter(r => r.slug).map(r => r.slug));
    return albums.filter(a => !owned.has(a.slug)).sort((a, b) => a.rank - b.rank);
  }, [items, albums]);

  const crown = useDashMemo(() => items.reduce((m, r) => (!m || r.value > m.value ? r : m), null), [items]);
  const years = items.map(r => r.year).filter(Boolean);
  const oldest = years.length ? Math.min(...years) : null;
  const avgYear = years.length ? Math.round(years.reduce((s, y) => s + y, 0) / years.length) : null;
  const oldestItem = oldest ? items.find(r => r.year === oldest) : null;

  const valuePoints = useDashMemo(() => {
    const sorted = items.filter(r => r.value > 0).slice().sort((a, b) => String(a.date_added).localeCompare(String(b.date_added)));
    let run = 0;
    return sorted.map(r => ({ v: (run += r.value), date: r.date_added }));
  }, [items]);

  const maxCond = Math.max(...condDist.map(c => c.n), 1);
  const pct = Math.round((canonOwned / 100) * 100);

  return (
    <div className="mc-dash">
      <div className="mc-dash-head">
        <h3>The numbers</h3>
        <span className="mc-eyebrow">Live from your collection</span>
      </div>

      {/* Lead-In 100 progress + gaps */}
      <div className="mc-panel v2-progress-panel">
        <div className="mc-panel-k">The Lead-In 100</div>
        <div className="v2-progress-head"><b>{canonOwned}</b> / 100 owned <span className="v2-progress-pct">{pct}%</span></div>
        <div className="mc-milestone-bar"><div className="mc-milestone-fill" style={{ width: pct + "%" }} /></div>
        {gaps.length > 0 && (
          <>
            <div className="v2-gaps-label">Closest gaps — tap to buy on vinyl</div>
            <div className="v2-gaps">
              {gaps.slice(0, 12).map(a => (
                <a className="v2-gap" key={a.slug} href={window.BBR_buyUrl(a.title + " " + a.artist, a.slug)}
                   target="_blank" rel="noopener"
                   onClick={() => window.BBR_trackClick && window.BBR_trackClick(a.slug, "dashboard-gap")}
                   title={a.title + " — " + a.artist}>
                  <Sleeve album={a} size={56} />
                  <span className="v2-gap-rank">№ {String(a.rank).padStart(3, "0")}</span>
                </a>
              ))}
            </div>
          </>
        )}
      </div>

      <div className="mc-dash-grid">
        <div className="mc-panel">
          <div className="mc-panel-k">Cumulative value as you add</div>
          <ValueOverTime points={valuePoints} />
        </div>
        <div className="mc-panel">
          <div className="mc-panel-k">Where the value sits</div>
          <Bars rows={byGenre} accentIndex={0} />
          <div style={{ height: 18 }} />
          <div className="mc-panel-k">By decade</div>
          <Bars rows={byDecade} accentIndex={-1} />
        </div>
      </div>

      {/* condition distribution */}
      <div className="mc-panel">
        <div className="mc-panel-k">Condition (media grade)</div>
        <div className="v2-cond-dist">
          {condDist.map(c => (
            <div className="v2-cond-row" key={c.k}>
              <span className="v2-cond-code">{c.k}</span>
              <span className="v2-cond-track"><span className="v2-cond-fill" style={{ width: (c.n / maxCond * 100) + "%" }} /></span>
              <span className="v2-cond-n">{c.n}</span>
            </div>
          ))}
        </div>
      </div>

      {/* tiles */}
      <div className="mc-tiles">
        {crown && crown.value > 0 && (
          <div className="mc-tile">
            <div className="cv"><Sleeve album={crown.album} size={64} /></div>
            <div>
              <div className="mc-tile-k">Crown jewel</div>
              <div className="mc-tile-t">{crown.title}</div>
              <div className="mc-tile-s">{dashGrade(crown.media_condition)} · {dashGbp(crown.value)}</div>
            </div>
          </div>
        )}
        {oldestItem && (
          <div className="mc-tile">
            <div className="cv"><Sleeve album={oldestItem.album} size={64} /></div>
            <div>
              <div className="mc-tile-k">Oldest pressing</div>
              <div className="mc-tile-t">{oldestItem.title}</div>
              <div className="mc-tile-s">{oldest} · average year {avgYear}</div>
            </div>
          </div>
        )}
      </div>

      <p className="add-pr-attr" style={{ marginTop: 18, justifyContent: "flex-start" }}>
        <svg width="11" height="11" viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="1.5"><circle cx="6" cy="6" r="5" /><path d="M6 5.5v3M6 3.6h.01" /></svg>
        Estimates from Discogs market data for each pressing &amp; grade. Shown publicly so the community can judge.
      </p>
    </div>
  );
}

Object.assign(window, { CollectionDashboard_v2 });
