/* global React, LVRD_AGENTS, LVRD_AGENT, LVRD_THREADS, LVRD_PROFILE, LVRD_NOW */
/* global LvAvatar, LvStatusDot, LvTopBar, LvBackBtn, LvIconBtn, LvToggle, LvIcon */
/* global LvAgentBubble, LvOwnerBubble, LvSystemMessage */
/* global LvApprovalCard, LvCompletionCard, LvDailyReport */
/* global LvQuickReplies, LvSendBox */

// ─────────────────────────────────────────────────────────────
// LVRD operator app — Screens
// MessagingInbox · Conversation · Roster · RosterDetail · Settings
// ─────────────────────────────────────────────────────────────

// ── Inbox thread helpers ───────────────────────────────────────
// Derive a card-type badge from the last structured card in the thread.
function getThreadBadge(thread) {
  const last = [...thread.messages].reverse().find(
    (m) => m.kind === "approval" || m.kind === "completion" || m.kind === "report"
  );
  if (!last) return null;
  const map = {
    approval:   { cls: "approval",   text: "Approval" },
    completion: { cls: "completion", text: "Done" },
    report:     { cls: "report",     text: "Briefing" },
  };
  return map[last.kind] || null;
}

// ── Inbox empty state ──────────────────────────────────────────
function InboxEmpty() {
  return (
    <div className="lv-empty-state" style={{ flex: 1, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", paddingTop: 60 }}>
      <div style={{ marginBottom: 20, color: "var(--fg-faint)" }}>
        <LvIcon name="messaging" size={32} />
      </div>
      <h3>Your team is getting set up</h3>
      <p>Once your agents start working, approvals, completions, and daily briefings will appear here.</p>
    </div>
  );
}

// ── Messaging inbox ────────────────────────────────────────────
function MessagingInbox({ onOpenThread, sendMode, setSendMode }) {
  const threads = window.LVRD_THREADS;
  const grouped = {
    waiting: threads.filter((t) => t.section === "waiting"),
    today:   threads.filter((t) => t.section === "today"),
    quiet:   threads.filter((t) => t.section === "quiet"),
  };

  const sections = [
    { id: "waiting", label: "Waiting on you", count: grouped.waiting.length },
    { id: "today",   label: "Today",          count: grouped.today.length },
    { id: "quiet",   label: "Quiet",          count: grouped.quiet.length },
  ];

  const hasAny = threads.length > 0;

  return (
    <React.Fragment>
      <div className="lv-statusbar-pad" />
      <LvTopBar
        title="Messages"
        eyebrow={"Tuesday · " + window.LVRD_NOW}
        trailing={
          <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
            <span className="lv-live" title="Polling every 30 s"><span className="dot" /></span>
            <LvIconBtn name="edit" label="New directive" />
          </div>
        }
      />
      <div className="lv-brand-strip">
        <span className="mark">LVRD</span>
        <span>Operator</span>
        <span className="now">{threads.length + " agents · " + grouped.waiting.length + " waiting"}</span>
      </div>
      <div className="lv-scroll" style={{ flex: 1 }}>
        {!hasAny ? <InboxEmpty /> : null}
        {sections.filter(s => s.count > 0).map((s) => (
          <React.Fragment key={s.id}>
            <div className="lv-section-h">
              <span className="lbl">{s.label}</span>
              <span className="ct">{String(s.count).padStart(2, "0")}</span>
              <span className="line" />
            </div>
            {grouped[s.id].map((thread) => {
              const a = LVRD_AGENT(thread.agentId);
              const badge = getThreadBadge(thread);
              return (
                <div
                  key={thread.id}
                  className={"lv-thread" + (thread.unread ? " unread" : "")}
                  onClick={() => onOpenThread(thread.id)}
                >
                  <LvAvatar initials={a.initials} />
                  <div style={{ minWidth: 0 }}>
                    <div className="who">{a.name}</div>
                    <div className="role">{a.role}</div>
                    <div className="preview">{thread.preview}</div>
                    {badge ? <span className={"lv-thread-badge " + badge.cls}>{badge.text}</span> : null}
                  </div>
                  <div className="meta">
                    <span className="t">{thread.time}</span>
                    <LvStatusDot status={a.status} />
                  </div>
                </div>
              );
            })}
          </React.Fragment>
        ))}
        <div style={{ height: 32 }} />
      </div>
      <div className="lv-sendbox-wrap">
        <LvSendBox
          placeholder={"Tell the team what you need done"}
          mode={sendMode}
          onMic={() => setSendMode(sendMode === "voice" ? "text" : "voice")}
          onSend={() => setSendMode("text")}
        />
      </div>
    </React.Fragment>
  );
}
// ── Conversation ───────────────────────────────────────────────
function Conversation({ thread, onBack, sendMode, setSendMode, onViewAgent, onHandoff }) {
  const a = LVRD_AGENT(thread.agentId);
  const scrollRef = React.useRef(null);
  const [menuOpen, setMenuOpen] = React.useState(false);
  const [muted, setMuted] = React.useState(false);
  const [paused, setPaused] = React.useState(a.status === "off");

  // Live messages appended via quick replies / send box. Reset per thread.
  const [extra, setExtra] = React.useState([]);
  const [chipsHidden, setChipsHidden] = React.useState(false);
  const [typing, setTyping] = React.useState(false);
  const [showEarlier, setShowEarlier] = React.useState(false);
  const [earlyLoading, setEarlyLoading] = React.useState(false);
  const replyTimer = React.useRef(null);
  React.useEffect(() => {
    setExtra([]);
    setChipsHidden(false);
    setTyping(false);
    setShowEarlier(false);
    setEarlyLoading(false);
    if (replyTimer.current) clearTimeout(replyTimer.current);
    return () => { if (replyTimer.current) clearTimeout(replyTimer.current); };
  }, [thread.id]);

  // Build a contextual agent reply for a given quick-reply pick.
  const replyFor = React.useCallback((pick) => {
    const p = (pick || "").toLowerCase();
    if (p.includes("looks good") || p.includes("approve") || p.includes("send it")) {
      return "Sending it out now. I'll ping you when they respond.";
    }
    if (p.includes("short")) {
      return "On it \u2014 trimming to the essentials. Back in five with a tighter draft.";
    }
    if (p.includes("price") || p.includes("cheaper") || p.includes("discount")) {
      return "Got it. Pulling the last three comps again. What's the target \u2014 closer to the Henderson number?";
    }
    if (p.includes("hold") || p.includes("not yet") || p.includes("wait")) {
      return "Holding. Tell me what you want to look at before the next pass.";
    }
    if (p.includes("walk") || p.includes("call")) {
      return "I'll set up a 10-minute call. Morning or afternoon?";
    }
    return "Noted. I'll fold that in and come back with a revision shortly.";
  }, []);

  const onPickReply = (pick) => {
    setExtra((prev) => [...prev, { kind: "owner", text: pick, t: "" }]);
    setChipsHidden(true);
    setTyping(true);
    if (replyTimer.current) clearTimeout(replyTimer.current);
    replyTimer.current = setTimeout(() => {
      setTyping(false);
      setExtra((prev) => [...prev, { kind: "agent", text: replyFor(pick), t: "" }]);
    }, 900);
  };

  React.useEffect(() => {
    if (scrollRef.current) {
      scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
    }
  }, [thread.id, sendMode, extra.length, typing]);

  // Group consecutive same-sender bubbles so we only show the
  // agent eyebrow above the first one in a run.
  const handleLoadEarlier = () => {
    if (!thread.olderMessages || earlyLoading) return;
    setEarlyLoading(true);
    setTimeout(() => {
      setShowEarlier(true);
      setEarlyLoading(false);
    }, 500);
  };

  const items = React.useMemo(() => {
    const older = (showEarlier && thread.olderMessages) ? thread.olderMessages : [];
    const all = [...older, ...thread.messages, ...extra];
    return all.map((m, i) => {
      const prev = all[i - 1];
      const isFirstAgent = m.kind === "agent" && (!prev || prev.kind !== "agent");
      return { m, isFirstAgent };
    });
  }, [thread.id, extra, showEarlier]);

  return (
    <React.Fragment>
      <div className="lv-statusbar-pad" />
      <div className="lv-topbar">
        <LvBackBtn onClick={onBack} />
        <div className="lv-stack" style={{ alignItems: "flex-start", minWidth: 0 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 10, width: "100%", minWidth: 0 }}>
            <LvAvatar initials={a.initials} size="sm" />
            <div style={{ minWidth: 0, flex: 1 }}>
              <div style={{ fontSize: 15, fontWeight: 600, color: "var(--fg-strong)", letterSpacing: "-0.005em", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{a.name}</div>
              <div style={{ fontFamily: "var(--font-mono)", fontSize: 9, letterSpacing: "0.08em", textTransform: "uppercase", color: "var(--fg-subtle)", display: "flex", alignItems: "center", gap: 6, marginTop: 2 }}>
                <LvStatusDot status={a.status} /> {a.status === "active" ? "Working now" : a.status === "idle" ? "Available" : "Paused"}
                <span className="lv-live" title="Polling every 15 s" style={{ marginLeft: 4 }}><span className="dot" /></span>
              </div>
            </div>
          </div>
        </div>
        <button className="lv-iconbtn" onClick={() => setMenuOpen(!menuOpen)} aria-label="Thread actions">
          <LvIcon name="more" size={18} />
        </button>
      </div>
      {menuOpen ? (
        <React.Fragment>
          <div className="lv-popover-scrim" onClick={() => setMenuOpen(false)} />
          <div className="lv-popover" role="menu">
            <div className="item" onClick={() => { setMenuOpen(false); onViewAgent && onViewAgent(a.id); }}>
              <span className="ico"><LvIcon name="user" size={15} /></span>
              <span>View agent</span>
            </div>
            <div className="item toggle" onClick={() => setPaused(!paused)}>
              <span className="left"><span className="ico"><LvIcon name={paused ? "play" : "pause"} size={15} /></span>{paused ? "Resume" : "Pause this agent"}</span>
            </div>
            <div className="item toggle" onClick={() => setMuted(!muted)}>
              <span className="left"><span className="ico"><LvIcon name="bell" size={15} /></span>Mute notifications</span>
              <LvToggle on={muted} onChange={setMuted} />
            </div>
            {a.id !== "chief" ? (
              <div className="item" onClick={() => { setMenuOpen(false); onHandoff && onHandoff(); }}>
                <span className="ico"><LvIcon name="arrow-r" size={15} /></span>
                <span>Hand off to Chief of Staff</span>
              </div>
            ) : null}
            <div className="item danger" onClick={() => setMenuOpen(false)}>
              <span className="ico"><LvIcon name="archive" size={15} /></span>
              <span>Clear conversation</span>
            </div>
          </div>
        </React.Fragment>
      ) : null}
      <div className="lv-scroll" ref={scrollRef}>
        <div className="lv-conv">
          {!showEarlier && thread.olderMessages ? (
            <button
              className="lv-load-earlier"
              onClick={handleLoadEarlier}
              disabled={earlyLoading}
            >
              {earlyLoading ? "Loading…" : "Load earlier messages"}
            </button>
          ) : null}
          {items.map(({ m, isFirstAgent }, i) => {
            if (m.kind === "system") {
              return <LvSystemMessage key={i} text={m.text} expandable={m.expandable} />;
            }
            if (m.kind === "agent") {
              return <LvAgentBubble key={i} text={m.text} name={a.name} showEyebrow={isFirstAgent} />;
            }
            if (m.kind === "owner") {
              return <LvOwnerBubble key={i} text={m.text} />;
            }
            if (m.kind === "approval") {
              return <LvApprovalCard key={i} data={m} agentName={a.name} />;
            }
            if (m.kind === "completion") {
              return <LvCompletionCard key={i} data={m} agentName={a.name} />;
            }
            if (m.kind === "report") {
              return <LvDailyReport key={i} data={m} agentName={a.name} />;
            }
            return null;
          })}
          {typing ? (
            <div className="lv-typing" aria-label={a.name + " is typing"}>
              <span /><span /><span />
            </div>
          ) : null}
          {chipsHidden ? null : (
            <LvQuickReplies items={thread.quickReplies} onPick={onPickReply} />
          )}
        </div>
      </div>
      <div className="lv-sendbox-wrap">
        <LvSendBox
          placeholder={"Message " + a.name}
          mode={sendMode}
          onMic={() => setSendMode(sendMode === "voice" ? "text" : "voice")}
          onSend={() => setSendMode("text")}
        />
      </div>
    </React.Fragment>
  );
}

// ── Roster ─────────────────────────────────────────────────────
function Roster({ onOpenAgent }) {
  const grouped = {
    active: LVRD_AGENTS.filter((a) => a.status === "active"),
    idle:   LVRD_AGENTS.filter((a) => a.status === "idle"),
    off:    LVRD_AGENTS.filter((a) => a.status === "off"),
  };

  const sections = [
    { id: "active", label: "Working now",   count: grouped.active.length },
    { id: "idle",   label: "Available",     count: grouped.idle.length },
    { id: "off",    label: "Paused",        count: grouped.off.length },
  ];

  return (
    <React.Fragment>
      <div className="lv-statusbar-pad" />
      <LvTopBar
        title="Your team"
        eyebrow={"7 agents \u00b7 1 working now"}
      />
      <div className="lv-roster-summary">
        <div className="stat"><span className="n">{grouped.active.length}</span><span className="l">Working</span></div>
        <div className="stat"><span className="n">{grouped.idle.length}</span><span className="l">Available</span></div>
        <div className="stat"><span className="n">{grouped.off.length}</span><span className="l">Paused</span></div>
      </div>
      <div className="lv-scroll" style={{ flex: 1 }}>
        {sections.filter(s => s.count > 0).map((s) => (
          <React.Fragment key={s.id}>
            <div className="lv-section-h">
              <span className="lbl">{s.label}</span>
              <span className="ct">{String(s.count).padStart(2, "0")}</span>
              <span className="line" />
            </div>
            {grouped[s.id].map((a) => (
              <div className="lv-agent-card" key={a.id} onClick={() => onOpenAgent(a.id)}>
                <LvAvatar initials={a.initials} />
                <div>
                  <div className="who">{a.name}</div>
                  <div className="role">{a.role}</div>
                  <div className="now">{a.workingOn}</div>
                </div>
                <LvIcon name="chev" size={16} />
              </div>
            ))}
          </React.Fragment>
        ))}
        <div style={{ height: 24 }} />
      </div>
    </React.Fragment>
  );
}

// ── Roster Detail ──────────────────────────────────────────────
function RosterDetail({ agent, onBack, onSendDirective }) {
  return (
    <React.Fragment>
      <div className="lv-statusbar-pad" />
      <div className="lv-topbar">
        <LvBackBtn onClick={onBack} />
        <div className="lv-stack">
          <span className="lv-eyebrow">Agent</span>
          <h1 className="compact">{agent.name}</h1>
        </div>
        <LvIconBtn name="more" label="More" />
      </div>
      <div className="lv-scroll" style={{ flex: 1 }}>
        <div className="lv-agent-detail">
          <div className="hero">
            <LvAvatar initials={agent.initials} size="lg" />
            <div className="role">{agent.role}</div>
            <div className="who">{agent.name}</div>
            <div className="desc">{agent.desc}</div>
            <div className="lv-status-row">
              <LvStatusDot status={agent.status} />
              {agent.status === "active" ? "Working now" : agent.status === "idle" ? "Available" : "Paused"}
            </div>
          </div>
          <span className="lv-accent-line" />
          <div className="panel">
            <h3>Working on</h3>
            <p>{agent.workingOn}</p>
          </div>
          <span className="lv-accent-line" />
          <div className="panel">
            <h3>Recently completed</h3>
            <ul>
              {agent.recent.map((r, i) => <li key={i}><span>{r}</span></li>)}
            </ul>
          </div>
          <div style={{ padding: "8px 24px 32px" }}>
            <button className="lv-btn primary block" onClick={onSendDirective}>
              Send a directive
            </button>
          </div>
        </div>
      </div>
    </React.Fragment>
  );
}

// ── Settings ───────────────────────────────────────────────────
function Settings({ theme, setTheme, openSub, onLogout }) {
  const p = LVRD_PROFILE;
  const [quietHours, setQuietHours] = React.useState(true);
  const [approvals, setApprovals] = React.useState(true);
  const [escalations, setEscalations] = React.useState(true);
  const [briefings, setBriefings] = React.useState(false);
  const [completions, setCompletions] = React.useState(false);

  return (
    <React.Fragment>
      <div className="lv-statusbar-pad" />
      <LvTopBar title="Account" />
      <div className="lv-scroll" style={{ flex: 1 }}>
        <div className="lv-profile-card">
          <LvAvatar initials={p.initials} size="lg" />
          <div>
            <div className="name">{p.name}</div>
            <div className="sub">{p.company}</div>
          </div>
        </div>

        <div className="lv-set-section">
          <div className="h"><span className="lbl">Profile</span></div>
          <div className="lv-set-row" onClick={() => openSub("profile")}><span className="k">Name</span><span className="v">{p.name}</span><span className="chev"><LvIcon name="chev" size={14} /></span></div>
          <div className="lv-set-row" onClick={() => openSub("profile")}><span className="k">Email</span><span className="v">{p.email}</span><span className="chev"><LvIcon name="chev" size={14} /></span></div>
          <div className="lv-set-row" onClick={() => openSub("profile")}><span className="k">Phone</span><span className="v">{p.phone}</span><span className="chev"><LvIcon name="chev" size={14} /></span></div>
          <div className="lv-set-row" onClick={() => openSub("profile")}><span className="k">Company</span><span className="v">{p.company}</span><span className="chev"><LvIcon name="chev" size={14} /></span></div>
        </div>

        <div className="lv-set-section">
          <div className="h"><span className="lbl">Billing</span></div>
          <div className="lv-set-row"><span className="k">Plan</span><span className="v">{p.plan}</span><span className="chev"><LvIcon name="chev" size={14} /></span></div>
          <div className="lv-set-row"><span className="k">Next charge</span><span className="v">{p.nextCharge}</span></div>
          <div className="lv-set-row" onClick={() => openSub("payment")}><span className="k">Payment method</span><span className="v">{"Visa \u2022\u2022\u2022\u2022 4412"}</span><span className="chev"><LvIcon name="chev" size={14} /></span></div>
          <div className="lv-set-row"><span className="k">Invoices</span><span className="v">{p.invoiceCount}</span><span className="chev"><LvIcon name="chev" size={14} /></span></div>
        </div>

        <div className="lv-set-section">
          <div className="h"><span className="lbl">Human team</span><span style={{ fontFamily: "var(--font-mono)", fontSize: 10, color: "var(--fg-faint)" }}>1 person</span></div>
          <div className="lv-set-row"><span className="k">You</span><span className="v">Owner</span></div>
          <div className="lv-set-row" onClick={() => openSub("invite")}><span className="k" style={{ color: "var(--accent)" }}>Invite a teammate</span><span className="chev"><LvIcon name="chev" size={14} /></span></div>
        </div>

        <div className="lv-set-section">
          <div className="h"><span className="lbl">Notifications</span></div>
          <div className="lv-set-row"><span className="k">Approvals waiting</span><LvToggle on={approvals} onChange={setApprovals} /></div>
          <div className="lv-set-row"><span className="k">Escalations</span><LvToggle on={escalations} onChange={setEscalations} /></div>
          <div className="lv-set-row"><span className="k">Daily briefings</span><LvToggle on={briefings} onChange={setBriefings} /></div>
          <div className="lv-set-row"><span className="k">Routine completions</span><LvToggle on={completions} onChange={setCompletions} /></div>
          <div className="lv-set-row"><span className="k">Quiet hours <span style={{ display: "block", fontSize: 12, color: "var(--fg-muted)", fontWeight: 400, marginTop: 2 }}>{"9 PM \u2013 7 AM"}</span></span><LvToggle on={quietHours} onChange={setQuietHours} /></div>
        </div>

        <div className="lv-set-section">
          <div className="h"><span className="lbl">Appearance</span></div>
          <div className="lv-set-row"><span className="k">Dark mode</span>
            <LvToggle on={theme === "dark"} onChange={(on) => setTheme(on ? "dark" : "light")} />
          </div>
        </div>

        <div className="lv-set-section">
          <div className="h"><span className="lbl">Support</span></div>
          <div className="lv-set-row"><span className="k">Reach LVRD</span><span className="chev"><LvIcon name="chev" size={14} /></span></div>
          <div className="lv-set-row"><span className="k">Methodology</span><span className="chev"><LvIcon name="chev" size={14} /></span></div>
          <div className="lv-set-row"><span className="k">Privacy &amp; data</span><span className="chev"><LvIcon name="chev" size={14} /></span></div>
        </div>

        {onLogout ? (
          <div className="lv-set-section">
            <div className="h"><span className="lbl">Session</span></div>
            <div className="lv-set-row danger" onClick={onLogout}>
              <span className="k">Sign out</span>
              <span className="chev"><LvIcon name="chev" size={14} /></span>
            </div>
          </div>
        ) : null}

        <div style={{ padding: "20px 24px 16px", display: "flex", alignItems: "center", justifyContent: "space-between" }}>
          <span style={{ fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: "0.12em", textTransform: "uppercase", color: "var(--fg-faint)" }}>{"Build 1.0.4 \u00b7 May 2026"}</span>
          <span className="lv-wordmark" style={{ fontFamily: "var(--font-sans)", fontWeight: 900, letterSpacing: "0.18em", fontSize: 11, color: "var(--fg-faint)" }}>LVRD</span>
        </div>
        <div style={{ height: 32 }} />
      </div>
    </React.Fragment>
  );
}

// ── Settings · Edit profile ────────────────────────────────────
function ProfileEdit({ onBack, onSave }) {
  const p = LVRD_PROFILE;
  const [name, setName] = React.useState(p.name);
  const [email, setEmail] = React.useState(p.email);
  const [phone, setPhone] = React.useState(p.phone);
  const [company, setCompany] = React.useState(p.company);

  return (
    <React.Fragment>
      <div className="lv-statusbar-pad" />
      <div className="lv-topbar">
        <LvBackBtn onClick={onBack} />
        <div className="lv-stack">
          <span className="lv-eyebrow">Account</span>
          <h1 className="compact">Profile</h1>
        </div>
        <LvIconBtn name="more" label="More" />
      </div>
      <div className="lv-scroll" style={{ flex: 1 }}>
        <div className="lv-form">
          <div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 12, padding: "16px 20px 24px" }}>
            <div style={{ position: "relative" }}>
              <LvAvatar initials={p.initials} size="lg" />
              <button className="lv-iconbtn" style={{ position: "absolute", right: -6, bottom: -6, width: 28, height: 28 }} aria-label="Change photo">
                <LvIcon name="edit" size={13} />
              </button>
            </div>
            <span style={{ fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: "0.08em", textTransform: "uppercase", color: "var(--fg-subtle)" }}>Owner</span>
          </div>

          <div className="lv-form-section">
            <span className="lbl">Name</span>
            <div className="lv-form-row col">
              <input className="lv-field" value={name} onChange={(e) => setName(e.target.value)} />
            </div>
          </div>

          <div className="lv-form-section">
            <span className="lbl">Contact</span>
            <div className="lv-form-row col">
              <span className="lv-field-lbl">Email</span>
              <input className="lv-field" type="email" value={email} onChange={(e) => setEmail(e.target.value)} />
            </div>
            <div className="lv-form-row col">
              <span className="lv-field-lbl">Phone</span>
              <input className="lv-field mono" type="tel" value={phone} onChange={(e) => setPhone(e.target.value)} />
              <span className="lv-field-hint">Used for push notifications and after-hours escalations.</span>
            </div>
          </div>

          <div className="lv-form-section">
            <span className="lbl">Company</span>
            <div className="lv-form-row col">
              <input className="lv-field" value={company} onChange={(e) => setCompany(e.target.value)} />
              <span className="lv-field-hint">This is the name LVRD uses on customer-facing communications.</span>
            </div>
          </div>

          <div style={{ height: 24 }} />
        </div>
        <div className="lv-form-foot">
          <div style={{ display: "flex", gap: 8 }}>
            <button className="lv-btn secondary" onClick={onBack}>Cancel</button>
            <button className="lv-btn primary" onClick={onSave}>Save changes</button>
          </div>
        </div>
      </div>
    </React.Fragment>
  );
}

// ── Settings · Invite teammate ─────────────────────────────────
function InviteTeammate({ onBack, onSend }) {
  const [name, setName] = React.useState("");
  const [email, setEmail] = React.useState("");
  const [phone, setPhone] = React.useState("");
  const [role, setRole] = React.useState("manager");
  const [note, setNote] = React.useState("");

  const roles = [
    { value: "owner",   name: "Owner",      desc: "Full access. Approves on your behalf, edits billing, hires and pauses agents." },
    { value: "manager", name: "Manager",    desc: "Reads everything. Approves work in threads you assign. Can\u2019t change billing or hire." },
    { value: "field",   name: "Field crew", desc: "Reads the day\u2019s schedule and assigned threads. No approvals." },
    { value: "read",    name: "Read-only",  desc: "Sees activity, gets briefings. Can\u2019t reply or approve." },
  ];

  return (
    <React.Fragment>
      <div className="lv-statusbar-pad" />
      <div className="lv-topbar">
        <LvBackBtn onClick={onBack} />
        <div className="lv-stack">
          <span className="lv-eyebrow">Human team</span>
          <h1 className="compact">Invite a teammate</h1>
        </div>
      </div>
      <div className="lv-scroll" style={{ flex: 1 }}>
        <div className="lv-form">
          <p className="lv-form-intro">
            {"They\u2019ll get a text and an email with a sign-in link. You can change their access anytime."}
          </p>

          <div className="lv-form-section">
            <span className="lbl">Currently on the team</span>
            <div className="lv-teammates">
              <div className="lv-teammate-row">
                <LvAvatar initials="RB" />
                <div>
                  <div className="who">Ryan Beck</div>
                  <div className="role">{"Owner \u00b7 You"}</div>
                </div>
                <span className="badge">Active</span>
              </div>
            </div>
          </div>

          <div className="lv-form-section">
            <span className="lbl">Person</span>
            <div className="lv-form-row col">
              <span className="lv-field-lbl">Name</span>
              <input className="lv-field" placeholder="Full name" value={name} onChange={(e) => setName(e.target.value)} />
            </div>
            <div className="lv-form-row col">
              <span className="lv-field-lbl">Email</span>
              <input className="lv-field" type="email" placeholder="name@company.com" value={email} onChange={(e) => setEmail(e.target.value)} />
            </div>
            <div className="lv-form-row col">
              <span className="lv-field-lbl">Phone <span style={{ color: "var(--fg-faint)" }}>(optional)</span></span>
              <input className="lv-field mono" type="tel" placeholder="(312) 555-0000" value={phone} onChange={(e) => setPhone(e.target.value)} />
              <span className="lv-field-hint">{"If provided, they\u2019ll get a text with their sign-in link."}</span>
            </div>
          </div>

          <div className="lv-form-section">
            <span className="lbl">Access</span>
            <div className="lv-seg">
              {roles.map((r) => (
                <div key={r.value} className={"lv-seg-opt" + (role === r.value ? " on" : "")} onClick={() => setRole(r.value)}>
                  <span className="ring" />
                  <div>
                    <div className="opt-name">{r.name}</div>
                    <div className="opt-desc">{r.desc}</div>
                  </div>
                </div>
              ))}
            </div>
          </div>

          <div className="lv-form-section">
            <span className="lbl">Note <span style={{ color: "var(--fg-faint)", textTransform: "none", letterSpacing: 0, fontFamily: "var(--font-sans)" }}>(optional)</span></span>
            <div className="lv-form-row col">
              <textarea className="lv-field" placeholder="A short note that goes with the invite." rows={3} value={note} onChange={(e) => setNote(e.target.value)} style={{ resize: "none", fontFamily: "var(--font-sans)" }} />
            </div>
          </div>

          <div style={{ height: 24 }} />
        </div>
        <div className="lv-form-foot">
          <div style={{ display: "flex", gap: 8 }}>
            <button className="lv-btn secondary" onClick={onBack}>Cancel</button>
            <button className="lv-btn primary" onClick={onSend} disabled={!name || !email}>Send invitation</button>
          </div>
        </div>
      </div>
    </React.Fragment>
  );
}

// ── Settings · Update payment method ───────────────────────────
function PaymentMethod({ onBack, onSave }) {
  const [num, setNum] = React.useState("");
  const [exp, setExp] = React.useState("");
  const [cvc, setCvc] = React.useState("");
  const [zip, setZip] = React.useState("");
  const [makeDefault, setMakeDefault] = React.useState(true);

  // simple input formatters
  const fmtNum = (v) => v.replace(/[^0-9]/g, "").slice(0, 19).replace(/(.{4})/g, "$1 ").trim();
  const fmtExp = (v) => {
    const d = v.replace(/[^0-9]/g, "").slice(0, 4);
    return d.length > 2 ? d.slice(0, 2) + "/" + d.slice(2) : d;
  };
  const fmtCvc = (v) => v.replace(/[^0-9]/g, "").slice(0, 4);

  return (
    <React.Fragment>
      <div className="lv-statusbar-pad" />
      <div className="lv-topbar">
        <LvBackBtn onClick={onBack} />
        <div className="lv-stack">
          <span className="lv-eyebrow">Billing</span>
          <h1 className="compact">Payment method</h1>
        </div>
      </div>
      <div className="lv-scroll" style={{ flex: 1 }}>
        <div className="lv-form">
          <p className="lv-form-intro">
            {"Charged on the 14th each month. Update the card on file or replace it. You\u2019ll get a receipt at "}{LVRD_PROFILE.email}.
          </p>

          <div className="lv-form-section">
            <span className="lbl">Card on file</span>
            <div className="lv-card-onfile">
              <div className="head">
                <span className="lbl">Visa</span>
                <span className="tag">Default</span>
              </div>
              <div className="num">{"\u2022\u2022\u2022\u2022  \u2022\u2022\u2022\u2022  \u2022\u2022\u2022\u2022  4412"}</div>
              <div className="row">
                <span><span className="k">EXP </span>11/27</span>
                <span><span className="k">ADDED </span>Mar 2025</span>
                <span><span className="k">NEXT </span>Jun 14</span>
              </div>
            </div>
            <div style={{ padding: "12px 20px 4px" }}>
              <button className="lv-btn ghost" style={{ color: "var(--fg-muted)", padding: "8px 0" }}>Remove this card</button>
            </div>
          </div>

          <div className="lv-form-section">
            <span className="lbl">Replace card</span>
            <div className="lv-form-row col">
              <span className="lv-field-lbl">Card number</span>
              <input className="lv-field mono" placeholder="1234 5678 9012 3456" value={num} onChange={(e) => setNum(fmtNum(e.target.value))} inputMode="numeric" />
            </div>
            <div className="lv-form-row grid">
              <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
                <span className="lv-field-lbl">Expiry</span>
                <input className="lv-field mono" placeholder="MM/YY" value={exp} onChange={(e) => setExp(fmtExp(e.target.value))} inputMode="numeric" />
              </div>
              <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
                <span className="lv-field-lbl">CVC</span>
                <input className="lv-field mono" placeholder="123" value={cvc} onChange={(e) => setCvc(fmtCvc(e.target.value))} inputMode="numeric" />
              </div>
            </div>
            <div className="lv-form-row col">
              <span className="lv-field-lbl">Postal code</span>
              <input className="lv-field mono" placeholder="60611" value={zip} onChange={(e) => setZip(e.target.value.replace(/[^0-9A-Za-z\s-]/g, "").slice(0, 10))} inputMode="numeric" />
            </div>
          </div>

          <div className="lv-form-section">
            <span className="lbl">Options</span>
            <div className="lv-set-row" onClick={() => setMakeDefault(!makeDefault)}>
              <span className="k" style={{ fontSize: 14, fontWeight: 500 }}>Make default<span style={{ display: "block", fontSize: 12, color: "var(--fg-muted)", fontWeight: 400, marginTop: 2 }}>Future charges go to this card.</span></span>
              <LvToggle on={makeDefault} onChange={setMakeDefault} />
            </div>
          </div>

          <div style={{ padding: "0 24px 8px" }}>
            <span style={{ fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: "0.06em", color: "var(--fg-faint)", lineHeight: 1.5 }}>
              Card details are encrypted on your device and stored by Stripe. LVRD never sees the full number.
            </span>
          </div>

          <div style={{ height: 24 }} />
        </div>
        <div className="lv-form-foot">
          <div style={{ display: "flex", gap: 8 }}>
            <button className="lv-btn secondary" onClick={onBack}>Cancel</button>
            <button className="lv-btn primary" onClick={onSave} disabled={!num || !exp || !cvc}>Save card</button>
          </div>
        </div>
      </div>
    </React.Fragment>
  );
}

Object.assign(window, {
  MessagingInbox, Conversation, Roster, RosterDetail, Settings,
  ProfileEdit, InviteTeammate, PaymentMethod,
});

// ── Auth · Phone entry ─────────────────────────────────────────
function PhoneEntry({ onSent }) {
  const [rawDigits, setRawDigits] = React.useState("");
  const [loading, setLoading] = React.useState(false);
  const [error, setError] = React.useState(null);

  function formatDisplay(digits) {
    if (digits.length <= 3) return digits;
    if (digits.length <= 6) return "(" + digits.slice(0, 3) + ") " + digits.slice(3);
    return "(" + digits.slice(0, 3) + ") " + digits.slice(3, 6) + "-" + digits.slice(6, 10);
  }

  function handleChange(e) {
    const d = e.target.value.replace(/\D/g, "").slice(0, 10);
    setRawDigits(d);
    if (error) setError(null);
  }

  const canSubmit = rawDigits.length >= 10;

  async function handleSubmit() {
    if (!canSubmit || loading) return;
    setLoading(true);
    setError(null);
    const e164 = "+1" + rawDigits.slice(0, 10);
    try {
      const res = await fetch("https://app.lvrd.ai/api/auth/send-code", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ phone: e164 }),
      });
      if (res.status === 429) {
        setError("Too many requests. Please wait a minute and try again.");
      } else if (!res.ok) {
        const data = await res.json().catch(function () { return {}; });
        setError(data.message || "Something went wrong. Please try again.");
      } else {
        onSent(e164);
      }
    } catch (err) {
      setError("Network error. Check your connection and try again.");
    } finally {
      setLoading(false);
    }
  }

  return (
    <div className="lv-auth">
      <div className="lv-statusbar-pad" />
      <div className="lv-auth-top">
        <span className="lv-auth-wordmark">LVRD</span>
      </div>
      <div className="lv-auth-body">
        <div className="lv-auth-form">
          <div>
            <h1 className="lv-auth-title">Sign in</h1>
            <p className="lv-auth-sub">Enter your phone number to receive a verification code.</p>
          </div>
          <div className="lv-auth-field-wrap">
            <span className="lv-auth-prefix">+1</span>
            <input
              className="lv-auth-field"
              type="tel"
              inputMode="numeric"
              placeholder="(312) 555-0000"
              value={formatDisplay(rawDigits)}
              onChange={handleChange}
              onKeyDown={function (e) { if (e.key === "Enter" && canSubmit) handleSubmit(); }}
              autoFocus
            />
          </div>
          {error ? <div className="lv-auth-error" role="alert" aria-live="polite">{error}</div> : null}
          <button
            className="lv-btn primary block lv-auth-btn"
            onClick={handleSubmit}
            disabled={!canSubmit || loading}
          >
            {loading ? "Sending…" : "Send code"}
          </button>
        </div>
      </div>
      <div className="lv-auth-foot">
        <span className="lv-auth-legal">By signing in you agree to our Terms and Privacy Policy.</span>
      </div>
    </div>
  );
}

// ── Auth · Code verification ───────────────────────────────────
function CodeVerify({ phone, onVerified, onBack }) {
  const [digits, setDigits] = React.useState(["", "", "", "", "", ""]);
  const [loading, setLoading] = React.useState(false);
  const [error, setError] = React.useState(null);
  const [cooldown, setCooldown] = React.useState(60);
  const [resending, setResending] = React.useState(false);
  const inputsRef = React.useRef([]);

  // Count down the resend cooldown
  React.useEffect(function () {
    if (cooldown <= 0) return;
    var id = setTimeout(function () { setCooldown(function (c) { return c - 1; }); }, 1000);
    return function () { clearTimeout(id); };
  }, [cooldown]);

  // Display phone: strip +1, format as (NNN) NNN-NNNN
  var bare = phone.replace(/^\+1/, "");
  var displayPhone = "(" + bare.slice(0, 3) + ") " + bare.slice(3, 6) + "-" + bare.slice(6, 10);

  async function verify(code) {
    setLoading(true);
    setError(null);
    try {
      const res = await fetch("https://app.lvrd.ai/api/auth/verify", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ phone: phone, code: code }),
      });
      if (!res.ok) {
        const data = await res.json().catch(function () { return {}; });
        if (data.code === "MAX_ATTEMPTS") {
          setError("Too many incorrect codes. Tap ‘Resend’ for a fresh code.");
        } else if (data.code === "EXPIRED") {
          setError("Code expired. Request a new one below.");
        } else if (res.status === 429) {
          setError("Too many attempts. Wait a moment and try again.");
        } else {
          setError(data.message || "Incorrect code. Try again.");
        }
      } else {
        const data = await res.json();
        try { localStorage.setItem("lvrd_session_token", data.token); } catch (e) { /* private browsing */ }
        onVerified(data);
      }
    } catch (err) {
      setError("Network error. Check your connection and try again.");
    } finally {
      setLoading(false);
    }
  }

  function handleDigit(i, value) {
    const d = value.replace(/\D/g, "").slice(-1);
    const next = digits.slice();
    next[i] = d;
    setDigits(next);
    setError(null);
    if (d && i < 5) {
      const el = inputsRef.current[i + 1];
      if (el) el.focus();
    }
    // Auto-submit when all 6 filled
    if (next.join("").length === 6 && next.indexOf("") === -1) {
      verify(next.join(""));
    }
  }

  function handleKeyDown(i, e) {
    if (e.key === "Backspace") {
      if (digits[i]) {
        const next = digits.slice();
        next[i] = "";
        setDigits(next);
        setError(null);
      } else if (i > 0) {
        const el = inputsRef.current[i - 1];
        if (el) el.focus();
      }
    }
  }

  function handlePaste(e) {
    const pasted = e.clipboardData.getData("text").replace(/\D/g, "").slice(0, 6);
    if (!pasted) return;
    e.preventDefault();
    const next = ["", "", "", "", "", ""];
    for (var j = 0; j < pasted.length; j++) next[j] = pasted[j];
    setDigits(next);
    setError(null);
    if (pasted.length < 6) {
      const el = inputsRef.current[pasted.length];
      if (el) el.focus();
    } else {
      verify(pasted);
    }
  }

  async function resend() {
    if (cooldown > 0 || resending) return;
    setResending(true);
    setError(null);
    try {
      const res = await fetch("https://app.lvrd.ai/api/auth/send-code", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ phone: phone }),
      });
      if (res.ok) {
        setCooldown(60);
        setDigits(["", "", "", "", "", ""]);
        setTimeout(function () {
          const el = inputsRef.current[0];
          if (el) el.focus();
        }, 50);
      } else {
        setError("Could not resend code. Please try again.");
      }
    } catch (err) {
      setError("Network error. Could not resend code.");
    } finally {
      setResending(false);
    }
  }

  var hasError = !!error;

  return (
    <div className="lv-auth">
      <div className="lv-statusbar-pad" />
      <div className="lv-auth-top">
        <button className="lv-backbtn lv-auth-back" onClick={onBack} aria-label="Back">
          <LvIcon name="back" size={18} />
        </button>
        <span className="lv-auth-wordmark">LVRD</span>
        <div style={{ width: 36 }} />
      </div>
      <div className="lv-auth-body">
        <div className="lv-auth-form">
          <div>
            <h1 className="lv-auth-title">Check your texts</h1>
            <p className="lv-auth-sub">{"We sent a 6-digit code to " + displayPhone + "."}</p>
          </div>
          <div className="lv-otp" onPaste={handlePaste}>
            {digits.map(function (d, i) {
              return (
                <input
                  key={i}
                  ref={function (el) { inputsRef.current[i] = el; }}
                  className={"lv-otp-box" + (hasError ? " error" : "")}
                  type="tel"
                  inputMode="numeric"
                  maxLength={1}
                  value={d}
                  onChange={function (e) { handleDigit(i, e.target.value); }}
                  onKeyDown={function (e) { handleKeyDown(i, e); }}
                  autoFocus={i === 0}
                  disabled={loading}
                  aria-label={"Digit " + (i + 1) + " of 6"}
                />
              );
            })}
          </div>
          {error ? <div className="lv-auth-error" role="alert" aria-live="polite">{error}</div> : null}
          {loading ? <div className="lv-auth-checking">Verifying…</div> : null}
          <div className="lv-auth-resend">
            {cooldown > 0 ? (
              <span>Resend code in <span className="count">{cooldown}s</span></span>
            ) : (
              <button className="lv-btn ghost" onClick={resend} disabled={resending}>
                {resending ? "Sending…" : "Resend code"}
              </button>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { PhoneEntry, CodeVerify });
