// components.jsx — Prompt Bank shared components
// Includes: RadarChart, Sidebar, AppHeader, mobile frame, etc.

const { useState, useEffect, useRef, useMemo } = React;

// ─────────── RadarChart ───────────
// values: array of {label, you (0-100), school (0-100)}
function RadarChart({ data, size = 320, animated = true }) {
  const cx = size / 2, cy = size / 2;
  const radius = size * 0.36;
  const N = data.length;

  const angle = (i) => (Math.PI * 2 * i) / N - Math.PI / 2;
  const point = (val, i) => {
    const r = (val / 100) * radius;
    return [cx + Math.cos(angle(i)) * r, cy + Math.sin(angle(i)) * r];
  };
  const polyPath = (key) =>
    data.map((d, i) => point(d[key], i).join(",")).join(" ");

  const rings = [0.25, 0.5, 0.75, 1];

  const [reveal, setReveal] = useState(animated ? 0 : 1);
  useEffect(() => {
    if (!animated) return;
    let raf;
    const t0 = performance.now();
    const tick = (t) => {
      const p = Math.min((t - t0) / 700, 1);
      setReveal(1 - Math.pow(1 - p, 3));
      if (p < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [animated]);

  return (
    <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
      {/* rings */}
      {rings.map((rr, i) => (
        <circle key={i} cx={cx} cy={cy} r={radius * rr}
          fill="none" stroke="var(--line)" strokeWidth="1" />
      ))}
      {/* spokes + labels */}
      {data.map((d, i) => {
        const [x, y] = point(100, i);
        const [lx, ly] = point(118, i);
        return (
          <g key={i}>
            <line x1={cx} y1={cy} x2={x} y2={y} stroke="var(--line)" strokeWidth="1" />
            <text x={lx} y={ly}
              fontFamily="JetBrains Mono, monospace"
              fontSize="10"
              letterSpacing="0.08em"
              textAnchor="middle"
              dominantBaseline="middle"
              fill="var(--mute)">
              {d.label.toUpperCase()}
            </text>
          </g>
        );
      })}
      {/* school target ring */}
      <polygon
        points={polyPath("school")}
        fill="var(--hot)"
        fillOpacity="0.12"
        stroke="var(--hot)"
        strokeWidth="1.5"
        strokeDasharray="4 4"
      />
      {/* you fill */}
      <polygon
        points={polyPath("you")}
        fill="var(--ink)"
        fillOpacity="0.85"
        stroke="var(--ink)"
        strokeWidth="2"
        style={{
          transformOrigin: `${cx}px ${cy}px`,
          transform: `scale(${reveal})`,
          transition: "none",
        }}
      />
      {/* you points */}
      {data.map((d, i) => {
        const [x, y] = point(d.you * reveal, i);
        return <circle key={i} cx={x} cy={y} r="4" fill="var(--pop)" stroke="var(--ink)" strokeWidth="1.5" />;
      })}
    </svg>
  );
}

// ─────────── Sidebar ───────────
function Sidebar({ step, onJump, completed, userName, userGrade, userCountry, streak = 1, onLogout }) {
  // steps 1 (intro) and 2 (prompt) share one sidebar item
  const items = [
    { label: "Эхлэл",      sub: "01", jumpTo: 0, doneStep: 0, activeSteps: [0] },
    { label: "Танилцах",   sub: "02", jumpTo: 1, doneStep: 1, activeSteps: [1] },
    { label: "AI анализ",  sub: "03", jumpTo: 2, doneStep: 2, activeSteps: [2] },
    { label: "Фит оноо",   sub: "04", jumpTo: 3, doneStep: 3, activeSteps: [3, 4] },
  ];
  return (
    <aside className="sidebar">
      <div className="brand">
        <div className="brand-mark"><img src="Promptbank.png" alt="Promptbank logo" style={{ width: "100%", height: "100%", objectFit: "contain" }} /></div>
        <div>Prompt<br/>Bank</div>
      </div>
      <div>
        <div className="nav-section-label">Чиний аялал</div>
        <div className="nav-list">
          {items.map((it, i) => (
            <button key={i}
              className={`nav-item ${it.activeSteps.includes(step) ? "active" : ""} ${completed.has(it.doneStep) ? "done" : ""}`}
              onClick={() => onJump(it.jumpTo)}>
              <span className="num">{it.sub}</span>
              <span>{it.label}</span>
              <span className="check">✓</span>
            </button>
          ))}
        </div>
      </div>
      <div className="student-card">
        <div className="row">
          <div className="avatar">{userName ? userName[0].toUpperCase() : "?"}</div>
          <div>
            <div className="name">{userName || "—"}</div>
            <div className="meta">{[userGrade, userCountry].filter(Boolean).join(" · ") || "—"}</div>
          </div>
        </div>
        <div className="streak-dots" title={`${streak} өдрийн streak`}>
          {Array.from({length: Math.min(streak, 14)}).map((_, i) => (
            <span key={i} className={i < streak - 1 ? "on" : "today"} />
          ))}
        </div>
        <div className="meta" style={{marginTop: 8}}>{streak} ӨДРИЙН STREAK</div>
        {onLogout && (
          <button
            onClick={onLogout}
            style={{
              marginTop: 10,
              width: "100%",
              background: "transparent",
              border: "1px solid var(--line)",
              color: "var(--mute)",
              fontFamily: "var(--font-mono)",
              fontSize: 11,
              letterSpacing: "0.06em",
              padding: "6px 0",
              borderRadius: 6,
              cursor: "pointer",
            }}
          >
            ГАРАХ
          </button>
        )}
      </div>
    </aside>
  );
}

// ─────────── App Header ───────────
function AppHeader({ crumb, schoolLabel = "MIT · Computer Science", streak = 1 }) {
  return (
    <div className="main-top">
      <div className="crumb">
        Мөрөөдлийн сургууль <b>· {schoolLabel}</b> &nbsp;/&nbsp; {crumb}
      </div>
      <div className="top-actions">
        <span className="chip-mini"><span className="live-dot" /> AI ХЯНАЖ БАЙНА</span>
        <span className="chip-mini">{streak} ӨДӨР STREAK 🔥</span>
      </div>
    </div>
  );
}

// ─────────── Typewriter ───────────
function Typewriter({ chunks, speed = 18, onDone, paused = false }) {
  // chunks: array of {text, className}
  const fullText = chunks.map(c => c.text).join("");
  const [n, setN] = useState(0);
  useEffect(() => {
    if (paused) return;
    if (n >= fullText.length) { onDone && onDone(); return; }
    const t = setTimeout(() => setN(n + 1), speed);
    return () => clearTimeout(t);
  }, [n, paused, fullText.length]);

  // walk chunks and slice
  const out = [];
  let consumed = 0;
  for (let i = 0; i < chunks.length; i++) {
    const c = chunks[i];
    if (consumed >= n) break;
    const take = Math.min(c.text.length, n - consumed);
    out.push(<span key={i} className={c.className || ""}>{c.text.slice(0, take)}</span>);
    consumed += take;
  }
  return <>{out}</>;
}

// ─────────── Mobile Frame ───────────
function PhoneFrame({ children }) {
  return (
    <div className="device-shell">
      <div className="iphone">
        <div className="iphone-screen">
          <div className="iphone-notch" />
          <div className="iphone-status">
            <span>9:41</span>
            <span className="right">
              <span style={{fontSize:11}}>5G</span>
              <span style={{display:"inline-block", width:18, height:10, border:"1.5px solid currentColor", borderRadius:2, position:"relative"}}>
                <span style={{position:"absolute", inset:1, background:"currentColor", borderRadius:1}}/>
              </span>
            </span>
          </div>
          <div className="iphone-content m">{children}</div>
        </div>
      </div>
    </div>
  );
}

// expose to other scripts
Object.assign(window, { RadarChart, Sidebar, AppHeader, Typewriter, PhoneFrame });
