// Meet the Team — split layout with live UI mockups
// Left: 3 employee cards (sidebar). Right: realistic product UI in light mode for the active employee.

const { useState: useTeamSplitState, useEffect: useTeamSplitEffect, useRef: useTeamSplitRef } = React;

/* ===== Typewriter — types out a sequence of text/structured fragments ===== */
function Typewriter({ nodes, active, charsPerTick = 2, tickMs = 16, startDelay = 180 }) {
  // nodes: array of { el: 'text'|'br'|React element factory, value }
  // When `active` flips true, we reset and progressively reveal chars.
  const [count, setCount] = useTeamSplitState(0);
  useTeamSplitEffect(() => {
    if (!active) { setCount(0); return; }
    setCount(0);
    let c = 0;
    let cancelled = false;
    const total = nodes.reduce((n, node) => n + ((node.kind === 'text' || node.kind === 'strong') ? node.value.length : (node.weight || 1)), 0);
    const start = setTimeout(function step() {
      if (cancelled) return;
      c = Math.min(total, c + charsPerTick);
      setCount(c);
      if (c < total) setTimeout(step, tickMs);
    }, startDelay);
    return () => { cancelled = true; clearTimeout(start); };
  }, [active, nodes]);

  // Render progressively
  let remaining = count;
  const out = [];
  for (let i = 0; i < nodes.length; i++) {
    const n = nodes[i];
    if (remaining <= 0) break;
    if (n.kind === 'text') {
      const take = Math.min(n.value.length, remaining);
      out.push(<React.Fragment key={i}>{n.value.slice(0, take)}</React.Fragment>);
      remaining -= take;
    } else if (n.kind === 'br') {
      out.push(<br key={i}/>);
      remaining -= 1;
    } else if (n.kind === 'strong') {
      // Reveal strong as atomic unit, but still counts as multiple chars
      const take = Math.min(n.value.length, remaining);
      if (take < n.value.length) {
        out.push(<strong key={i}>{n.value.slice(0, take)}</strong>);
        remaining = 0;
      } else {
        out.push(<strong key={i}>{n.value}</strong>);
        remaining -= n.value.length;
      }
    } else if (n.kind === 'block') {
      // Block-level element (rendered only once fully 'arrived')
      out.push(<React.Fragment key={i}>{n.render()}</React.Fragment>);
      remaining -= n.weight || 20;
    }
  }
  const total = nodes.reduce((n, node) => n + ((node.kind === 'text' || node.kind === 'strong') ? node.value.length : (node.weight || 1)), 0);
  const typing = count < total;
  return <span className={`tw ${typing ? 'tw-typing' : 'tw-done'}`}>{out}{typing && <span className="tw-caret" aria-hidden="true"/>}</span>;
}

const TALLY_URL = "https://tally.so/r/jaMNq4";
const goToTally = () => window.open(TALLY_URL, "_blank", "noopener");

const EMPLOYEES = [
  {
    id: "watchdog",
    num: "EMP·001",
    name: "Watchdog",
    role: "the auditor",
    sub: "Maps your operations. Hands you the repo.",
  },
  {
    id: "ezra",
    num: "EMP·002",
    name: "Ezra",
    role: "the knowledge employee",
    sub: "Lives in Slack or Teams. Runs on your full company context.",
  },
  {
    id: "mia",
    num: "EMP·003",
    name: "Mia",
    role: "the caller",
    sub: "Answers and makes calls. Reports into Ezra's channel.",
  },
];

/* ===== Right panel mockups ===== */

function GitHubMock() {
  return (
    <div className="gh-mock">
      <div className="gh-head">
        <div className="gh-repo">
          <svg width="14" height="14" viewBox="0 0 16 16" fill="#57606a" aria-hidden="true">
            <path d="M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.714 1.7.75.75 0 1 1-1.072 1.05A2.495 2.495 0 0 1 2 11.5Zm10.5-1h-8a1 1 0 0 0-1 1v6.708A2.486 2.486 0 0 1 4.5 9h8ZM5 12.25a.25.25 0 0 1 .25-.25h3.5a.25.25 0 0 1 .25.25v3.25a.25.25 0 0 1-.4.2l-1.45-1.087a.249.249 0 0 0-.3 0L5.4 15.7a.25.25 0 0 1-.4-.2Z"/>
          </svg>
          <span className="gh-owner">acme-ops</span>
          <span className="gh-slash">/</span>
          <span className="gh-name">operations-repo</span>
          <span className="gh-vis">Private</span>
        </div>
        <div className="gh-head-right">
          <span className="gh-pill">★ 4</span>
          <span className="gh-pill">Fork 1</span>
        </div>
      </div>
      <div className="gh-body">
        <div className="gh-files">
          <div className="gh-filerow gh-folder">
            <FolderIcon /> <span>org</span> <span className="gh-commit">Added key contacts · 2d</span>
          </div>
          <div className="gh-filerow gh-folder">
            <FolderIcon /> <span>processes</span> <span className="gh-commit">Refined dispatch SOP · 2d</span>
          </div>
          <div className="gh-filerow gh-folder">
            <FolderIcon /> <span>vendors</span> <span className="gh-commit">Preferred vendor list · 3d</span>
          </div>
          <div className="gh-filerow gh-folder">
            <FolderIcon /> <span>systems</span> <span className="gh-commit">ServiceTitan mapping · 3d</span>
          </div>
          <div className="gh-filerow gh-folder">
            <FolderIcon /> <span>pain-points</span> <span className="gh-commit">Top 12 ranked · 3d</span>
          </div>
          <div className="gh-filerow">
            <FileIcon /> <span>README.md</span> <span className="gh-commit">Initial audit summary · 3d</span>
          </div>
        </div>
        <div className="gh-readme">
          <div className="gh-readme-head">
            <span>📘</span> <strong>README.md</strong>
          </div>
          <div className="gh-readme-body">
            <h3>Operations audit — Acme Ops</h3>
            <p>3-day audit completed Apr 22. Highest-leverage workflows, ranked by annual hours recovered.</p>
            <ol>
              <li><strong>Inbound call triage</strong> — 1,040 hr/yr · Mia</li>
              <li><strong>Vendor COI chasing</strong> — 620 hr/yr · Ezra</li>
              <li><strong>Weekly owner reporting</strong> — 310 hr/yr · Ezra</li>
            </ol>
          </div>
        </div>
      </div>
    </div>
  );
}

function FolderIcon() {
  return (
    <svg width="14" height="14" viewBox="0 0 16 16" fill="#54aeff" aria-hidden="true">
      <path d="M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z"/>
    </svg>
  );
}
function FileIcon() {
  return (
    <svg width="14" height="14" viewBox="0 0 16 16" fill="#57606a" aria-hidden="true">
      <path d="M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z"/>
    </svg>
  );
}

/* Staggered reveal of Ezra's deal list + actions (fires after the opening line finishes typing) */
function EzraReveal({ active }) {
  const [phase, setPhase] = useTeamSplitState(0); // 0 hidden, 1..3 list items, 4 footer, 5 buttons
  useTeamSplitEffect(() => {
    if (!active) { setPhase(0); return; }
    setPhase(0);
    const timers = [
      setTimeout(() => setPhase(1), 1700),
      setTimeout(() => setPhase(2), 2100),
      setTimeout(() => setPhase(3), 2500),
      setTimeout(() => setPhase(4), 3050),
      setTimeout(() => setPhase(5), 3450),
    ];
    return () => timers.forEach(clearTimeout);
  }, [active]);
  return (
    <React.Fragment>
      <ul className="sl-list">
        <li className={`sl-reveal ${phase >= 1 ? 'in' : ''}`}><strong>Blue Lane Electrical</strong> · $4.2M revenue · 3 locations · retiring owner</li>
        <li className={`sl-reveal ${phase >= 2 ? 'in' : ''}`}><strong>Metro Star</strong> · $12M revenue · $2.1M EBITDA · founder exit</li>
        <li className={`sl-reveal ${phase >= 3 ? 'in' : ''}`}><strong>Precision Repairs</strong> · $6.8M revenue · 82% recurring · growth add-on</li>
      </ul>
      <div className={`sl-text sl-muted sl-reveal ${phase >= 4 ? 'in' : ''}`}>Want me to reach out for more details?</div>
      <div className={`sl-actions sl-reveal ${phase >= 5 ? 'in' : ''}`}>
        <button className="sl-btn sl-btn-primary" onClick={goToTally}>Reach out to all 3</button>
        <button className="sl-btn" onClick={goToTally}>Select which</button>
      </div>
    </React.Fragment>
  );
}

function SlackEzraMock({ active }) {
  const placeholder = "Message #ops-ezra";
  const nodes = [
    { kind: 'text', value: "Hi Michael — I've found " },
    { kind: 'strong', value: "3 new deals" },
    { kind: 'text', value: " matching your search criteria in the DFW area:" },
  ];
  return (
    <div className="sl-mock">
      <div className="sl-head">
        <div className="sl-channel">
          <span className="sl-hash">#</span>
          <span className="sl-channel-name">ops-ezra</span>
        </div>
        <div className="sl-head-right">
          <span className="sl-topic">Ezra's workspace · full context connected</span>
        </div>
      </div>
      <div className="sl-body">
        <div className="sl-message">
          <div className="sl-avatar ezra-avatar">E</div>
          <div className="sl-content">
            <div className="sl-meta">
              <span className="sl-name">Ezra</span>
              <span className="sl-app">APP</span>
              <span className="sl-time">8:42 AM</span>
            </div>
            <div className="sl-text">
              <Typewriter nodes={nodes} active={active} />
            </div>
            <EzraReveal active={active} />
          </div>
        </div>
      </div>
      <div className="sl-compose">
        <form
          className="sl-compose-box"
          onSubmit={(e) => { e.preventDefault(); goToTally(); }}
        >
          <input
            className="sl-compose-input"
            type="text"
            placeholder={placeholder}
            onKeyDown={(e) => { if (e.key === "Enter") { e.preventDefault(); goToTally(); } }}
          />
          <button type="submit" className="sl-send" aria-label="Send">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>
          </button>
        </form>
      </div>
    </div>
  );
}

function MiaReveal({ active }) {
  const [phase, setPhase] = useTeamSplitState(0);
  useTeamSplitEffect(() => {
    if (!active) { setPhase(0); return; }
    setPhase(0);
    const timers = [
      setTimeout(() => setPhase(1), 1600),
      setTimeout(() => setPhase(2), 1950),
      setTimeout(() => setPhase(3), 2300),
      setTimeout(() => setPhase(4), 2650),
      setTimeout(() => setPhase(5), 3100),
    ];
    return () => timers.forEach(clearTimeout);
  }, [active]);
  return (
    <React.Fragment>
      <div className="sl-call-grid">
        <div className={`sl-call-k sl-reveal ${phase >= 1 ? 'in' : ''}`}>Caller</div>
        <div className={`sl-call-v sl-reveal ${phase >= 1 ? 'in' : ''}`}>Margaret Reyes — 847 N Lincoln</div>
        <div className={`sl-call-k sl-reveal ${phase >= 2 ? 'in' : ''}`}>Reason</div>
        <div className={`sl-call-v sl-reveal ${phase >= 2 ? 'in' : ''}`}>Furnace won't start</div>
        <div className={`sl-call-k sl-reveal ${phase >= 3 ? 'in' : ''}`}>Booked</div>
        <div className={`sl-call-v sl-reveal ${phase >= 3 ? 'in' : ''}`}>Tuesday Apr 28 · 10a–12p window</div>
        <div className={`sl-call-k sl-reveal ${phase >= 4 ? 'in' : ''}`}>Tech skill</div>
        <div className={`sl-call-v sl-reveal ${phase >= 4 ? 'in' : ''}`}>Gas-heat diag</div>
      </div>
      <div className={`sl-call-tags sl-reveal ${phase >= 5 ? 'in' : ''}`}>
        <span className="sl-tag sl-tag-ok">✓ Written to ServiceTitan</span>
        <span className="sl-tag sl-tag-ok">✓ Confirmation SMS sent</span>
      </div>
    </React.Fragment>
  );
}

function SlackMiaMock({ active }) {
  const placeholder = "Message #dispatch-mia";
  const headerNodes = [
    { kind: 'text', value: "Inbound · (312) 555-0148 · 4m 22s" },
  ];
  return (
    <div className="sl-mock">
      <div className="sl-head">
        <div className="sl-channel">
          <span className="sl-hash">#</span>
          <span className="sl-channel-name">dispatch-mia</span>
        </div>
        <div className="sl-head-right">
          <span className="sl-topic">Mia · inbound + outbound · 24/7</span>
        </div>
      </div>
      <div className="sl-body">
        <div className="sl-message">
          <div className="sl-avatar mia-avatar">M</div>
          <div className="sl-content">
            <div className="sl-meta">
              <span className="sl-name">Mia</span>
              <span className="sl-app">APP</span>
              <span className="sl-time">2:14 PM</span>
            </div>
            <div className="sl-call-header">
              <span className="sl-call-icon">📞</span>
              <span><Typewriter nodes={headerNodes} active={active} /></span>
            </div>
            <MiaReveal active={active} />
          </div>
        </div>
      </div>
      <div className="sl-compose">
        <form
          className="sl-compose-box"
          onSubmit={(e) => { e.preventDefault(); goToTally(); }}
        >
          <input
            className="sl-compose-input"
            type="text"
            placeholder={placeholder}
            onKeyDown={(e) => { if (e.key === "Enter") { e.preventDefault(); goToTally(); } }}
          />
          <button type="submit" className="sl-send" aria-label="Send">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>
          </button>
        </form>
      </div>
    </div>
  );
}

const CAPTIONS = {
  watchdog: "The deliverable isn't a slide deck. It's a live repository of how your business runs. You own it from day one.",
  ezra:     "Grounded in your full context. Not a chatbot. A teammate.",
  mia:      "Books straight onto your dispatch board. No answering-service miscodes. No Monday-morning cleanup.",
};

function renderMock(id) {
  if (id === "watchdog") return <GitHubMock />;
  if (id === "ezra")     return <SlackEzraMock active={true} />;
  if (id === "mia")      return <SlackMiaMock active={true} />;
  return null;
}

function TeamSplit() {
  const [active, setActive] = useTeamSplitState("ezra");

  return (
    <section id="team" className="team-split">
      <div className="container">
        <div className="ts-head">
          <span className="eyebrow-num">§ 02 / MEET THE TEAM</span>
          <h2 className="ts-headline">
            Three teammates.<br/>
            <span className="text-accent" style={{fontStyle:"italic"}}>One instance.</span>
          </h2>
        </div>

        <div className="ts-layout">
          <aside className="ts-sidebar">
            {EMPLOYEES.map(e => (
              <React.Fragment key={e.id}>
                <button
                  className={`ts-card ${active === e.id ? "active" : ""}`}
                  onClick={() => setActive(e.id)}
                  aria-pressed={active === e.id}
                >
                  <div className="ts-card-num">{e.num}</div>
                  <div className="ts-card-name">
                    {e.name}
                    <span className="ts-card-role"> — {e.role}</span>
                  </div>
                  <div className="ts-card-sub">{e.sub}</div>
                </button>
                {active === e.id && (
                  <div className="ts-panel-inline">
                    <div className="ts-panel" key={`inline-${e.id}`}>
                      {renderMock(e.id)}
                    </div>
                    <p className="ts-caption">{CAPTIONS[e.id]}</p>
                  </div>
                )}
              </React.Fragment>
            ))}
          </aside>

          <div className="ts-panel-wrap ts-panel-wrap-desktop">
            <div className="ts-panel" key={active}>
              {renderMock(active)}
            </div>
            <p className="ts-caption">{CAPTIONS[active]}</p>
          </div>
        </div>
      </div>
    </section>
  );
}

function Team() {
  const [variant, setVariant] = useTeamSplitState(
    () => document.body.dataset.team || "split"
  );
  useTeamSplitEffect(() => {
    const obs = new MutationObserver(() => setVariant(document.body.dataset.team || "split"));
    obs.observe(document.body, { attributes: true, attributeFilter: ["data-team"] });
    return () => obs.disconnect();
  }, []);
  if (variant === "bios") return <TeamBios />;
  return <TeamSplit />;
}

window.Team = Team;
