/* ============================================================
   Deal Flow charts — graphite styled.
   SeasonFunnel (div) · StepFunnel (div) · GoalTrend (svg) ·
   DualLine (svg) · TeamBars (div) · MiniFunnel (svg)
   ============================================================ */

const DCH = {
  platform: '#3e6e8c', addon: '#9db4c0', goal: '#6e7479',
  pos: '#3f7d58', warn: '#b07a2e', danger: '#a4453c',
  area: '#c5d3db', line: '#3e6e8c', line2: '#b07a2e',
  axis: '#9aa0a5', grid: '#e7e8e9', ink: '#1a1c1e', muted: '#6e7479', ghost: '#d3d5d7',
};

function dfNiceMax(v) {
  if (v <= 5) return 5;
  const pow = Math.pow(10, Math.floor(Math.log10(v)));
  const n = v / pow;
  const step = n <= 1 ? 1 : n <= 2 ? 2 : n <= 5 ? 5 : 10;
  return Math.ceil(v / (step * pow / 5)) * (step * pow / 5);
}

/* ---------- Season funnel (hero) ----------
   stages: [{ key, label, platform, addon, total, prev }]
   prior year drawn as a ghost track behind each bar. */
function SeasonFunnel({ stages, onSeg, compareLabel, fmt }) {
  const F = fmt || ((v) => v);
  const max = Math.max(1, ...stages.map((s) => Math.max(s.total, s.prev || 0)));
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 13 }}>
      {stages.map((s, i) => {
        const prevPct = (s.prev || 0) / max * 100;
        const platPct = s.platform / max * 100;
        const addPct = s.addon / max * 100;
        const yoy = s.prev ? Math.round((s.total - s.prev) / s.prev * 100) : null;
        const conv = i > 0 && stages[i - 1].total ? Math.round(s.total / stages[i - 1].total * 100) : null;
        return (
          <div key={s.key}>
            {conv != null && (
              <div style={{ display: 'flex', alignItems: 'center', gap: 7, margin: '-6px 0 5px 2px' }}>
                <Icon name="chevronDown" size={12} style={{ color: 'var(--ink-faint)' }} />
                <span className="tabular" style={{ fontSize: 10.5, color: 'var(--ink-soft)', fontWeight: 600 }}>{conv}% advance</span>
              </div>
            )}
            <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
              <div style={{ width: 132, flexShrink: 0, textAlign: 'right' }}>
                <div style={{ fontSize: 12.5, fontWeight: 700, color: 'var(--ink)' }}>{s.label}</div>
                {yoy != null && (
                  <div style={{ fontSize: 10.5, fontWeight: 700, color: yoy >= 0 ? 'var(--positive)' : 'var(--danger)', display: 'flex', gap: 2, justifyContent: 'flex-end', alignItems: 'center', marginTop: 1 }}>
                    <Icon name={yoy >= 0 ? 'arrowUp' : 'arrowDown'} size={10} stroke={2.4} />{Math.abs(yoy)}% YoY
                  </div>
                )}
              </div>
              <div style={{ flex: 1, position: 'relative', height: 34 }}>
                {/* prior-year ghost track */}
                <div title={`${compareLabel}: ${s.prev || 0}`} style={{ position: 'absolute', top: -3, left: 0, width: prevPct + '%', height: 40, border: '1.5px dashed var(--line)', borderRadius: 6, background: 'repeating-linear-gradient(135deg, rgba(0,0,0,0.018) 0 6px, transparent 6px 12px)' }}></div>
                {/* current bar: platform + addon, container sized to total */}
                <div style={{ position: 'absolute', top: 0, left: 0, height: 34, width: (platPct + addPct) + '%', display: 'flex', borderRadius: 6, overflow: 'hidden', boxShadow: '0 1px 2px rgba(0,0,0,.06)' }}>
                  <button onClick={() => onSeg && onSeg(s, 'platform')} title={`${s.label} · Platform · ${s.platform}`}
                    style={{ width: `${s.platform / (s.total || 1) * 100}%`, minWidth: s.platform ? 2 : 0, height: '100%', border: 'none', background: DCH.platform, cursor: 'pointer' }}></button>
                  <button onClick={() => onSeg && onSeg(s, 'addon')} title={`${s.label} · Add-on · ${s.addon}`}
                    style={{ width: `${s.addon / (s.total || 1) * 100}%`, minWidth: s.addon ? 2 : 0, height: '100%', border: 'none', background: DCH.addon, cursor: 'pointer' }}></button>
                </div>
              </div>
              <div style={{ width: 92, flexShrink: 0, display: 'flex', flexDirection: 'column', alignItems: 'flex-start' }}>
                <span className="tabular" style={{ fontSize: 18, fontWeight: 700, lineHeight: 1 }}>{F(s.total)}</span>
                <span className="tabular" style={{ fontSize: 10, color: 'var(--ink-soft)', marginTop: 2 }}>{F(s.platform)} P · {F(s.addon)} A</span>
              </div>
            </div>
          </div>
        );
      })}
    </div>
  );
}

/* ---------- Step funnel (outreach / industry progression) ----------
   steps: [{label, value}]  dropoffs (optional): [{label, value, tone}] */
function StepFunnel({ steps, dropoffs, onStep, accent = '#3e6e8c' }) {
  const max = Math.max(1, ...steps.map((s) => s.value));
  return (
    <div style={{ display: 'flex', gap: 18 }}>
      <div style={{ flex: 1, display: 'flex', flexDirection: 'column', gap: 9 }}>
        {steps.map((s, i) => {
          const pct = s.value / max * 100;
          const conv = i > 0 && steps[i - 1].value ? Math.round(s.value / steps[i - 1].value * 100) : null;
          const shade = `color-mix(in srgb, ${accent} ${100 - i * 13}%, #c9d4db)`;
          return (
            <div key={s.label} style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
              <div style={{ width: 132, flexShrink: 0, textAlign: 'right', fontSize: 12, fontWeight: 600, color: 'var(--ink)' }}>{s.label}</div>
              <div style={{ flex: 1, height: 28, position: 'relative' }}>
                <button onClick={() => onStep && onStep(s, i)} title={`${s.label}: ${s.value}`}
                  style={{ width: pct + '%', minWidth: 3, height: '100%', border: 'none', borderRadius: 5, background: shade, cursor: onStep ? 'pointer' : 'default', boxShadow: '0 1px 2px rgba(0,0,0,.05)' }}></button>
                <span className="tabular" style={{ position: 'absolute', left: `calc(${pct}% + 8px)`, top: 5, fontSize: 12.5, fontWeight: 700, color: 'var(--ink)' }}>{s.value.toLocaleString('en-US')}</span>
              </div>
              <div style={{ width: 54, flexShrink: 0, fontSize: 10.5, color: 'var(--ink-soft)', fontWeight: 600, fontFamily: 'var(--mono)' }}>{conv != null ? conv + '%' : ''}</div>
            </div>
          );
        })}
      </div>
      {dropoffs && dropoffs.length > 0 && (
        <div style={{ width: 168, flexShrink: 0, borderLeft: '1px solid var(--line-soft)', paddingLeft: 16, display: 'flex', flexDirection: 'column', gap: 9, justifyContent: 'center' }}>
          <div className="micro" style={{ marginBottom: 1 }}>Drop-off</div>
          {dropoffs.map((d) => (
            <button key={d.label} onClick={() => d.onClick && d.onClick()} style={{ border: 'none', background: 'transparent', textAlign: 'left', cursor: d.onClick ? 'pointer' : 'default', padding: 0, display: 'flex', alignItems: 'center', gap: 8 }}>
              <span style={{ width: 8, height: 8, borderRadius: 9, background: d.tone === 'danger' ? DCH.danger : DCH.warn, flexShrink: 0 }}></span>
              <span style={{ fontSize: 12, color: 'var(--ink-muted)', fontWeight: 600, flex: 1 }}>{d.label}</span>
              <span className="tabular" style={{ fontSize: 12.5, fontWeight: 700 }}>{d.value}</span>
            </button>
          ))}
        </div>
      )}
    </div>
  );
}

/* ---------- Goal trend (monthly leads vs goal line) ---------- */
function GoalTrend({ data, goal, onPoint, height = 220 }) {
  const [tip, setTip] = React.useState(null);
  const pad = { l: 30, r: 12, t: 14, b: 26 };
  const W = 560, H = height, iw = W - pad.l - pad.r, ih = H - pad.t - pad.b;
  const max = dfNiceMax(Math.max(goal * 1.15, ...data.map((d) => d.value)));
  const xOf = (i) => pad.l + (data.length === 1 ? iw / 2 : iw * i / (data.length - 1));
  const yOf = (v) => pad.t + ih - v / max * ih;
  const area = data.map((d, i) => `${i ? 'L' : 'M'}${xOf(i)},${yOf(d.value)}`).join(' ') + ` L${xOf(data.length - 1)},${pad.t + ih} L${xOf(0)},${pad.t + ih} Z`;
  const line = data.map((d, i) => `${i ? 'L' : 'M'}${xOf(i)},${yOf(d.value)}`).join(' ');
  const ticks = 4;
  return (
    <div style={{ position: 'relative' }}>
      <svg viewBox={`0 0 ${W} ${H}`} width="100%" style={{ display: 'block', overflow: 'visible' }}>
        {Array.from({ length: ticks + 1 }).map((_, i) => {
          const v = max / ticks * i, y = yOf(v);
          return <g key={i}><line x1={pad.l} x2={W - pad.r} y1={y} y2={y} stroke={DCH.grid} /><text x={pad.l - 6} y={y + 3} textAnchor="end" fontSize="10" fill={DCH.axis} fontFamily="var(--mono)">{Math.round(v)}</text></g>;
        })}
        <path d={area} fill={DCH.area} opacity="0.5" />
        <path d={line} fill="none" stroke={DCH.line} strokeWidth="2" />
        {/* goal line */}
        <line x1={pad.l} x2={W - pad.r} y1={yOf(goal)} y2={yOf(goal)} stroke={DCH.danger} strokeWidth="1.6" strokeDasharray="5 3" opacity="0.85" />
        <text x={W - pad.r} y={yOf(goal) - 5} textAnchor="end" fontSize="10" fontWeight="700" fill={DCH.danger}>Goal {goal}</text>
        {data.map((d, i) => {
          const below = d.value < goal;
          return (
            <g key={i}>
              <circle cx={xOf(i)} cy={yOf(d.value)} r={below ? 4 : 3.4} fill={below ? DCH.danger : '#fff'} stroke={below ? DCH.danger : DCH.line} strokeWidth="2"
                style={{ cursor: onPoint ? 'pointer' : 'default' }}
                onMouseEnter={() => setTip({ x: xOf(i), y: yOf(d.value), v: d.value, l: d.label, below })}
                onMouseLeave={() => setTip(null)} onClick={() => onPoint && onPoint(d)} />
              {i % 1 === 0 && <text x={xOf(i)} y={H - pad.b + 15} textAnchor="middle" fontSize="9.5" fill={DCH.muted} fontWeight="600">{d.label}</text>}
            </g>
          );
        })}
      </svg>
      {tip && <div style={{ position: 'absolute', left: tip.x, top: tip.y, transform: 'translate(-50%,-120%)', background: '#1a1c1e', color: '#fff', padding: '5px 8px', borderRadius: 6, fontSize: 11, fontWeight: 600, whiteSpace: 'nowrap', pointerEvents: 'none', zIndex: 20 }}>{tip.l}: {tip.v} {tip.below ? '· below goal' : ''}</div>}
    </div>
  );
}

/* ---------- Dual line (two count series) ---------- */
function DualLine({ data, aKey, bKey, aLabel, bLabel, onPoint, height = 220 }) {
  const [tip, setTip] = React.useState(null);
  const pad = { l: 30, r: 12, t: 14, b: 26 };
  const W = 560, H = height, iw = W - pad.l - pad.r, ih = H - pad.t - pad.b;
  const max = dfNiceMax(Math.max(1, ...data.map((d) => Math.max(d[aKey], d[bKey]))));
  const xOf = (i) => pad.l + (data.length === 1 ? iw / 2 : iw * i / (data.length - 1));
  const yOf = (v) => pad.t + ih - v / max * ih;
  const path = (k) => data.map((d, i) => `${i ? 'L' : 'M'}${xOf(i)},${yOf(d[k])}`).join(' ');
  const ticks = 4;
  return (
    <div style={{ position: 'relative' }}>
      <svg viewBox={`0 0 ${W} ${H}`} width="100%" style={{ display: 'block', overflow: 'visible' }}>
        {Array.from({ length: ticks + 1 }).map((_, i) => { const v = max / ticks * i, y = yOf(v); return <g key={i}><line x1={pad.l} x2={W - pad.r} y1={y} y2={y} stroke={DCH.grid} /><text x={pad.l - 6} y={y + 3} textAnchor="end" fontSize="10" fill={DCH.axis} fontFamily="var(--mono)">{Math.round(v)}</text></g>; })}
        <path d={path(aKey)} fill="none" stroke={DCH.line} strokeWidth="2" />
        <path d={path(bKey)} fill="none" stroke={DCH.line2} strokeWidth="2" strokeDasharray="4 3" />
        {data.map((d, i) => (
          <g key={i}>
            <circle cx={xOf(i)} cy={yOf(d[aKey])} r="3" fill="#fff" stroke={DCH.line} strokeWidth="2" style={{ cursor: onPoint ? 'pointer' : 'default' }} onMouseEnter={() => setTip({ x: xOf(i), y: yOf(d[aKey]), lines: [d.label, `${aLabel}: ${d[aKey]}`, `${bLabel}: ${d[bKey]}`] })} onMouseLeave={() => setTip(null)} onClick={() => onPoint && onPoint(d)} />
            <circle cx={xOf(i)} cy={yOf(d[bKey])} r="2.6" fill={DCH.line2} />
            <text x={xOf(i)} y={H - pad.b + 15} textAnchor="middle" fontSize="9.5" fill={DCH.muted} fontWeight="600">{d.label}</text>
          </g>
        ))}
      </svg>
      {tip && <div style={{ position: 'absolute', left: tip.x, top: tip.y, transform: 'translate(-50%,-116%)', background: '#1a1c1e', color: '#fff', padding: '5px 8px', borderRadius: 6, fontSize: 11, fontWeight: 500, whiteSpace: 'nowrap', pointerEvents: 'none', zIndex: 20, lineHeight: 1.35 }}>{tip.lines.map((l, i) => <div key={i} style={{ fontWeight: i === 0 ? 700 : 500 }}>{l}</div>)}</div>}
    </div>
  );
}

/* ---------- Team bars (horizontal, with goal marker) ---------- */
function TeamBars({ rows, goal, onRow }) {
  const max = Math.max(goal * 1.1, ...rows.map((r) => r.value), 1);
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
      {rows.map((r) => {
        const pct = r.value / max * 100;
        const goalPct = goal / max * 100;
        const hit = r.value >= goal;
        return (
          <div key={r.label} style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
            <div style={{ width: 78, flexShrink: 0, fontSize: 12, fontWeight: 600, textAlign: 'right' }}>{r.label}</div>
            <div style={{ flex: 1, height: 24, position: 'relative', background: 'var(--surface-deep)', borderRadius: 5 }}>
              <button onClick={() => onRow && onRow(r)} title={`${r.label}: ${r.value}`}
                style={{ width: pct + '%', height: '100%', border: 'none', borderRadius: 5, background: hit ? DCH.pos : DCH.platform, cursor: onRow ? 'pointer' : 'default' }}></button>
              <div style={{ position: 'absolute', left: goalPct + '%', top: -3, bottom: -3, width: 2, background: DCH.danger, opacity: 0.8 }} title={`Goal ${goal}`}></div>
              <span className="tabular" style={{ position: 'absolute', left: `calc(${pct}% + 7px)`, top: 3, fontSize: 12, fontWeight: 700, color: 'var(--ink)' }}>{r.value}</span>
            </div>
          </div>
        );
      })}
    </div>
  );
}

/* ---------- Mini funnel (sparkline) ---------- */
function MiniFunnel({ values, color = '#3e6e8c' }) {
  const max = Math.max(1, ...values);
  const W = 96, H = 26, bw = W / values.length;
  return (
    <svg width={W} height={H} viewBox={`0 0 ${W} ${H}`} style={{ display: 'block' }}>
      {values.map((v, i) => {
        const h = Math.max(2, v / max * H);
        return <rect key={i} x={i * bw + 1} y={H - h} width={bw - 2} height={h} rx="1" fill={color} opacity={1 - i * 0.1} />;
      })}
    </svg>
  );
}

Object.assign(window, { SeasonFunnel, StepFunnel, GoalTrend, DualLine, TeamBars, MiniFunnel, DCH });
