/* Light-mode causal graph
   variants:
     'ambient'  — barely visible, hero background
     'mini'     — small, no labels-heavy, for cards
     'showcase' — full, interactive, for atlas detail
*/
const { useState: gUseState, useMemo: gUseMemo } = React;

function CausalGraph({ variant = 'showcase', data, onHoverEdge, className = '' }) {
  const W = 800, H = 480;
  const [hoverEdge, setHoverEdge] = gUseState(null);
  const [hoverNode, setHoverNode] = gUseState(null);
  const isAmbient = variant === 'ambient';
  const isMini = variant === 'mini';

  const D = data || defaultGraphData();
  const nodeById = gUseMemo(() => {
    const m = {}; D.nodes.forEach(n => m[n.id] = n); return m;
  }, [D]);

  const edgePath = (a, b) => {
    const dx = b.x - a.x, dy = b.y - a.y;
    const cx = a.x + dx * 0.5, cy = a.y + dy * 0.5 - 22;
    return `M ${a.x},${a.y} Q ${cx},${cy} ${b.x},${b.y}`;
  };

  const baseAlpha = isAmbient ? 0.18 : 1;

  return (
    <svg viewBox={`0 0 ${W} ${H}`} preserveAspectRatio="xMidYMid meet" className={`w-full h-full ${className}`}
      onMouseLeave={() => { setHoverEdge(null); setHoverNode(null); }}>
      <defs>
        <marker id={`arr-${variant}`} viewBox="0 0 10 10" refX="9" refY="5" markerWidth="4.6" markerHeight="4.6" orient="auto">
          <path d="M 0 0 L 10 5 L 0 10 z" fill="#1E3A8A"/>
        </marker>
      </defs>

      {/* edges */}
      {D.edges.map((e, i) => {
        const a = nodeById[e.from], b = nodeById[e.to];
        if (!a || !b) return null;
        const isHover = hoverEdge === i;
        const w = isAmbient ? 0.7 : Math.max(1, e.strength * (isMini ? 1.8 : 2.4));
        const alpha = isHover ? 1 : baseAlpha * (0.5 + e.strength * 0.5);
        return (
          <g key={i}
            onMouseEnter={() => { setHoverEdge(i); onHoverEdge && onHoverEdge(e); }}>
            <path d={edgePath(a, b)} stroke="transparent" strokeWidth={14} fill="none"/>
            <path d={edgePath(a, b)}
              stroke="#1E3A8A" strokeWidth={w} fill="none" opacity={alpha}
              className={isAmbient ? 'edge-flow' : ''}
              markerEnd={isAmbient ? undefined : `url(#arr-${variant})`}/>
          </g>
        );
      })}

      {/* nodes */}
      {D.nodes.map(n => {
        const isEffect = n.kind === 'effect';
        const isCause = n.kind === 'cause';
        const r = isAmbient ? 4 : (isMini ? 6 : (isEffect ? 9 : 7));
        const isHover = hoverNode === n.id;
        const fill = isAmbient
          ? (isEffect ? '#22D3EE' : '#1D4ED8')
          : isEffect ? '#22D3EE' : 'var(--paper)';
        const stroke = '#1E3A8A';
        return (
          <g key={n.id} onMouseEnter={() => setHoverNode(n.id)}>
            <circle cx={n.x} cy={n.y} r={r + (isHover ? 3 : 0)} fill={fill} stroke={stroke}
              strokeWidth={isHover ? 1.6 : 1.2}
              opacity={isAmbient ? 0.55 : 1}/>
            {!isAmbient && (
              <text x={n.x} y={n.y + r + 16}
                textAnchor="middle"
                fontSize={isMini ? 10 : 11.5}
                style={{ fill: 'var(--ink)' }}
                fontFamily="Geist, system-ui">
                {n.label}
              </text>
            )}
            {!isAmbient && isEffect && (
              <text x={n.x} y={n.y - r - 7}
                textAnchor="middle"
                fontSize={9}
                style={{ fill: 'var(--mute)', letterSpacing: '0.14em', textTransform: 'uppercase' }}
                fontFamily="Geist Mono, ui-monospace">
                EFFECT
              </text>
            )}
          </g>
        );
      })}

      {/* hover tooltip */}
      {!isAmbient && hoverEdge !== null && (() => {
        const e = D.edges[hoverEdge];
        const a = nodeById[e.from], b = nodeById[e.to];
        if (!a || !b) return null;
        const cx = (a.x + b.x) / 2, cy = (a.y + b.y) / 2 - 28;
        const tw = 188, th = 60;
        return (
          <g pointerEvents="none">
            <rect x={cx - tw/2} y={cy - th} width={tw} height={th} rx={10}
              style={{ fill: 'var(--paper)', stroke: 'var(--ink)' }} strokeWidth={1}/>
            <text x={cx - tw/2 + 12} y={cy - th + 18} fontSize={9.5} fontFamily="Geist Mono, ui-monospace"
              style={{ fill: 'var(--mute)', letterSpacing: '0.12em', textTransform: 'uppercase' }}>
              CAUSAL EFFECT
            </text>
            <text x={cx - tw/2 + 12} y={cy - th + 36} fontSize={14} fontFamily="Geist, system-ui"
              style={{ fill: 'var(--ink)' }} fontWeight={600}>
              β = {e.beta>0?'+':''}{e.beta.toFixed(2)}
            </text>
            <text x={cx - tw/2 + 12} y={cy - th + 51} fontSize={10} fontFamily="Geist Mono, ui-monospace"
              fill="#1E3A8A" style={{ letterSpacing: '0.10em', textTransform: 'uppercase' }}>
              CI95 [{e.ci[0].toFixed(2)}, {e.ci[1].toFixed(2)}]
            </text>
          </g>
        );
      })()}
    </svg>
  );
}

function defaultGraphData() {
  return {
    nodes: [
      { id: 'rude',  label: 'Service Rudeness',     kind: 'cause', x: 110, y: 80 },
      { id: 'wait',  label: 'Wait Time',            kind: 'cause', x: 90,  y: 200 },
      { id: 'rep',   label: 'Repair Quality',       kind: 'cause', x: 130, y: 320 },
      { id: 'trans', label: 'Pricing Transparency', kind: 'cause', x: 90,  y: 420 },
      { id: 'load',  label: 'Loaner Vehicle',       kind: 'cause', x: 230, y: 150 },
      { id: 'comm',  label: 'Status Communication', kind: 'cause', x: 250, y: 380 },

      { id: 'trust', label: 'Brand Trust',          kind: 'mediator', x: 420, y: 180 },
      { id: 'sat',   label: 'Visit Satisfaction',   kind: 'mediator', x: 420, y: 320 },

      { id: 'churn', label: 'Customer Churn',       kind: 'effect', x: 680, y: 130 },
      { id: 'repeat',label: 'Repeat Purchase',      kind: 'effect', x: 700, y: 280 },
      { id: 'nps',   label: 'NPS Lift',             kind: 'effect', x: 680, y: 410 },
    ],
    edges: [
      { from: 'rude',  to: 'trust', beta: -0.41, ci: [-0.46,-0.36], strength: 0.82 },
      { from: 'wait',  to: 'sat',   beta: -0.28, ci: [-0.33,-0.23], strength: 0.55 },
      { from: 'rep',   to: 'trust', beta:  0.34, ci: [ 0.30, 0.39], strength: 0.70 },
      { from: 'trans', to: 'trust', beta:  0.22, ci: [ 0.18, 0.27], strength: 0.45 },
      { from: 'load',  to: 'sat',   beta:  0.31, ci: [ 0.26, 0.36], strength: 0.62 },
      { from: 'comm',  to: 'sat',   beta:  0.19, ci: [ 0.15, 0.24], strength: 0.40 },
      { from: 'trust', to: 'churn', beta: -0.52, ci: [-0.58,-0.46], strength: 0.95 },
      { from: 'trust', to: 'repeat',beta:  0.47, ci: [ 0.42, 0.52], strength: 0.88 },
      { from: 'sat',   to: 'repeat',beta:  0.29, ci: [ 0.24, 0.34], strength: 0.58 },
      { from: 'sat',   to: 'nps',   beta:  0.44, ci: [ 0.39, 0.49], strength: 0.80 },
      { from: 'rude',  to: 'churn', beta:  0.18, ci: [ 0.13, 0.23], strength: 0.36 },
    ],
  };
}

window.CausalGraph = CausalGraph;
window.defaultGraphData = defaultGraphData;
