// Agency Audit — gedeelde labels en visuals (bovenop groeiscan-shared.jsx).

const AUDIT_CHECK_LABELS = {
  'transparency-center': 'Google Ads-advertenties',
  'meta-ad-library': 'Meta-advertenties',
  'serp-brand': 'Je merknaam in Google',
  'serp-keywords': 'Kernzoektermen in Google',
  'site-crawl': 'Website en blog',
  sitemap: 'Sitemap',
  wayback: 'Wijzigingen (Wayback Machine)',
  'seo-data': 'Zichtbaarheid (Semrush)',
  'seo-competitors': 'Vergelijkbare partijen',
  'tag-detect': 'Meting en tags',
  'page-speed': 'Laadsnelheid',
  'landing-pages': "Landingspagina's",
};

const AUDIT_DIMENSIONS = [
  { key: 'activity', label: 'Activiteit', sub: 'Wordt er nog aan gewerkt?' },
  { key: 'visibility', label: 'Zichtbaarheid', sub: 'Groei je mee met de markt?' },
  { key: 'tracking', label: 'Meting', sub: 'Is het resultaat meetbaar?' },
  { key: 'landing', label: "Landingspagina's", sub: 'Maakt de site het af?' },
  { key: 'brand_bidding', label: 'Merkbescherming', sub: 'Wie pakt jouw naam in Google?' },
];

// Het oordeel is een beeld, geen verdict: neutrale labels, de feiten spreken.
const AUDIT_VERDICTS = {
  stay: { label: 'De signalen zijn positief', tone: 'green', text: 'Op basis van publieke data is er beweging en resultaat op de kanalen die je afneemt.' },
  talk: { label: 'Goede basis, een paar aandachtspunten', tone: 'orange', text: 'Een aantal onderdelen staat goed; op een paar punten is een toelichting van je bureau op zijn plaats.' },
  consider_switch: { label: 'Meerdere signalen vragen om opheldering', tone: 'red', text: 'Op meerdere onderdelen zien we minder beweging of resultaat dan je bij de afgenomen diensten mag verwachten.' },
  insufficient_data: { label: 'Te weinig data voor een beeld', tone: 'grey', text: 'We konden te weinig publiek meten. Wat we wél zagen staat hieronder.' },
};

const LIGHT_STYLE = {
  green: { bg: '#E6F4EC', fg: '#1F6B43', bar: 'var(--au-green)', label: 'goed' },
  orange: { bg: '#FBF0DA', fg: '#8A5A0B', bar: 'var(--au-orange)', label: 'matig' },
  red: { bg: '#FBE9E1', fg: '#9B3413', bar: 'var(--au-red)', label: 'zwak' },
  grey: { bg: '#EEF3F2', fg: '#5A7472', bar: 'var(--au-grey)', label: 'niet gemeten' },
};

function Stoplicht({ light, children }) {
  const s = LIGHT_STYLE[light] || LIGHT_STYLE.grey;
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, fontSize: 11.5, fontWeight: 800, borderRadius: 999, padding: '3px 10px', background: s.bg, color: s.fg, whiteSpace: 'nowrap' }}>
      <span style={{ width: 8, height: 8, borderRadius: '50%', background: s.bar, display: 'inline-block' }}></span>
      {children || s.label}
    </span>
  );
}

// Halve ring 0-100 met het totaal in het midden
function ScoreGauge({ score, tone = 'grey', size = 180 }) {
  const r = 70; const c = Math.PI * r; // halve cirkel
  const pct = score == null ? 0 : Math.max(0, Math.min(100, score)) / 100;
  const color = (LIGHT_STYLE[tone] || LIGHT_STYLE.grey).bar;
  return (
    <svg viewBox="0 0 200 120" style={{ width: size, height: size * 0.6, display: 'block' }}>
      <path d="M 30 100 A 70 70 0 0 1 170 100" fill="none" stroke="#E4EDEC" strokeWidth="14" strokeLinecap="round" />
      <path d="M 30 100 A 70 70 0 0 1 170 100" fill="none" stroke={color} strokeWidth="14" strokeLinecap="round" strokeDasharray={`${c * pct} ${c}`} />
      <text x="100" y="92" textAnchor="middle" fontSize="40" fontWeight="900" fill="#12302E" fontFamily="Lato, sans-serif">{score == null ? '–' : score}</text>
      <text x="100" y="112" textAnchor="middle" fontSize="11" fill="#8AA3A1" fontFamily="Lato, sans-serif">van 100</text>
    </svg>
  );
}

// Tijdlijn van 12 maanden met de laatste beweging per kanaal
function ActivityTimeline({ channels }) {
  const rows = (channels || []).filter((c) => c.expected !== false);
  if (!rows.length) return null;
  const W = 720; const L = 150; const R = 16; const rowH = 34; const H = rows.length * rowH + 30;
  const x = (days) => L + (1 - Math.min(365, Math.max(0, days)) / 365) * (W - L - R);
  return (
    <svg viewBox={`0 0 ${W} ${H}`} style={{ width: '100%', display: 'block' }}>
      {[365, 270, 180, 90, 30, 0].map((d) => (
        <g key={d}>
          <line x1={x(d)} x2={x(d)} y1={8} y2={H - 22} stroke="#E4EDEC" strokeWidth="1" />
          <text x={x(d)} y={H - 6} textAnchor="middle" fontSize="10" fill="#8AA3A1">{d === 0 ? 'nu' : `${d} d`}</text>
        </g>
      ))}
      {rows.map((c, i) => {
        const y = 14 + i * rowH + rowH / 2;
        const s = LIGHT_STYLE[c.light] || LIGHT_STYLE.grey;
        const has = c.days != null && !c.noActivity;
        return (
          <g key={c.key}>
            <text x={0} y={y + 4} fontSize="12.5" fontWeight="700" fill="#2E4A48">{c.label}</text>
            <line x1={L} x2={W - R} y1={y} y2={y} stroke="#EEF4F3" strokeWidth="6" strokeLinecap="round" />
            {has ? (
              <g>
                <line x1={x(c.days)} x2={W - R} y1={y} y2={y} stroke={s.bar} strokeWidth="6" strokeLinecap="round" opacity="0.35" />
                <circle cx={x(c.days)} cy={y} r="7" fill={s.bar} stroke="#fff" strokeWidth="2" />
                {x(c.days) > W - 130
                  ? <text x={x(c.days) - 12} y={y - 10} textAnchor="end" fontSize="10.5" fontWeight="700" fill={s.fg}>{c.days} dagen geleden</text>
                  : <text x={x(c.days) + 12} y={y - 10} fontSize="10.5" fontWeight="700" fill={s.fg}>{c.days} dagen geleden</text>}
              </g>
            ) : (
              <text x={L + 8} y={y + 4} fontSize="11" fontWeight="700" fill={c.noActivity ? LIGHT_STYLE.red.fg : '#8AA3A1'}>{c.noActivity ? 'niets gevonden in 12 maanden' : 'niet gemeten'}</text>
            )}
          </g>
        );
      })}
    </svg>
  );
}

// Trend van eigen organisch verkeer naast concurrenten (12 maanden, absolute lijnen)
function TrendChart({ series }) {
  const months = [...new Set(series.flatMap((s) => s.points.map((p) => p.ym)))].sort();
  if (months.length < 2) return null;
  const W = 720, H = 220, PL = 46, PR = 14, PT = 12, PB = 26;
  const lines = series.map((s) => { const m = new Map(s.points.map((p) => [p.ym, p.v])); return { ...s, values: months.map((ym) => m.get(ym) ?? null) }; });
  const maxY = Math.max(...lines.flatMap((l) => l.values.filter((v) => v != null)), 1);
  const x = (i) => PL + (i / (months.length - 1)) * (W - PL - PR);
  const y = (v) => PT + (1 - v / maxY) * (H - PT - PB);
  const fmt = (n) => (n >= 1000 ? `${(n / 1000).toFixed(n >= 10000 ? 0 : 1).replace('.', ',')}k` : String(Math.round(n)));
  const path = (vals) => { let d = ''; let pen = false; vals.forEach((v, i) => { if (v == null) { pen = false; return; } d += `${pen ? 'L' : 'M'}${x(i).toFixed(1)},${y(v).toFixed(1)}`; pen = true; }); return d; };
  return (
    <div>
      <svg viewBox={`0 0 ${W} ${H}`} style={{ width: '100%', display: 'block' }}>
        {[0, 0.5, 1].map((f) => (
          <g key={f}>
            <line x1={PL} x2={W - PR} y1={y(maxY * f)} y2={y(maxY * f)} stroke="#E4EDEC" strokeWidth="1" />
            <text x={PL - 6} y={y(maxY * f) + 3.5} textAnchor="end" fontSize="10" fill="#8AA3A1">{fmt(maxY * f)}</text>
          </g>
        ))}
        {[0, Math.floor((months.length - 1) / 2), months.length - 1].map((i) => <text key={i} x={x(i)} y={H - 8} textAnchor="middle" fontSize="10" fill="#8AA3A1">{months[i]}</text>)}
        {lines.map((l) => <path key={l.label} d={path(l.values)} fill="none" stroke={l.color} strokeWidth={l.isOwn ? 3 : 2} strokeLinejoin="round" strokeLinecap="round" opacity={l.isOwn ? 1 : 0.8} />)}
      </svg>
      <div style={{ display: 'flex', gap: 16, flexWrap: 'wrap', marginTop: 6 }}>
        {lines.map((l) => (
          <span key={l.label} style={{ display: 'inline-flex', alignItems: 'center', gap: 6, fontSize: 12.5, fontWeight: l.isOwn ? 900 : 700, color: l.isOwn ? 'var(--bm-cta-2)' : '#3A5250' }}>
            <span style={{ width: 14, height: 3, borderRadius: 2, background: l.color, display: 'inline-block' }}></span>{l.label}{l.isOwn ? ' ← jij' : ''}
          </span>
        ))}
      </div>
    </div>
  );
}

function AuditSection({ tag, title, children, alt }) {
  return (
    <section style={{ background: alt ? 'var(--bm-mist)' : '#fff', padding: '52px clamp(20px, 6vw, 72px)' }}>
      <div style={{ maxWidth: 1040, margin: '0 auto' }}>
        {tag && <SectionTag>{tag}</SectionTag>}
        {title && <h2 style={{ fontWeight: 900, fontSize: 'clamp(22px, 2.8vw, 30px)', color: '#12302E', margin: '14px 0 22px', textWrap: 'balance' }}>{title}</h2>}
        {children}
      </div>
    </section>
  );
}

// Interactieve trendgrafiek: eigen domein naast vergelijkbare partijen, met
// weergave-keuze (organisch verkeer / betaald verkeer / organische zoektermen),
// hover-tooltip met de maandcijfers en een klikbare legenda.
function InteractiveTrendChart({ ownLabel, own, competitors, showPaid = true }) {
  const { useState, useRef } = React;
  const VIEWS = [['organicTraffic', 'Organisch verkeer'], ...(showPaid ? [['paidTraffic', 'Betaald verkeer']] : []), ['organicKeywords', 'Organische zoektermen']];
  const [view, setView] = useState('organicTraffic');
  const [hidden, setHidden] = useState({});
  const [hover, setHover] = useState(null);
  const svgRef = useRef(null);
  const palette = ['var(--bm-teal)', '#4A6FA5', '#8A5A0B'];
  const series = [{ label: ownLabel, color: 'var(--bm-cta-1)', isOwn: true, points: own || [] }, ...(competitors || []).slice(0, 3).map((c, i) => ({ label: c.domain, color: palette[i], isOwn: false, points: c.trend12m || [] }))];
  const months = [...new Set(series.flatMap((s) => s.points.map((p) => p.ym)))].sort();
  if (months.length < 2) return null;
  const W = 760, H = 250, PL = 50, PR = 16, PT = 14, PB = 28;
  const lines = series.map((s) => { const m = new Map(s.points.map((p) => [p.ym, p[view]])); return { ...s, values: months.map((ym) => (m.has(ym) ? (m.get(ym) ?? null) : null)) }; });
  const visible = lines.filter((l) => !hidden[l.label]);
  const maxY = Math.max(...visible.flatMap((l) => l.values.filter((v) => v != null)), 1);
  const x = (i) => PL + (i / (months.length - 1)) * (W - PL - PR);
  const y = (v) => PT + (1 - v / maxY) * (H - PT - PB);
  const fmtN = (v) => new Intl.NumberFormat('nl-NL').format(Math.round(v));
  const fmtShort = (v) => (v >= 1000 ? `${(v / 1000).toFixed(v >= 10000 ? 0 : 1).replace('.', ',')}k` : String(Math.round(v)));
  const pathFor = (vals) => { let d = ''; let pen = false; vals.forEach((v, i) => { if (v == null) { pen = false; return; } d += `${pen ? 'L' : 'M'}${x(i).toFixed(1)},${y(v).toFixed(1)}`; pen = true; }); return d; };
  const locate = (clientX) => {
    const rect = svgRef.current?.getBoundingClientRect();
    if (!rect || !rect.width) return;
    const px = ((clientX - rect.left) / rect.width) * W;
    const i = Math.round(((px - PL) / (W - PL - PR)) * (months.length - 1));
    setHover(Math.max(0, Math.min(months.length - 1, i)));
  };
  const monthLabel = (ym) => { const [yy, mm] = ym.split('-'); return `${['jan', 'feb', 'mrt', 'apr', 'mei', 'jun', 'jul', 'aug', 'sep', 'okt', 'nov', 'dec'][Number(mm) - 1] || mm} ${yy.slice(2)}`; };
  const unit = view === 'organicKeywords' ? 'zoektermen in de top-100' : 'geschatte bezoekers per maand';
  const btn = (active) => ({ fontSize: 12, fontWeight: 800, borderRadius: 999, padding: '5px 14px', cursor: 'pointer', border: '1px solid #D8E5E3', background: active ? 'var(--bm-dark)' : '#fff', color: active ? '#fff' : '#3A5250', fontFamily: "'Lato', sans-serif" });
  return (
    <div>
      <div style={{ display: 'flex', gap: 8, marginBottom: 12, flexWrap: 'wrap' }}>
        {VIEWS.map(([k, label]) => <button key={k} type="button" onClick={() => { setView(k); setHover(null); }} style={btn(view === k)}>{label}</button>)}
      </div>
      <div style={{ position: 'relative' }}>
        <svg ref={svgRef} viewBox={`0 0 ${W} ${H}`} style={{ width: '100%', display: 'block', touchAction: 'pan-y' }}
          onMouseMove={(e) => locate(e.clientX)} onMouseLeave={() => setHover(null)}
          onTouchStart={(e) => locate(e.touches[0].clientX)} onTouchMove={(e) => locate(e.touches[0].clientX)}>
          {[0, 0.25, 0.5, 0.75, 1].map((f) => (
            <g key={f}>
              <line x1={PL} x2={W - PR} y1={y(maxY * f)} y2={y(maxY * f)} stroke="#E4EDEC" strokeWidth="1" />
              <text x={PL - 6} y={y(maxY * f) + 3.5} textAnchor="end" fontSize="10" fill="#8AA3A1">{fmtShort(maxY * f)}</text>
            </g>
          ))}
          {months.map((ym, i) => (i % 2 === 0 || i === months.length - 1) && <text key={ym} x={x(i)} y={H - 8} textAnchor="middle" fontSize="10" fill="#8AA3A1">{monthLabel(ym)}</text>)}
          {hover != null && <line x1={x(hover)} x2={x(hover)} y1={PT} y2={H - PB} stroke="#B8CCCA" strokeWidth="1" strokeDasharray="3 3" />}
          {visible.map((l) => <path key={l.label} d={pathFor(l.values)} fill="none" stroke={l.color} strokeWidth={l.isOwn ? 3 : 2} strokeLinejoin="round" strokeLinecap="round" opacity={l.isOwn ? 1 : 0.85} />)}
          {hover != null && visible.map((l) => l.values[hover] != null && <circle key={l.label} cx={x(hover)} cy={y(l.values[hover])} r="4.5" fill={l.color} stroke="#fff" strokeWidth="1.5" />)}
          <rect x={PL} y={PT} width={W - PL - PR} height={H - PT - PB} fill="transparent" />
        </svg>
        {hover != null && (
          <div style={{ position: 'absolute', top: 6, [hover > (months.length - 1) / 2 ? 'left' : 'right']: 8, background: 'var(--bm-dark)', color: '#fff', borderRadius: 10, padding: '10px 14px', fontSize: 12, pointerEvents: 'none', boxShadow: '0 6px 18px rgba(0,0,0,0.18)', minWidth: 200 }}>
            <div style={{ fontWeight: 800, marginBottom: 2 }}>{monthLabel(months[hover])}</div>
            <div style={{ color: '#8FB5B1', fontSize: 11, marginBottom: 6 }}>{unit}</div>
            {visible.map((l) => <div key={l.label} style={{ display: 'flex', justifyContent: 'space-between', gap: 14 }}><span style={{ color: l.isOwn ? '#FFD9C2' : '#C6DBD9' }}>{l.label}</span><b>{l.values[hover] != null ? fmtN(l.values[hover]) : '–'}</b></div>)}
          </div>
        )}
      </div>
      <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap', marginTop: 8 }}>
        {lines.map((l) => (
          <button key={l.label} type="button" onClick={() => { if (!l.isOwn) setHidden({ ...hidden, [l.label]: !hidden[l.label] }); }} title={l.isOwn ? 'jouw domein' : 'klik om te tonen of te verbergen'}
            style={{ display: 'inline-flex', alignItems: 'center', gap: 6, fontSize: 12.5, fontWeight: l.isOwn ? 900 : 700, color: hidden[l.label] ? '#B8CCCA' : l.isOwn ? 'var(--bm-cta-2)' : '#3A5250', background: 'none', border: 'none', padding: 0, cursor: l.isOwn ? 'default' : 'pointer', fontFamily: "'Lato', sans-serif", textDecoration: hidden[l.label] ? 'line-through' : 'none' }}>
            <span style={{ width: 14, height: 3, borderRadius: 2, background: hidden[l.label] ? '#DCE8E6' : l.color, display: 'inline-block' }}></span>{l.label}{l.isOwn ? ' ← jij' : ''}
          </button>
        ))}
      </div>
      <p style={{ margin: '8px 0 0', fontSize: 11.5, color: '#8AA3A1' }}>Beweeg over de grafiek voor de maandcijfers; klik op een naam om die lijn te verbergen. Bron: Semrush (NL), schattingen per maand.</p>
    </div>
  );
}

// Sectie-CTA: elke oproep in het rapport leidt naar de onafhankelijke second opinion
function AuditCta({ text, button = 'Vraag een second opinion aan', compact }) {
  return (
    <div style={{ marginTop: compact ? 16 : 22, background: 'var(--bm-dark)', borderRadius: 14, padding: compact ? '14px 18px' : '18px 22px', display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 16, flexWrap: 'wrap' }}>
      <p style={{ margin: 0, color: '#C6DBD9', fontSize: 14, lineHeight: 1.55, maxWidth: 620 }}>{text}</p>
      <CtaButton onClick={() => document.getElementById('au-contact')?.scrollIntoView({ behavior: 'smooth' })} style={{ padding: '11px 20px', fontSize: 13 }}>{button}</CtaButton>
    </div>
  );
}

// Lijstje met concrete punten: ✓ (goed) of ! (aandacht)
function Punten({ items, tone = 'good', style, light }) {
  if (!items?.length) return null;
  const good = tone === 'good';
  return (
    <ul style={{ listStyle: 'none', margin: 0, padding: 0, display: 'grid', gap: 5, ...style }}>
      {items.map((it, i) => (
        <li key={i} style={{ display: 'flex', gap: 8, fontSize: 13, lineHeight: 1.5, color: light ? '#E4F0EF' : '#2E4A48' }}>
          <span style={{ flex: '0 0 18px', height: 18, borderRadius: '50%', background: good ? '#E6F4EC' : '#FBE9E1', color: good ? '#1F6B43' : '#9B3413', fontSize: 11, fontWeight: 900, display: 'grid', placeItems: 'center', marginTop: 1 }}>{good ? '✓' : '!'}</span>
          <span>{it}</span>
        </li>
      ))}
    </ul>
  );
}

// Kop/waarde-rijen in een kaart: [[label, waarde, kleur?], …]
function Rijen({ rows }) {
  return (rows || []).filter(Boolean).map(([k, v, color]) => (
    <div key={k} style={{ display: 'flex', justifyContent: 'space-between', gap: 12, padding: '7px 0', borderTop: '1px solid #F0F5F4', fontSize: 13.5 }}>
      <span style={{ color: '#3A5250' }}>{k}</span><span style={{ fontWeight: 800, color: color || '#12302E', textAlign: 'right' }}>{v}</span>
    </div>
  ));
}

Object.assign(window, { AUDIT_CHECK_LABELS, AUDIT_DIMENSIONS, AUDIT_VERDICTS, LIGHT_STYLE, Stoplicht, ScoreGauge, ActivityTimeline, TrendChart, InteractiveTrendChart, AuditCta, Punten, Rijen, AuditSection });
