// Spend Leak Visualizer — animated Sankey-style flow for Solutions page.
// Shows SaaS/license/cloud spend flowing into "waste" buckets, then consolidating.
const { useState: useStateSL, useEffect: useEffectSL } = React;

const LEAK_BEFORE = {
  sources: [
    { name: 'SaaS subscriptions', value: 48 },
    { name: 'Software licensing', value: 22 },
    { name: 'Cloud resources', value: 20 },
    { name: 'Vendor contracts', value: 10 },
  ],
  sinks: [
    { name: 'Used — drives outcomes', value: 42, kind: 'used' },
    { name: 'Overlapping SaaS tools', value: 18, kind: 'waste' },
    { name: 'Unused licenses', value: 12, kind: 'waste' },
    { name: 'Overprovisioned cloud', value: 14, kind: 'waste' },
    { name: 'Redundant vendors', value: 14, kind: 'waste' },
  ],
};
const LEAK_AFTER = {
  sources: [
    { name: 'SaaS subscriptions', value: 30 },
    { name: 'Software licensing', value: 16 },
    { name: 'Cloud resources', value: 14 },
    { name: 'Vendor contracts', value: 8 },
    { name: 'Custom-built alternatives', value: 4 },
  ],
  sinks: [
    { name: 'Used — drives outcomes', value: 62, kind: 'used' },
    { name: 'Strategic reserve', value: 10, kind: 'used' },
  ],
};

window.SpendLeakViz = function SpendLeakViz() {
  const [mode, setMode] = useStateSL('before');
  const [hint, setHint] = useStateSL(false);
  const rootRef = React.useRef(null);
  const autoplayed = React.useRef(false);

  // Autoplay: on first view, flip to "after" for 3s, then return so the
  // user can interact.
  useEffectSL(() => {
    if (!rootRef.current) return;
    const io = new IntersectionObserver(entries => {
      entries.forEach(e => {
        if (e.isIntersecting && !autoplayed.current) {
          autoplayed.current = true;
          io.disconnect();
          setTimeout(() => setMode('after'), 800);
          setTimeout(() => { setMode('before'); setHint(true); }, 3800);
          setTimeout(() => setHint(false), 9000);
        }
      });
    }, { threshold: 0.3 });
    io.observe(rootRef.current);
    return () => io.disconnect();
  }, []);

  const data = mode === 'before' ? LEAK_BEFORE : LEAK_AFTER;
  const totalSource = data.sources.reduce((s, x) => s + x.value, 0);
  const totalSink = data.sinks.reduce((s, x) => s + x.value, 0);
  const wasted = data.sinks.filter(s => s.kind === 'waste').reduce((s, x) => s + x.value, 0);

  // Chart needs ~180px on each side for labels. Approach: keep the canvas
  // compact (W=860) but move the bars inward so labels anchored at
  // (LEFT_X - 8) / (RIGHT_X + 8) render entirely inside the viewBox.
  const W = 860, H = 420;
  const LEFT_X = 200, RIGHT_X = W - 200;
  const BAR_W = 14;
  const GAP = 14;

  // compute positions
  let srcY = 20;
  const srcs = data.sources.map((s) => {
    const h = (s.value / totalSource) * (H - 40 - (data.sources.length - 1) * GAP);
    const item = { ...s, y: srcY, h };
    srcY += h + GAP;
    return item;
  });
  let sinkY = 20;
  const sinks = data.sinks.map((s) => {
    const h = (s.value / totalSink) * (H - 40 - (data.sinks.length - 1) * GAP);
    const item = { ...s, y: sinkY, h };
    sinkY += h + GAP;
    return item;
  });

  // flows: even distribution from each source across sinks weighted by sink share
  const flows = [];
  srcs.forEach((src) => {
    let srcOffset = 0;
    sinks.forEach((sink) => {
      const share = (sink.value / totalSink) * src.h;
      flows.push({
        src, sink,
        srcY0: src.y + srcOffset,
        srcY1: src.y + srcOffset + share,
        kind: sink.kind,
      });
      srcOffset += share;
    });
    // reset sink offsets need separate tracking below
  });
  // recompute sink offsets per sink
  const sinkOffsets = {};
  flows.forEach(f => {
    const o = sinkOffsets[f.sink.name] || 0;
    const share = f.srcY1 - f.srcY0;
    f.sinkY0 = f.sink.y + o;
    f.sinkY1 = f.sink.y + o + share;
    sinkOffsets[f.sink.name] = o + share;
  });

  return (
    <div className="leak-viz" ref={rootRef}>
      <div className="leak-head">
        <div>
          <span className="label-mono">Technology spend · snapshot</span>
          <h3 style={{ fontSize: 28, marginTop: 8 }}>
            {mode === 'before' ? 'Where the money is going today' : 'Where it goes after we\'re done'}
          </h3>
        </div>
        <div className="leak-toggle">
          <button className={mode === 'before' ? 'active' : ''} onClick={() => setMode('before')}>Before</button>
          <button className={mode === 'after' ? 'active' : ''} onClick={() => setMode('after')}>After</button>
          {/* hint removed — users will figure it out */}
        </div>
      </div>

      <div className="leak-svg-wrap">
        <svg viewBox={`0 0 ${W} ${H}`} className="leak-svg" preserveAspectRatio="xMidYMid meet">
          <defs>
            <linearGradient id="leak-flow-used" x1="0" x2="1" y1="0" y2="0">
              <stop offset="0%" stopColor="#5BC5E3" stopOpacity="0.6" />
              <stop offset="100%" stopColor="#10B981" stopOpacity="0.55" />
            </linearGradient>
            <linearGradient id="leak-flow-waste" x1="0" x2="1" y1="0" y2="0">
              <stop offset="0%" stopColor="#6B8BC5" stopOpacity="0.4" />
              <stop offset="100%" stopColor="#ef4444" stopOpacity="0.45" />
            </linearGradient>
          </defs>

          {/* source bars */}
          {srcs.map(s => (
            <g key={'src-' + s.name}>
              <rect x={LEFT_X} y={s.y} width={BAR_W} height={s.h} fill="url(#leak-flow-used)" rx="2" />
              <text x={LEFT_X - 8} y={s.y + s.h / 2 + 4} textAnchor="end" fontSize="12" fontFamily="var(--font-mono)" fill="var(--text-muted)">{s.name}</text>
              <text x={LEFT_X - 8} y={s.y + s.h / 2 + 18} textAnchor="end" fontSize="10" fontFamily="var(--font-mono)" fill="var(--text-dim)">{s.value}%</text>
            </g>
          ))}

          {/* flows */}
          {flows.map((f, i) => {
            const x1 = LEFT_X + BAR_W;
            const x2 = RIGHT_X - BAR_W;
            const cp = (x1 + x2) / 2;
            const path = `
              M ${x1} ${f.srcY0}
              C ${cp} ${f.srcY0}, ${cp} ${f.sinkY0}, ${x2} ${f.sinkY0}
              L ${x2} ${f.sinkY1}
              C ${cp} ${f.sinkY1}, ${cp} ${f.srcY1}, ${x1} ${f.srcY1}
              Z
            `;
            return (
              <path
                key={i}
                d={path}
                fill={f.kind === 'waste' ? 'url(#leak-flow-waste)' : 'url(#leak-flow-used)'}
                opacity={0.7}
                style={{ transition: 'all 0.6s var(--ease-out)' }}
              />
            );
          })}

          {/* sink bars */}
          {sinks.map(s => (
            <g key={'sink-' + s.name}>
              <rect x={RIGHT_X - BAR_W} y={s.y} width={BAR_W} height={s.h} fill={s.kind === 'waste' ? '#ef4444' : '#10B981'} opacity="0.7" rx="2" />
              <text x={RIGHT_X + 8} y={s.y + s.h / 2 + 4} fontSize="12" fontFamily="var(--font-mono)" fill={s.kind === 'waste' ? '#ef4444' : 'var(--text)'}>{s.name}</text>
              <text x={RIGHT_X + 8} y={s.y + s.h / 2 + 18} fontSize="10" fontFamily="var(--font-mono)" fill="var(--text-dim)">{s.value}%</text>
            </g>
          ))}
        </svg>
      </div>

      <div className="leak-summary">
        <div className="leak-summary-item">
          <span className="label-mono">Waste identified</span>
          <div className="leak-summary-num" style={{ color: mode === 'before' ? '#ef4444' : 'var(--brand-success)' }}>
            {mode === 'before' ? `${wasted}%` : '0%'}
          </div>
        </div>
        <div className="leak-summary-item">
          <span className="label-mono">Delivering value</span>
          <div className="leak-summary-num">{data.sinks.filter(s => s.kind === 'used').reduce((a, b) => a + b.value, 0)}%</div>
        </div>
        <div className="leak-summary-item">
          <span className="label-mono">In many cases</span>
          <div className="leak-summary-num" style={{ fontSize: 18, letterSpacing: '-0.01em' }}>
            The savings pay for<br />the entire engagement.
          </div>
        </div>
      </div>
    </div>
  );
};
