/* Supporting interactive components for the concept page */

const TangentPlot = ({ func, h, a, Tex }) => {
  const W = 540, H = 360;
  const PAD = 32;
  const xMin = -2.4, xMax = 2.4;

  // dynamic y range based on function
  const yRanges = {
    "x²": [-1, 5],
  };
  // compute by sampling
  const samples = [];
  const N = 200;
  for (let i = 0; i <= N; i++) {
    const x = xMin + (xMax - xMin) * (i / N);
    const y = func.f(x);
    if (isFinite(y)) samples.push([x, y]);
  }
  let yMin = Math.min(...samples.map(s => s[1]));
  let yMax = Math.max(...samples.map(s => s[1]));
  // include the tangent neighborhood
  const fa = func.f(a);
  yMin = Math.min(yMin, fa - 0.5);
  yMax = Math.max(yMax, fa + 0.5);
  const yPad = (yMax - yMin) * 0.08;
  yMin -= yPad; yMax += yPad;

  const xToPx = (x) => PAD + (x - xMin) / (xMax - xMin) * (W - 2 * PAD);
  const yToPx = (y) => H - PAD - (y - yMin) / (yMax - yMin) * (H - 2 * PAD);

  // function path
  const path = samples.map(([x,y], i) => `${i ? "L" : "M"} ${xToPx(x).toFixed(2)} ${yToPx(y).toFixed(2)}`).join(" ");

  // secant: from (a, f(a)) to (a+h, f(a+h))
  const fah = func.f(a + h);
  const secSlope = (fah - fa) / h;

  // tangent: f(a) + f'(a)(x - a)
  const tSlope = func.df(a);
  const tx0 = xMin, tx1 = xMax;
  const ty0 = fa + tSlope * (tx0 - a);
  const ty1 = fa + tSlope * (tx1 - a);

  // secant extended a bit beyond endpoints for visual continuation
  const sx0 = a - h * 0.4;
  const sx1 = a + h * 1.4;
  const sy0 = fa + secSlope * (sx0 - a);
  const sy1 = fa + secSlope * (sx1 - a);

  return (
    <div className="tp">
      <div className="tp__head">
        <span className="t-meta">Plot · {func.label.replace("f(x) =","f(x) =")}</span>
        <span className="t-mono tp__head-meta">domain ℝ · grid 0.5</span>
      </div>
      <svg viewBox={`0 0 ${W} ${H}`} className="tp__svg">
        <defs>
          <pattern id="tp-grid" width={(W-2*PAD)/8} height={(H-2*PAD)/6} patternUnits="userSpaceOnUse" x={PAD} y={PAD}>
            <path d={`M ${(W-2*PAD)/8} 0 L 0 0 0 ${(H-2*PAD)/6}`} fill="none" stroke="var(--rule-3)" strokeWidth="0.5"/>
          </pattern>
        </defs>
        <rect x={PAD} y={PAD} width={W-2*PAD} height={H-2*PAD} fill="url(#tp-grid)" />
        <rect x={PAD} y={PAD} width={W-2*PAD} height={H-2*PAD} fill="none" stroke="var(--rule)" strokeWidth="1"/>

        {/* axes */}
        {yMin <= 0 && yMax >= 0 && (
          <line x1={PAD} y1={yToPx(0)} x2={W-PAD} y2={yToPx(0)} stroke="var(--rule-2)" strokeWidth="1"/>
        )}
        {xMin <= 0 && xMax >= 0 && (
          <line x1={xToPx(0)} y1={PAD} x2={xToPx(0)} y2={H-PAD} stroke="var(--rule-2)" strokeWidth="1"/>
        )}

        {/* function */}
        <path d={path} fill="none" stroke="var(--ink)" strokeWidth="1.5"/>

        {/* tangent — accent dashed */}
        <line x1={xToPx(tx0)} y1={yToPx(ty0)} x2={xToPx(tx1)} y2={yToPx(ty1)}
              stroke="var(--accent)" strokeWidth="1" strokeDasharray="4 3" />

        {/* secant — solid accent */}
        <line x1={xToPx(sx0)} y1={yToPx(sy0)} x2={xToPx(sx1)} y2={yToPx(sy1)}
              stroke="var(--accent)" strokeWidth="2" />

        {/* h interval at the bottom */}
        <line x1={xToPx(a)} y1={yToPx(yMin) - 12} x2={xToPx(a + h)} y2={yToPx(yMin) - 12}
              stroke="var(--ink)" strokeWidth="1" markerStart="url(#tp-tick)" markerEnd="url(#tp-tick)" />
        <line x1={xToPx(a)} y1={yToPx(yMin) - 16} x2={xToPx(a)} y2={yToPx(yMin) - 8} stroke="var(--ink)" strokeWidth="1" />
        <line x1={xToPx(a+h)} y1={yToPx(yMin) - 16} x2={xToPx(a+h)} y2={yToPx(yMin) - 8} stroke="var(--ink)" strokeWidth="1" />

        {/* points */}
        <circle cx={xToPx(a)} cy={yToPx(fa)} r="4" fill="var(--paper)" stroke="var(--accent)" strokeWidth="2"/>
        <circle cx={xToPx(a+h)} cy={yToPx(fah)} r="3.5" fill="var(--accent)" />

        {/* labels */}
        <text x={xToPx(a)} y={yToPx(fa) - 10} fontFamily="var(--font-mono)" fontSize="10" fill="var(--ink)" textAnchor="middle">a</text>
        <text x={xToPx(a+h)+8} y={yToPx(fah) + 4} fontFamily="var(--font-mono)" fontSize="10" fill="var(--accent)">a+h</text>
      </svg>
      <div className="tp__legend">
        <span><i className="tp__sw tp__sw--ink"></i><span className="t-ui">{func.label}</span></span>
        <span><i className="tp__sw tp__sw--secant"></i><span className="t-ui">Secant · slope {((func.f(a+h)-func.f(a))/h).toFixed(3)}</span></span>
        <span><i className="tp__sw tp__sw--tangent"></i><span className="t-ui">Tangent · slope {func.df(a).toFixed(3)}</span></span>
      </div>
    </div>
  );
};

const LimitTable = ({ func, a, Tex }) => {
  const hs = [1, 0.5, 0.1, 0.05, 0.01, 0.005, 0.001, 0.0001];
  const exact = func.df(a);
  return (
    <table className="lt">
      <thead>
        <tr>
          <th className="lt__h"><span className="t-meta">h</span></th>
          <th className="lt__h"><span className="t-meta">f(a + h)</span></th>
          <th className="lt__h"><span className="t-meta">f(a + h) − f(a)</span></th>
          <th className="lt__h"><span className="t-meta">[f(a + h) − f(a)] / h</span></th>
          <th className="lt__h"><span className="t-meta">|err|</span></th>
        </tr>
      </thead>
      <tbody>
        {hs.map((h, i) => {
          const fah = func.f(a + h);
          const fa  = func.f(a);
          const dq  = (fah - fa) / h;
          const err = Math.abs(dq - exact);
          return (
            <tr key={i} className="lt__row">
              <td className="lt__c t-mono">{h.toFixed(4)}</td>
              <td className="lt__c t-mono">{fah.toFixed(6)}</td>
              <td className="lt__c t-mono">{(fah - fa).toFixed(6)}</td>
              <td className="lt__c t-mono lt__c--em">{dq.toFixed(6)}</td>
              <td className="lt__c t-mono lt__c--err">{err.toExponential(2)}</td>
            </tr>
          );
        })}
        <tr className="lt__row lt__row--limit">
          <td className="lt__c t-mono">→ 0</td>
          <td className="lt__c t-mono">f(a) = {func.f(a).toFixed(6)}</td>
          <td className="lt__c t-mono">→ 0</td>
          <td className="lt__c t-mono lt__c--em lt__c--accent">{exact.toFixed(6)}</td>
          <td className="lt__c t-mono">0</td>
        </tr>
      </tbody>
    </table>
  );
};

const EmbeddingNeighborhood = () => {
  // 2D UMAP-style projection — derivative at center, neighbors plotted by semantic distance
  const W = 1080, H = 380;
  const center = { x: W/2, y: H/2, label: "derivative", kind: "self" };
  const neighbors = [
    { x: 0.18, y: 0.32, label: "differential",            kind: "definition", d: 0.08, mastery:"frontier" },
    { x: 0.27, y: 0.65, label: "tangent line",            kind: "definition", d: 0.12, mastery:"learning" },
    { x: 0.36, y: 0.18, label: "limit",                   kind: "definition", d: 0.14, mastery:"mastered" },
    { x: 0.62, y: 0.22, label: "secant line",             kind: "definition", d: 0.15, mastery:"frontier" },
    { x: 0.72, y: 0.58, label: "rate of change",          kind: "definition", d: 0.18, mastery:"mastered" },
    { x: 0.81, y: 0.30, label: "instantaneous velocity",  kind: "example",    d: 0.22, mastery:"mastered" },
    { x: 0.10, y: 0.50, label: "directional derivative",  kind: "definition", d: 0.24, mastery:"locked"   },
    { x: 0.45, y: 0.78, label: "partial derivative",      kind: "definition", d: 0.26, mastery:"locked"   },
    { x: 0.88, y: 0.72, label: "linear approximation",    kind: "theorem",    d: 0.28, mastery:"learning" },
    { x: 0.20, y: 0.85, label: "differential operator",   kind: "definition", d: 0.30, mastery:"locked"   },
    { x: 0.93, y: 0.45, label: "Jacobian",                kind: "definition", d: 0.32, mastery:"locked"   },
    { x: 0.55, y: 0.10, label: "subdifferential",         kind: "definition", d: 0.36, mastery:"locked"   },
    { x: 0.06, y: 0.18, label: "Newton's method",         kind: "procedure",  d: 0.34, mastery:"learning" },
    { x: 0.40, y: 0.38, label: "chain rule",              kind: "theorem",    d: 0.16, mastery:"frontier" },
    { x: 0.66, y: 0.40, label: "MVT",                     kind: "theorem",    d: 0.20, mastery:"locked"   },
  ];
  return (
    <div className="en">
      <svg viewBox={`0 0 ${W} ${H}`} className="en__svg">
        {/* iso-distance rings */}
        <circle cx={W/2} cy={H/2} r="80"  fill="none" stroke="var(--rule-3)" strokeDasharray="2 3" />
        <circle cx={W/2} cy={H/2} r="160" fill="none" stroke="var(--rule-3)" strokeDasharray="2 3" />
        <circle cx={W/2} cy={H/2} r="240" fill="none" stroke="var(--rule-3)" strokeDasharray="2 3" />

        {/* radial connectors to nearest 6 */}
        {neighbors.slice(0, 6).map((n, i) => (
          <line key={i} x1={W/2} y1={H/2} x2={n.x*W} y2={n.y*H}
                stroke="var(--rule-3)" strokeWidth="0.5" />
        ))}

        {/* nodes */}
        {neighbors.map((n, i) => {
          const cx = n.x * W, cy = n.y * H;
          return (
            <g key={i} className="en__node">
              <circle cx={cx} cy={cy} r={n.kind==="theorem"?5:n.kind==="procedure"?4:3.5}
                      fill={n.mastery==="mastered" ? "var(--ink)" : n.mastery==="frontier" ? "var(--accent)" : "var(--paper)"}
                      stroke={n.mastery==="locked" ? "var(--rule-2)" : "var(--ink)"}
                      strokeWidth="1" />
              <text x={cx + 8} y={cy + 4}
                    fontFamily="var(--font-ui)" fontSize="11"
                    fill={n.mastery==="locked" ? "var(--ink-4)" : "var(--ink)"}>
                {n.label}
              </text>
              <text x={cx + 8} y={cy + 17}
                    fontFamily="var(--font-mono)" fontSize="9"
                    fill="var(--ink-4)">d={n.d}</text>
            </g>
          );
        })}

        {/* center node */}
        <circle cx={W/2} cy={H/2} r="6" fill="var(--accent)" />
        <circle cx={W/2} cy={H/2} r="11" fill="none" stroke="var(--accent)" strokeWidth="1" />
        <text x={W/2 + 14} y={H/2 + 5}
              fontFamily="var(--font-ui)" fontSize="13" fontWeight="500"
              fill="var(--ink)">derivative</text>
      </svg>
      <div className="en__legend">
        <span className="t-meta">Legend</span>
        <span><i className="en__dot en__dot--def" /><span className="t-ui">definition</span></span>
        <span><i className="en__dot en__dot--thm" /><span className="t-ui">theorem</span></span>
        <span><i className="en__dot en__dot--proc" /><span className="t-ui">procedure</span></span>
        <span><i className="en__dot en__dot--ex" /><span className="t-ui">example</span></span>
        <span className="en__legend-sep">·</span>
        <span className="t-meta">Distance</span>
        <span className="t-mono" style={{color:"var(--ink-4)"}}>cosine, qwen3 1024-dim</span>
      </div>
    </div>
  );
};

window.TangentPlot = TangentPlot;
window.LimitTable = LimitTable;
window.EmbeddingNeighborhood = EmbeddingNeighborhood;
