// app.jsx — three directions of the conversational homepage, on a design canvas.

// Subtle animated telco "node" network — several selectable treatments.
// Canvas + requestAnimationFrame so it animates live (CSS-keyframe captures freeze).
function NodeField({ variant = 'constellation', count = 42, speed = 1 }) {
  const ref = React.useRef(null);
  const speedRef = React.useRef(speed);
  speedRef.current = speed;
  React.useEffect(() => {
    const canvas = ref.current;
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    const parent = canvas.parentElement;
    const dpr = Math.min(window.devicePixelRatio || 1, 2);
    let w = 0, h = 0, raf = 0;
    function size() {
      const r = parent.getBoundingClientRect();
      w = Math.max(1, r.width); h = Math.max(1, r.height);
      canvas.width = w * dpr; canvas.height = h * dpr;
      canvas.style.width = w + 'px'; canvas.style.height = h + 'px';
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
    }
    size();
    const ro = new ResizeObserver(size); ro.observe(parent);
    const N = count;
    const COL = { white: '255,255,255', lav: '160,158,255', apr: '255,169,101' };
    const nodes = Array.from({ length: N }, () => {
      const roll = Math.random();
      return {
        x: Math.random(), y: Math.random(),
        vx: (Math.random() - 0.5) * 0.00020,
        vy: (Math.random() - 0.5) * 0.00020,
        r: Math.random() * 1.5 + 1.1,
        c: roll < 0.10 ? 'lav' : (roll < 0.18 ? 'apr' : 'white'),
        pulse: Math.random(),
        pulseRate: 0.0024 + Math.random() * 0.0034,
      };
    });
    const maxD = variant === 'mesh' ? 0.17 : 0.135;
    let packets = [];
    function spawnPacket() {
      const ai = (Math.random() * N) | 0; const a = nodes[ai];
      let best = -1, bd = maxD;
      for (let j = 0; j < N; j++) {
        if (j === ai) continue;
        const b = nodes[j]; const d = Math.hypot(a.x - b.x, a.y - b.y);
        if (d < bd) { bd = d; best = j; }
      }
      if (best >= 0) packets.push({ a: ai, b: best, t: 0, sp: 0.011 + Math.random() * 0.01 });
    }
    function frame() {
      const sp = speedRef.current;
      ctx.clearRect(0, 0, w, h);
      for (const n of nodes) {
        n.x += n.vx * sp; n.y += n.vy * sp;
        if (n.x < 0 || n.x > 1) n.vx *= -1;
        if (n.y < 0 || n.y > 1) n.vy *= -1;
      }
      // connecting lines (all variants except the sparse "signal")
      if (variant !== 'signal') {
        const lineAlpha = variant === 'mesh' ? 0.17 : 0.13;
        for (let i = 0; i < N; i++) {
          for (let j = i + 1; j < N; j++) {
            const a = nodes[i], b = nodes[j];
            const d = Math.hypot(a.x - b.x, a.y - b.y);
            if (d < maxD) {
              ctx.strokeStyle = 'rgba(255,255,255,' + ((1 - d / maxD) * lineAlpha).toFixed(3) + ')';
              ctx.lineWidth = 1;
              ctx.beginPath();
              ctx.moveTo(a.x * w, a.y * h);
              ctx.lineTo(b.x * w, b.y * h);
              ctx.stroke();
            }
          }
        }
      }
      // SIGNAL — expanding tower rings
      if (variant === 'signal') {
        for (const n of nodes) {
          n.pulse += n.pulseRate * sp;
          if (n.pulse > 1) n.pulse -= 1;
          const rad = n.pulse * maxD * w * 0.95;
          const al = (1 - n.pulse) * 0.30;
          const col = n.c === 'white' ? '160,158,255' : COL[n.c];
          ctx.strokeStyle = 'rgba(' + col + ',' + al.toFixed(3) + ')';
          ctx.lineWidth = 1;
          ctx.beginPath();
          ctx.arc(n.x * w, n.y * h, rad, 0, Math.PI * 2);
          ctx.stroke();
        }
      }
      // DATAFLOW — packets travel along links
      if (variant === 'dataflow') {
        if (packets.length < Math.max(6, N * 0.35) && Math.random() < 0.09 * sp) spawnPacket();
        packets = packets.filter(p => p.t < 1);
        for (const p of packets) {
          p.t += p.sp * sp;
          const a = nodes[p.a], b = nodes[p.b];
          const x = (a.x + (b.x - a.x) * p.t) * w;
          const y = (a.y + (b.y - a.y) * p.t) * h;
          ctx.shadowColor = 'rgba(160,158,255,0.9)'; ctx.shadowBlur = 8;
          ctx.fillStyle = 'rgba(201,198,255,0.95)';
          ctx.beginPath(); ctx.arc(x, y, 1.9, 0, Math.PI * 2); ctx.fill();
          ctx.shadowBlur = 0;
        }
      }
      // node dots
      for (const n of nodes) {
        const accent = n.c !== 'white';
        ctx.shadowColor = accent ? 'rgba(' + COL[n.c] + ',0.9)' : 'transparent';
        ctx.shadowBlur = accent ? 9 : 0;
        ctx.beginPath();
        ctx.arc(n.x * w, n.y * h, n.r, 0, Math.PI * 2);
        ctx.fillStyle = 'rgba(' + COL[n.c] + ',' + (accent ? 0.9 : 0.45) + ')';
        ctx.fill();
      }
      ctx.shadowBlur = 0;
      raf = requestAnimationFrame(frame);
    }
    frame();
    return () => { cancelAnimationFrame(raf); ro.disconnect(); };
  }, [variant, count]);
  return <canvas ref={ref} className="dir-a__nodes" aria-hidden="true"></canvas>;
}

function Carriers({ className = '' }) {
  const list = ['AT&T', 'Verizon', 'Comcast', 'T-Mobile', 'NVIDIA'];
  return (
    <div className={'carrier-strip ' + className}>
      {list.map(c => <span className="carrier" key={c}>{c}</span>)}
    </div>
  );
}

// shared animated background (glows + node field)
function HeroBG({ nodeVariant, nodeCount, nodeSpeed }) {
  return (
    <React.Fragment>
      <div className="dir-a__bg" aria-hidden="true"><div className="dir-a__glows"><i></i></div><NodeField variant={nodeVariant} count={nodeCount} speed={nodeSpeed} /></div>
      <div className="dir-a__grid" aria-hidden="true"></div>
    </React.Fragment>
  );
}

const DEMO_GREETING = [
  "Hi there. You're texting Personal AI — the AI Memory Platform — answering live on the network, the way I would for a real subscriber.",
  "I'm not a stateless chatbot. I run on the network edge with persistent memory, so I remember every interaction and you never start over.",
  "To point you the right way — which carrier or telecom are you with, and what's your role?",
];

function DemoPhone({ storeKey }) {
  return (
    <ChatPhone
      accent="#6756FF"
      carrier="your carrier"
      subtitle="+1 (415) 555·0148 · live demo"
      storeKey={storeKey}
      placeholder="Text the network…"
      greeting={DEMO_GREETING}
    />
  );
}

// ── Mobile V2 — hero snap → chat snap ────────────────────────
const FullSiteArrow = () => (
  <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" fill="none" aria-hidden="true" style={{ display: 'inline', verticalAlign: 'middle', flexShrink: 0 }}>
    <path d="M2.1875 7L11.8125 7" stroke="currentColor" strokeWidth="1.3125" strokeLinecap="round" strokeLinejoin="round"/>
    <path d="M7.875 10.9375L11.8125 7L7.875 3.0625" stroke="currentColor" strokeWidth="1.3125" strokeLinecap="round" strokeLinejoin="round"/>
  </svg>
);

function MobileChatV2() {
  const chatRef = React.useRef(null);
  function scrollToChat() {
    if (chatRef.current) chatRef.current.scrollIntoView({ behavior: 'smooth' });
  }
  return (
    <React.Fragment>

      {/* ── Shared sticky nav ────────────────────────── */}
      <div className="mv2-nav">
        <img src={(window.__resources && window.__resources.paLogo) || 'assets/logos/personal-ai-horizontal-white.svg'} alt="Personal AI" className="m-nav__logo" />
        <a href="https://personalai.webflow.io/home-testing" target="_top" rel="noopener" className="m-nav__link">
          <span>Full site</span><FullSiteArrow />
        </a>
      </div>

      <div className="mv2">

        {/* ── Section 1: Hero ───────────────────────────── */}
        <div className="mv2__hero">
          <HeroBG nodeVariant="constellation" nodeCount={28} nodeSpeed={1} />

          <div className="mv2__body">
            <div className="mv2__copy">
              <div className="dir-a__pill"><span className="dot"></span> Memory · Context · Carrier-native AI</div>
              <h1 className="mv2__head"><span className="grad">The AI Memory Platform</span></h1>
              <p className="mv2__sub">Deliver AI services that remember, learn, and continuously improve, running natively at the network edge. <b>Start a conversation</b> and see how AI becomes more personal with every interaction.</p>
              <div className="mv2__swipe" onClick={scrollToChat} role="button" tabIndex={-1}>
                <span>Scroll to talk to an agent</span>
                <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" fill="none">
                  <path d="M7 2.1875V11.8125" stroke="currentColor" strokeWidth="1.3125" strokeLinecap="round" strokeLinejoin="round"/>
                  <path d="M3.0625 7.875L7 11.8125L10.9375 7.875" stroke="currentColor" strokeWidth="1.3125" strokeLinecap="round" strokeLinejoin="round"/>
                </svg>
              </div>
            </div>
            <div className="mv2__bottom">
              <div className="mv2__customers">
                <span className="dir-a__eyebrow">Our customers</span>
                <Carriers />
              </div>
              <p className="mv2__tagline">The memory layer that remembers, connects, and improves.</p>
            </div>
          </div>
        </div>

        {/* ── Section 2: Chat ───────────────────────────── */}
        <div className="mv2__chat" ref={chatRef} style={{ '--accent': '#6756FF' }}>
          <div className="m-chat">
            <ChatPhone accent="#6756FF" storeKey="mobile-v2" placeholder="Text the network…" greeting={DEMO_GREETING} bare={true} />
          </div>
        </div>

      </div>

    </React.Fragment>
  );
}

// ── Mobile layout — bare chat fills the screen ───────────────
function MobileChat() {
  return (
    <div className="m-view" style={{ '--accent': '#6756FF' }}>
      <div className="m-nav">
        <img
          src={(window.__resources && window.__resources.paLogo) || "assets/logos/personal-ai-horizontal-white.svg"}
          alt="Personal AI"
          className="m-nav__logo"
        />
<a
  href="https://personalai.webflow.io/home-testing"
  target="_top"
  rel="noopener"
  className="m-nav__link"
>
  <span>VIEW FULL WEBSITE</span>
  <svg
    xmlns="http://www.w3.org/2000/svg"
    width="14"
    height="14"
    viewBox="0 0 14 14"
    fill="none"
    aria-hidden="true"
    style={{ display: "inline", verticalAlign: "middle", flexShrink: 0 }}
  >
    <path
      d="M2.1875 7L11.8125 7"
      stroke="currentColor"
      strokeWidth="1.3125"
      strokeLinecap="round"
      strokeLinejoin="round"
    />
    <path
      d="M7.875 10.9375L11.8125 7L7.875 3.0625"
      stroke="currentColor"
      strokeWidth="1.3125"
      strokeLinecap="round"
      strokeLinejoin="round"
    />
  </svg>
</a>
      </div>
      <div className="m-chat">
        <ChatPhone
          accent="#6756FF"
          storeKey="mobile"
          placeholder="Text the network…"
          greeting={DEMO_GREETING}
          bare={true}
        />
      </div>
    </div>
  );
}

// ── Desktop layout 1 — Split: copy left, phone right ─────────
function DesktopSplit({ nodeVariant, nodeCount, nodeSpeed }) {
  return (
    <div className="dir dlay dlay--split" style={{ '--accent': '#6756FF' }}>
      <HeroBG nodeVariant={nodeVariant} nodeCount={nodeCount} nodeSpeed={nodeSpeed} />
      <div className="dlay__nav">
        <div className="dir-a__brand"><img src={(window.__resources && window.__resources.paLogo) || "assets/logos/personal-ai-horizontal-white.svg"} alt="Personal AI" /></div>
        <a className="dir-a__viewsite" href="https://personalai.webflow.io/home-testing" target="_top" rel="noopener"><span>View full website</span>
<svg
  xmlns="http://www.w3.org/2000/svg"
  width="14"
  height="14"
  viewBox="0 0 14 14"
  fill="none"
  aria-hidden="true"
  style={{ display: "block", flexShrink: 0 }}
>
  <path
    d="M2.1875 7L11.8125 7"
    stroke="currentColor"
    strokeWidth="1.3125"
    strokeLinecap="round"
    strokeLinejoin="round"
  />
  <path
    d="M7.875 10.9375L11.8125 7L7.875 3.0625"
    stroke="currentColor"
    strokeWidth="1.3125"
    strokeLinecap="round"
    strokeLinejoin="round"
  />
</svg></a>
      </div>
      <div className="dlay__body">
        <div className="dlay__copy">
          <div className="dir-a__pill"><span className="dot"></span> Memory · Context · Carrier-native AI</div>
          <h1 className="dlay__head"><span className="grad">The AI Memory Platform</span></h1>
          <p className="dlay__sub">Deliver AI services that remember, learn, and continuously improve, running natively at the network edge. <b>Start a conversation</b> and see how AI becomes more personal with every interaction.</p>
        </div>
        <div className="dlay__phone"><DemoPhone storeKey="deskSplit" /></div>
      </div>
      <div className="dlay__bar">
        <span className="dir-a__eyebrow">Our customers</span>
        <Carriers />
        <span className="dlay__bar-tag">The memory layer that remembers, connects, and improves.</span>
      </div>
    </div>
  );
}


const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "nodeStyle": "constellation",
  "density": 42,
  "speed": 1
}/*EDITMODE-END*/;

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const isV2 = window.location.search.indexOf('v2') !== -1 || window.location.hash === '#v2';
  return (
    <React.Fragment>
      <div style={{ width: '100%', height: '100%', overflow: 'hidden' }}>
        <div className="d-view" style={{ height: '100%' }}>
          <DesktopSplit nodeVariant={t.nodeStyle} nodeCount={Math.round(t.density)} nodeSpeed={t.speed} />
        </div>
        {isV2 ? <MobileChatV2 /> : <MobileChat />}
      </div>
      <TweaksPanel title="Tweaks">
        <TweakSection label="Background nodes" />
        <TweakSelect
          label="Style"
          value={t.nodeStyle}
          options={[
            { value: 'constellation', label: 'Constellation — dots + links' },
            { value: 'mesh', label: 'Mesh — dense web' },
            { value: 'signal', label: 'Signal — tower pulses' },
            { value: 'dataflow', label: 'Data flow — moving packets' },
          ]}
          onChange={(v) => setTweak('nodeStyle', v)}
        />
        <TweakSlider label="Density" value={t.density} min={18} max={72} step={1} onChange={(v) => setTweak('density', v)} />
        <TweakSlider label="Speed" value={t.speed} min={0.3} max={2.4} step={0.1} unit="×" onChange={(v) => setTweak('speed', v)} />
      </TweaksPanel>
    </React.Fragment>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
