/* global React, Icon, Brand, Sparkline, SEED_NUDGES_FEED, AGENT_FEED, SIGNAL_DELTAS, DEAL_DIAGNOSIS, EvidenceQuote */

// ---------- ANALYTICS / REPORTING / INTERPRETATION ----------
const isClosedAnalyticsDeal = (deal) => /^closed/i.test(deal.stage || "") || /^closed/i.test(deal.statusLabel || "");
const isLostAnalyticsDeal = (deal) => /lost/i.test(`${deal.stage || ""} ${deal.statusLabel || ""} ${deal.status || ""}`);
const analyticsMoney = (value) => {
  if (value >= 1000000) return `$${(value / 1000000).toFixed(value % 1000000 === 0 ? 0 : 1)}M`;
  return `$${Math.round(value / 1000)}K`;
};

// Deterministic trend generator — converges to `current` over `weeks` points
// with mild noise, so the same input always renders the same sparkline.
const buildTrend = (current, weeks = 8, volatility = 0.18, drift = -0.12, seed = 1) => {
  const out = [];
  let v = current * (1 + drift);
  for (let i = 0; i < weeks; i++) {
    const t = i / (weeks - 1);
    const target = v + (current - v) * t;
    const noise = Math.sin(seed * (i + 1) * 1.7) * volatility * Math.max(1, Math.abs(current));
    out.push(Math.max(0, Math.round(target + noise)));
  }
  out[out.length - 1] = Math.round(current);
  return out;
};
const trendDelta = (series) => {
  if (!series || series.length < 2) return 0;
  return series[series.length - 1] - series[0];
};
const formatDelta = (delta, suffix = "") => {
  if (!delta) return `±0${suffix}`;
  const sign = delta > 0 ? "+" : "−";
  return `${sign}${Math.abs(delta)}${suffix}`;
};

// PipelineFunnel — clean column chart. One column per stage; bar height
// proportional to total $ moving through the stage (active + lost), with
// active stacked above lost so the eye sees both the volume *and* the
// drop-off in a single glance. No SVG, no motion — just HTML + CSS bars.
const PipelineFunnel = ({ stages, worstStageName, onSelectStage, selectedStage }) => {
  const [hoveredStage, setHoveredStage] = useState(null);
  const [keyboardFocused, setKeyboardFocused] = useState(false);

  // Arrow-key navigation when the funnel has keyboard focus. Wraps around.
  const cycle = (dir) => {
    const idx = stages.findIndex((s) => s.name === selectedStage);
    if (idx === -1) {
      onSelectStage(stages[0].name);
      return;
    }
    const next = (idx + dir + stages.length) % stages.length;
    onSelectStage(stages[next].name);
  };
  const onKeyDown = (e) => {
    if (e.key === "ArrowRight" || e.key === "ArrowDown") { e.preventDefault(); cycle(1); }
    else if (e.key === "ArrowLeft" || e.key === "ArrowUp") { e.preventDefault(); cycle(-1); }
    else if (e.key === "Escape" && selectedStage) { e.preventDefault(); onSelectStage(selectedStage); }
  };

  // Bar-height calculation — proportional to (active + lost) $ at the stage.
  const totals = stages.map((s) => (s.value || 0) + (s.lostValue || 0));
  const maxTotal = Math.max(1, ...totals);

  const fmt = (v) => analyticsMoney(v);

  return (
    <div
      className={`pipeline-funnel ${keyboardFocused ? "is-keyboard" : ""}`}
      role="group"
      aria-label="Pipeline funnel"
      tabIndex={0}
      data-tour="analytics-funnel"
      onKeyDown={onKeyDown}
      onFocus={() => setKeyboardFocused(true)}
      onBlur={() => setKeyboardFocused(false)}
      onMouseLeave={() => setHoveredStage(null)}
    >
      <div className="pipeline-chart-row">
        {stages.map((s, i) => {
          const total = totals[i];
          const heightPct = (total / maxTotal) * 100;
          const activeShare = total > 0 ? ((s.value || 0) / total) * 100 : 0;
          const lostShare = total > 0 ? ((s.lostValue || 0) / total) * 100 : 0;
          const isSelected = selectedStage === s.name;
          const isWorst = worstStageName === s.name && s.lostValue > 0;
          const isHovered = hoveredStage === s.name && !isSelected;
          return (
            <button
              key={s.name}
              type="button"
              className={`pipeline-col ${isSelected ? "is-selected" : ""} ${isWorst ? "is-worst" : ""} ${isHovered ? "is-hovered" : ""}`}
              onClick={() => onSelectStage(s.name)}
              onMouseEnter={() => setHoveredStage(s.name)}
              aria-pressed={isSelected}
              aria-label={`${s.name}: ${s.count} active deals (${fmt(s.value)}), ${s.lostCount} closed lost (${fmt(s.lostValue)})`}
              data-tour={isWorst || (!worstStageName && i === 0) ? "analytics-stage-focus" : undefined}
            >
              <span className="pipeline-col-head">
                <span className="pipeline-col-count">
                  <b>{s.count}</b>
                  <em>{s.count === 1 ? "deal" : "deals"}</em>
                </span>
                <span className="pipeline-col-money">{fmt(s.value)}</span>
              </span>

              <span className="pipeline-col-bar-wrap" aria-hidden="true">
                <span className="pipeline-col-bar" style={{ height: `${Math.max(6, heightPct)}%` }}>
                  {s.value > 0 && (
                    <span className="pipeline-col-bar-active" style={{ height: `${activeShare}%` }} />
                  )}
                  {s.lostValue > 0 && (
                    <span className="pipeline-col-bar-lost" style={{ height: `${lostShare}%` }} />
                  )}
                </span>
              </span>

              <span className="pipeline-col-name">{s.name}</span>

              {s.lostCount > 0 ? (
                <span className="pipeline-col-lost">
                  <span className="pipeline-col-lost-dot" aria-hidden="true" />
                  <b>{s.lostCount}</b>
                  <em>lost · {fmt(s.lostValue)}</em>
                </span>
              ) : (
                <span className="pipeline-col-lost is-empty">no losses</span>
              )}
            </button>
          );
        })}
      </div>

      <div className="pipeline-funnel-legend">
        <span className="pipeline-funnel-key">
          <span className="dot dot-active" aria-hidden="true" /> Active pipeline
        </span>
        <span className="pipeline-funnel-key">
          <span className="dot dot-loss" aria-hidden="true" /> Closed lost
        </span>
        <span className="pipeline-funnel-hint">
          Click any stage to inspect the deals · use <kbd>←</kbd> <kbd>→</kbd> to step through.
        </span>
      </div>
    </div>
  );
};

// StageDrawer — opens beneath the funnel when a stage is selected. Re-uses
// the Home-page "Top priority deals" expanded card pattern: a priority-split
// with a left rail of the stage's deals (active + lost, filterable) and a
// priority-detail card on the right for the focused deal.
const StageDrawer = ({ stage, onClose, openDeal }) => {
  // Default to the Lost tab — the funnel is built around "where do we lose
  // buyers", so the most useful view when opening a stage is the closed-lost
  // pattern. Falls back to All if the stage has no losses.
  const [filter, setFilter] = useState(stage.lostCount > 0 ? "lost" : "all");
  const allDeals = useMemo(
    () => [
      ...stage.deals.map((d) => ({ ...d, _bucket: "active" })),
      ...stage.lostDeals.map((d) => ({ ...d, _bucket: "lost" })),
    ],
    [stage]
  );
  const filteredDeals = useMemo(
    () => allDeals.filter((d) => filter === "all" || d._bucket === filter),
    [allDeals, filter]
  );
  const [selectedDealId, setSelectedDealId] = useState(filteredDeals[0]?.id || null);

  // Keep the focused deal in sync with the active filter — if it dropped out
  // of view (e.g. user switched to Lost while looking at an active deal),
  // re-pick the first deal in the filtered list.
  useEffect(() => {
    if (!filteredDeals.some((d) => d.id === selectedDealId)) {
      setSelectedDealId(filteredDeals[0]?.id || null);
    }
  }, [filter, stage, filteredDeals, selectedDealId]);

  const activeDeal = filteredDeals.find((d) => d.id === selectedDealId) || filteredDeals[0];
  const activeDiag = activeDeal ? (DEAL_DIAGNOSIS[activeDeal.id] || {}) : {};
  const isLost = activeDeal?._bucket === "lost";
  const activeTone = isLost
    ? "warn"
    : activeDeal?.status === "at-risk"
      ? "warn"
      : activeDeal?.status === "needs-attention"
        ? "amber"
        : "good";
  const activeValue = activeDeal ? (activeDeal.arr || analyticsMoney(activeDeal.value)) : "";

  return (
    <div className="stage-drawer cp-priority-shell" role="dialog" aria-label={`${stage.name} stage`} data-tour="analytics-stage-drawer">
      <header className="cp-priority-shell-head stage-drawer-head">
        <div className="cp-feed-headings">
          <span className="cp-eyebrow">
            <span className="cp-eyebrow-dot accent" aria-hidden="true" />
            Stage focus · {stage.name}
          </span>
          <h2 className="cp-feed-title">{stage.name}</h2>
          <p className="cp-feed-helper">
            {stage.count} active · {stage.lostCount} lost · {analyticsMoney(stage.value)} moving · {analyticsMoney(stage.lostValue)} written off
          </p>
        </div>
        <button
          type="button"
          className="stage-drawer-close"
          onClick={onClose}
          aria-label="Close stage details"
          title="Close"
        >
          <Icon name="close" size={12} />
        </button>
      </header>

      <div className="priority-split stage-drawer-split">
        <div className="priority-stack stage-drawer-stack" role="listbox" aria-label={`${stage.name} deals`}>
          <div className="stage-drawer-filter" role="tablist">
            {[
              { id: "all",    label: "All",    count: allDeals.length },
              { id: "active", label: "Active", count: stage.count },
              { id: "lost",   label: "Lost",   count: stage.lostCount },
            ].map((opt) => (
              <button
                key={opt.id}
                type="button"
                role="tab"
                aria-selected={filter === opt.id}
                className={`stage-drawer-filter-btn ${filter === opt.id ? "is-active" : ""} ${opt.id === "lost" ? "is-loss" : ""}`}
                onClick={() => setFilter(opt.id)}
              >
                <span>{opt.label}</span>
                <em>{opt.count}</em>
              </button>
            ))}
          </div>
          {filteredDeals.length === 0 ? (
            <div className="stage-drawer-empty">No deals in this view.</div>
          ) : (
            filteredDeals.map((d) => {
              const tone = d._bucket === "lost"
                ? "warn"
                : d.status === "at-risk"
                  ? "warn"
                  : d.status === "needs-attention"
                    ? "amber"
                    : "good";
              const selected = d.id === (activeDeal && activeDeal.id);
              return (
                <button
                  key={d.id}
                  type="button"
                  role="option"
                  aria-selected={selected}
                  className={`priority-stack-card tone-${tone} ${selected ? "is-selected" : ""} ${d._bucket === "lost" ? "is-lost" : ""}`}
                  onClick={() => setSelectedDealId(d.id)}
                >
                  <span className={`priority-stack-sev tone-${tone}`} aria-hidden="true" />
                  <span className="priority-stack-main">
                    <span className="priority-stack-name">{d.company}</span>
                    <span className="priority-stack-meta">
                      {d._bucket === "lost" ? `Closed lost · ${d.closeDate}` : (d.statusLabel || d.dealName)}
                    </span>
                  </span>
                  <span className="priority-stack-side">
                    <span className="priority-stack-value">{analyticsMoney(d.value)}</span>
                  </span>
                </button>
              );
            })
          )}
        </div>

        {activeDeal && (
          <article key={activeDeal.id} className={`priority-detail tone-${activeTone} stage-drawer-detail`}>
            <header className="priority-detail-head">
              <div className="priority-detail-title">
                <span className="priority-detail-kicker">
                  {isLost ? "Closed lost · review" : "Selected deal"}
                </span>
                <h3>{activeDeal.company}</h3>
                <p>{activeDeal.stage === "Closed Lost" ? `Lost at ${activeDeal.lostAtStage || stage.name}` : activeDeal.stage} · {activeDeal.closeDate} · {activeValue}</p>
              </div>
              <div className="priority-detail-actions">
                <button
                  type="button"
                  className="priority-detail-room"
                  onClick={() => openDeal(activeDeal.id, "overview")}
                  aria-label={`Open ${activeDeal.company} deal room`}
                >
                  <span>Deal room</span>
                  <Icon name="expand" size={10} />
                </button>
              </div>
            </header>

            <div className="priority-detail-body">
              <section className="priority-detail-block priority-detail-diagnosis">
                <span className="coach-mini-label">{isLost ? "Why we lost it" : "Why this matters"}</span>
                <h4>{activeDiag.headline || activeDeal.statusLabel || activeDeal.dealName}</h4>
                <p>{activeDiag.why || activeDeal.summary}</p>
              </section>

              {activeDiag.what && (
                <section className="priority-detail-block">
                  <span className="coach-mini-label">Signal</span>
                  <p>{activeDiag.what}</p>
                </section>
              )}

              {activeDiag.symptoms && activeDiag.symptoms.length > 0 && (
                <section className="priority-detail-block">
                  <span className="coach-mini-label">{isLost ? "Loss pattern" : "Proof points"}</span>
                  <div className="coach-chips">
                    {activeDiag.symptoms.map((s, i) => (
                      <span key={i} className={`coach-chip tone-${s.tone || "good"}`}>{s.label}</span>
                    ))}
                  </div>
                </section>
              )}

              {!isLost && activeDiag.fix && (
                <button
                  type="button"
                  className="coach-cta priority-detail-cta"
                  onClick={() => openDeal(activeDeal.id, "overview")}
                >
                  <span className="coach-cta-text">{activeDiag.fix}</span>
                  {activeDiag.draft && (
                    <span className="coach-cta-chip">{activeDiag.draft.channel || "Email"} · {activeDiag.draft.to}</span>
                  )}
                  <span className="coach-cta-track" aria-hidden="true">
                    <span className="coach-cta-dot" />
                    <span className="coach-cta-dot" />
                    <span className="coach-cta-dot" />
                    <Icon name="arrow" size={14} className="coach-cta-arrow" />
                  </span>
                </button>
              )}
              {isLost && (
                <button
                  type="button"
                  className="coach-cta priority-detail-cta"
                  onClick={() => openDeal(activeDeal.id, "overview")}
                >
                  <span className="coach-cta-text">Open loss review</span>
                  <span className="coach-cta-chip">Log pattern · update playbook</span>
                  <span className="coach-cta-track" aria-hidden="true">
                    <span className="coach-cta-dot" />
                    <span className="coach-cta-dot" />
                    <span className="coach-cta-dot" />
                    <Icon name="arrow" size={14} className="coach-cta-arrow" />
                  </span>
                </button>
              )}
            </div>
          </article>
        )}
      </div>
    </div>
  );
};

// WonLossAnalysis — coaching tool. Default surface = aggregate patterns
// (clustered closed-won/closed-lost deals around a theme), each with a
// coaching prescription ("pattern to repeat" / "pattern to avoid").
// Drilling into a pattern reveals the matching deals + their individual
// diagnosis (same priority-detail card pattern as Top Priority Deals).
//
// Rules cluster deals by keyword match across the deal's summary +
// DEAL_DIAGNOSIS.what / .why. New patterns can be added by appending to
// LOSS_PATTERNS / WIN_PATTERNS.
const LOSS_PATTERNS = [
  {
    id: "finance-missing",
    label: "Finance / EB never engaged",
    summary: "Champion was active but the economic buyer (CFO / finance) stayed outside the process. ROI was never validated.",
    avoid: "Make 'EB identified + ROI reviewed' a qualification exit criterion. Don't let proposal land without finance in the thread.",
    keywords: /\b(finance|cfo|economic buyer|roi|budget approval|finance sponsor)\b/i,
  },
  {
    id: "procurement-incumbent",
    label: "Procurement freeze / incumbent counter",
    summary: "Lost in procurement: a freeze, a counter-quote from an incumbent, or an internal alternative blocked the switch.",
    avoid: "Build the cost-of-staying case in discovery. Surface incumbent + procurement risk before pricing — never after.",
    keywords: /\b(procurement|incumbent|counter-quote|counter quote|matched price|internal alternative|freeze)\b/i,
  },
  {
    id: "champion-drift",
    label: "Champion left or went silent",
    summary: "Champion changed jobs, lost interest, or couldn't carry the deal. Backup champion was never built.",
    avoid: "Map a second champion in every deal by qualification. Run a champion-health check at each stage transition.",
    keywords: /\b(champion (left|drifted|silent|couldn|disengaged)|backup (never|wasn)|champion changed|champion went)\b/i,
  },
  {
    id: "discovery-thin",
    label: "Discovery never landed",
    summary: "Discovery didn't surface a problem worth solving. Buyer chose to do nothing, go internal, or run a workaround.",
    avoid: "Tighten discovery: a quantified pain + a named owner + a deadline before qualification. No exception.",
    keywords: /\b(discovery|never converted|no problem|scoping|pulled before|nothing to solve)\b/i,
  },
  {
    id: "legal-redlines",
    label: "Legal / redline pushback",
    summary: "Deal stalled in redlines (indemnification, security, compliance) past the buyer's go-live or close window.",
    avoid: "Pre-share MSA + security pack at proposal. Schedule legal kickoff in parallel — don't wait for buyer signature to start.",
    keywords: /\b(legal|redline|indemnification|security review|compliance|past the buyer|stalled in redlines)\b/i,
  },
  {
    id: "price-pushback",
    label: "Pricing pushback we couldn't meet",
    summary: "Buyer asked for a discount the deal couldn't bear, or pricing landed without enough business-case backing.",
    avoid: "Build the value model before sending the price. Anchor on cost-of-staying, not list price.",
    keywords: /\b(50% cut|discount|price.*cut|pricing.*pushback|asked for.*cut)\b/i,
  },
];

const WIN_PATTERNS = [
  {
    id: "exec-aligned-early",
    label: "Exec aligned before proposal",
    summary: "Champion brought CFO / CRO / exec sponsor into pricing or solution alignment ahead of proposal — no late-stage surprise.",
    repeat: "Make 'CFO comfortable with ramp' the proposal exit criterion. Pricing waits until exec is in the thread.",
    keywords: /\b(cfo.*aligned|cro|exec.*aligned|economic buyer (joined|aligned)|buyer-led|exec sponsor)\b/i,
  },
  {
    id: "buyer-owned-plan",
    label: "Buyer owned the close plan",
    summary: "Champion drove the mutual action plan and procurement timeline. Seller stayed in support — never had to push.",
    repeat: "Co-author a written mutual plan by proposal. Re-route ownership to the champion any time the calendar slips.",
    keywords: /\b(mutual.*plan|champion.*drove|champion.*close plan|buyer-led close|brought.*pricing)\b/i,
  },
];

function buildPatternMatches(deals, rules) {
  return rules.map((rule) => {
    const matching = deals.filter((d) => {
      const diag = DEAL_DIAGNOSIS[d.id] || {};
      const text = [d.summary, d.statusLabel, diag.headline, diag.why, diag.what]
        .filter(Boolean).join(" \n ");
      return rule.keywords.test(text);
    });
    const value = matching.reduce((s, d) => s + (d.value || 0), 0);
    return { ...rule, deals: matching, count: matching.length, value };
  })
  .filter((p) => p.count > 0)
  .sort((a, b) => b.value - a.value);
}

const WonLossAnalysis = ({ deals, openDeal, cardClass = "", cardDragProps = {}, onRemove }) => {
  const [tab, setTab] = useState("loss");          // "loss" | "win"
  const [selectedPatternId, setSelectedPatternId] = useState(null);
  const [drillDealId, setDrillDealId] = useState(null);
  // Pattern breakdown is folded by default. The root-why panel is the
  // landing read; the manager / AE expands the detail when they want to
  // drill into the patterns + deals beneath.
  const [detailsOpen, setDetailsOpen] = useState(false);

  const closedDeals = useMemo(() => deals.filter((d) => isClosedAnalyticsDeal(d)), [deals]);
  const wonDeals = useMemo(() => closedDeals.filter((d) => !isLostAnalyticsDeal(d)), [closedDeals]);
  const lostDeals = useMemo(() => closedDeals.filter((d) => isLostAnalyticsDeal(d)), [closedDeals]);

  const lossPatterns = useMemo(() => buildPatternMatches(lostDeals, LOSS_PATTERNS), [lostDeals]);
  const winPatterns = useMemo(() => buildPatternMatches(wonDeals, WIN_PATTERNS), [wonDeals]);

  const patterns = tab === "loss" ? lossPatterns : winPatterns;
  const headline = tab === "loss" ? lostDeals : wonDeals;
  const tabIsLoss = tab === "loss";

  // Auto-select the top pattern when the tab changes (or first load).
  useEffect(() => {
    if (!patterns.length) {
      setSelectedPatternId(null);
      setDrillDealId(null);
      return;
    }
    if (!patterns.some((p) => p.id === selectedPatternId)) {
      setSelectedPatternId(patterns[0].id);
      setDrillDealId(null);
    }
  }, [patterns, selectedPatternId]);

  const selectedPattern = patterns.find((p) => p.id === selectedPatternId) || patterns[0] || null;
  // When a pattern is selected, default-focus the largest deal in it.
  const orderedDeals = useMemo(() => {
    if (!selectedPattern) return [];
    return [...selectedPattern.deals].sort((a, b) => (b.value || 0) - (a.value || 0));
  }, [selectedPattern]);
  const focusedDeal = drillDealId
    ? orderedDeals.find((d) => d.id === drillDealId)
    : orderedDeals[0];
  const focusedDiag = focusedDeal ? (DEAL_DIAGNOSIS[focusedDeal.id] || {}) : {};
  const focusedValue = focusedDeal ? (focusedDeal.arr || analyticsMoney(focusedDeal.value)) : "";

  const totalCount = lostDeals.length + wonDeals.length;
  const winRateCount = totalCount ? Math.round((wonDeals.length / totalCount) * 100) : 0;
  const wonValueAll = wonDeals.reduce((s, d) => s + (d.value || 0), 0);
  const lostValueAll = lostDeals.reduce((s, d) => s + (d.value || 0), 0);

  if (closedDeals.length === 0) {
    return (
      <section className={`cp-priority-shell cp-priority-shell-empty ${cardClass}`} aria-label="Won/Loss patterns">
        <header className="cp-priority-shell-head" {...cardDragProps}>
          <div className="cp-feed-headings">
            <div className="cp-feed-affordance">
              <span className="cp-drag-handle" aria-hidden="true"><Icon name="grip" size={12} /></span>
            </div>
            <h2 className="cp-feed-title">Won/Loss patterns</h2>
            <p className="cp-feed-helper">No closed deals yet — patterns will appear as deals close.</p>
          </div>
          {onRemove && (
            <button type="button" className="cp-slot-remove" onClick={(e) => { e.stopPropagation(); onRemove(); }} aria-label="Remove section" title="Remove section">
              <Icon name="close" size={11} />
            </button>
          )}
        </header>
      </section>
    );
  }

  const focusedTone = tabIsLoss ? "warn" : "good";

  return (
    <section
      className={`cp-priority-shell cp-priority-shell-active tone-${focusedTone} won-loss-shell ${cardClass}`}
      aria-label="Won/Loss patterns"
      data-tour="analytics-won-loss"
    >
      <header className="cp-priority-shell-head" {...cardDragProps}>
        <div className="cp-feed-headings">
          <div className="cp-feed-affordance">
            <span className="cp-drag-handle" aria-hidden="true"><Icon name="grip" size={12} /></span>
          </div>
          <h2 className="cp-feed-title">Won/Loss patterns</h2>
          <p className="cp-feed-helper">
            Coaching layer for closed deals — <b>{wonDeals.length}</b> won · <b>{lostDeals.length}</b> lost · <b>{winRateCount}%</b> win rate · {analyticsMoney(wonValueAll)} won, {analyticsMoney(lostValueAll)} lost. Pick a pattern, drill into the deals.
          </p>
        </div>
        {onRemove && (
          <button type="button" className="cp-slot-remove" onClick={(e) => { e.stopPropagation(); onRemove(); }} aria-label="Remove section" title="Remove section">
            <Icon name="close" size={11} />
          </button>
        )}
      </header>

      <div className="wl-tabs" role="tablist" aria-label="Pattern view">
        <button
          type="button"
          role="tab"
          aria-selected={tab === "loss"}
          className={`wl-tab ${tab === "loss" ? "is-active is-loss" : ""}`}
          onClick={() => setTab("loss")}
        >
          <span className="wl-tab-dot wl-tab-dot-loss" aria-hidden="true" />
          Loss patterns
          <em>{lossPatterns.length}</em>
        </button>
        <button
          type="button"
          role="tab"
          aria-selected={tab === "win"}
          className={`wl-tab ${tab === "win" ? "is-active is-win" : ""}`}
          onClick={() => setTab("win")}
        >
          <span className="wl-tab-dot wl-tab-dot-win" aria-hidden="true" />
          Win patterns
          <em>{winPatterns.length}</em>
        </button>
      </div>

      {/* ── Root why · global analysis ─────────────────────────────────
          The first thing the manager reads when they land here. Synthesises
          the dominant theme across the current tab's closed deals into one
          coaching read. Patterns + drill-down below let them dig deeper. */}
      {(() => {
        const tabTotalValue = tabIsLoss ? lostValueAll : wonValueAll;
        const tabTotalCount = tabIsLoss ? lostDeals.length : wonDeals.length;
        const topPattern = patterns[0];
        const topShare = topPattern && tabTotalValue > 0
          ? Math.round((topPattern.value / tabTotalValue) * 100)
          : 0;
        const verb = tabIsLoss ? "losing" : "winning";
        const closedLabel = tabIsLoss ? "closed lost" : "closed won";
        let rootHeadline;
        let rootBody;
        const moneyTone = tabIsLoss ? "loss" : "money";
        if (tabTotalCount === 0) {
          rootHeadline = tabIsLoss
            ? "No losses this quarter"
            : "No wins this quarter";
          rootBody = <>Closed-deal data will populate once pipeline starts settling.</>;
        } else if (!topPattern) {
          rootHeadline = tabIsLoss
            ? "Losses spread across reasons"
            : "Wins spread across reasons";
          rootBody = (
            <>
              <span className={`kw tone-${moneyTone}`}>{analyticsMoney(tabTotalValue)}</span> across{" "}
              <span className="kw tone-num">{tabTotalCount}</span> {tabTotalCount === 1 ? "deal" : "deals"}{" "}
              <span className="kw tone-muted">{closedLabel}</span> — no single pattern dominates yet. Themes will sharpen as more deals close.
            </>
          );
        } else {
          rootHeadline = tabIsLoss
            ? `Most loss dollars trace to ${topPattern.label}`
            : `Most won dollars share ${topPattern.label}`;
          rootBody = (
            <>
              <span className="kw tone-num">{topShare}%</span> of this quarter's{" "}
              <span className={`kw tone-${moneyTone}`}>{analyticsMoney(tabTotalValue)}</span> in{" "}
              <span className="kw tone-muted">{closedLabel}</span> dollars share one root {tabIsLoss ? "cause" : "pattern"}:{" "}
              <span className="kw tone-key">{topPattern.label.toLowerCase()}</span>. {tabIsLoss ? topPattern.avoid : topPattern.repeat}
            </>
          );
        }
        return (
          <section className={`wl-root-why tone-${focusedTone}`} aria-label={`Why we're ${verb}`}>
            <div className="wl-root-why-kicker">
              <span className="wl-root-why-dot" aria-hidden="true" />
              {tabIsLoss ? "Why we're losing" : "Why we're winning"}
              <em>· this quarter</em>
            </div>
            <h3 className="wl-root-why-headline">{rootHeadline}</h3>
            <p className="wl-root-why-body">{rootBody}</p>
            <div className="wl-root-why-meta">
              <span>
                <b>{analyticsMoney(tabTotalValue)}</b> <em>·</em> {tabTotalCount} {tabTotalCount === 1 ? "deal" : "deals"} {closedLabel}
              </span>
              {topPattern && (
                <span>
                  Top pattern <b>{topShare}%</b> <em>· {topPattern.count} {topPattern.count === 1 ? "deal" : "deals"} · {analyticsMoney(topPattern.value)}</em>
                </span>
              )}
              {patterns.length > 1 && (
                <button
                  type="button"
                  className="wl-root-why-jump"
                  onClick={() => {
                    setSelectedPatternId(topPattern.id);
                    setDetailsOpen(true);
                  }}
                  aria-label={`Drill into ${topPattern.label}`}
                >
                  Drill in <Icon name="arrow" size={11} />
                </button>
              )}
            </div>
          </section>
        );
      })()}

      {patterns.length > 0 && (
        <button
          type="button"
          className={`wl-details-toggle ${detailsOpen ? "is-open" : ""}`}
          onClick={() => setDetailsOpen((open) => !open)}
          aria-expanded={detailsOpen}
        >
          {detailsOpen ? (
            <>
              <span>Hide pattern breakdown</span>
              <Icon name="chevron" size={11} className="is-flipped" />
            </>
          ) : (
            <>
              <span>Show pattern breakdown</span>
              <em>· {patterns.length} {patterns.length === 1 ? "pattern" : "patterns"}</em>
              <Icon name="chevron" size={11} />
            </>
          )}
        </button>
      )}

      {detailsOpen && patterns.length > 0 && (
        <div className="priority-split wl-split">
          {/* Left rail — list of patterns. */}
          <div className="priority-stack wl-pattern-stack" role="listbox" aria-label="Patterns">
            {patterns.map((p) => {
              const isSel = selectedPattern && p.id === selectedPattern.id;
              return (
                <button
                  key={p.id}
                  type="button"
                  role="option"
                  aria-selected={isSel}
                  className={`wl-pattern-card tone-${focusedTone} ${isSel ? "is-selected" : ""}`}
                  onClick={() => { setSelectedPatternId(p.id); setDrillDealId(null); }}
                >
                  <span className={`wl-pattern-stripe tone-${focusedTone}`} aria-hidden="true" />
                  <span className="wl-pattern-body">
                    <span className="wl-pattern-label">{p.label}</span>
                    <span className="wl-pattern-stats">
                      <b>{p.count}</b>
                      <em>{p.count === 1 ? "deal" : "deals"} · {analyticsMoney(p.value)}</em>
                    </span>
                  </span>
                </button>
              );
            })}
          </div>

          {/* Right — selected pattern detail (coaching) + drill-down deal. */}
          {selectedPattern && (
            <article key={selectedPattern.id} className={`priority-detail tone-${focusedTone} wl-pattern-detail`}>
              <header className="priority-detail-head">
                <div className="priority-detail-title">
                  <span className="priority-detail-kicker">
                    {tabIsLoss ? "Loss pattern · coaching" : "Win pattern · coaching"}
                  </span>
                  <h3>{selectedPattern.label}</h3>
                  <p>
                    {selectedPattern.count} {selectedPattern.count === 1 ? "deal" : "deals"} · {analyticsMoney(selectedPattern.value)} {tabIsLoss ? "written off" : "closed-won"} this period
                  </p>
                </div>
              </header>

              <div className="priority-detail-body">
                <section className="priority-detail-block priority-detail-diagnosis">
                  <span className="coach-mini-label">What's happening</span>
                  <p>{selectedPattern.summary}</p>
                </section>

                <section className="priority-detail-block wl-prescription">
                  <span className="coach-mini-label">{tabIsLoss ? "Pattern to avoid · coaching cue" : "Pattern to repeat · coaching cue"}</span>
                  <p>{tabIsLoss ? selectedPattern.avoid : selectedPattern.repeat}</p>
                </section>

                {/* Drill-down: deals matching this pattern. */}
                <section className="priority-detail-block wl-deals-block">
                  <div className="wl-deals-header">
                    <span className="coach-mini-label">Deals matching this pattern</span>
                    {focusedDeal && (
                      <button
                        type="button"
                        className="priority-detail-room"
                        onClick={() => openDeal(focusedDeal.id, "overview")}
                        aria-label={`Open ${focusedDeal.company} deal room`}
                      >
                        <span>Open {focusedDeal.company}</span>
                        <Icon name="expand" size={10} />
                      </button>
                    )}
                  </div>
                  <div className="wl-deals">
                    {orderedDeals.map((d) => {
                      const isFocused = focusedDeal && d.id === focusedDeal.id;
                      const stageLine = tabIsLoss && d.lostAtStage ? `Lost at ${d.lostAtStage}` : d.stage;
                      return (
                        <button
                          key={d.id}
                          type="button"
                          className={`wl-deal-row tone-${focusedTone} ${isFocused ? "is-focused" : ""}`}
                          onClick={() => setDrillDealId(d.id)}
                        >
                          <span className="wl-deal-row-main">
                            <b>{d.company}</b>
                            <em>{stageLine} · {d.closeDate}</em>
                          </span>
                          <span className="wl-deal-row-value">{analyticsMoney(d.value)}</span>
                        </button>
                      );
                    })}
                  </div>
                </section>

                {/* Focused deal — its specific why (so the coach can speak to a concrete example). */}
                {focusedDeal && (
                  <section className="priority-detail-block wl-focus">
                    <span className="coach-mini-label">{tabIsLoss ? "Why we lost" : "Why we won"} · {focusedDeal.company}</span>
                    <h4>{focusedDiag.headline || (tabIsLoss ? "Closed lost" : "Closed won")}</h4>
                    <p>{focusedDiag.why || focusedDeal.summary}</p>
                    {focusedDiag.symptoms && focusedDiag.symptoms.length > 0 && (
                      <div className="coach-chips" style={{ marginTop: 8 }}>
                        {focusedDiag.symptoms.map((s, i) => (
                          <span key={i} className={`coach-chip tone-${s.tone || focusedTone}`}>{s.label}</span>
                        ))}
                      </div>
                    )}
                  </section>
                )}

                <button
                  type="button"
                  className="coach-cta priority-detail-cta"
                  onClick={() => {
                    if (typeof window.previewAction !== "function") return;
                    window.previewAction({
                      kicker: tabIsLoss ? "Loss-pattern coaching" : "Win-pattern coaching",
                      title: tabIsLoss
                        ? `Coach the team on: ${selectedPattern.label}`
                        : `Replicate: ${selectedPattern.label}`,
                      meta: [
                        { label: "PATTERN", value: selectedPattern.label },
                        { label: "DEALS", value: `${selectedPattern.count} · ${analyticsMoney(selectedPattern.value)}` },
                        { label: "PERIOD", value: "This quarter" },
                      ],
                      body: {
                        label: tabIsLoss ? "Pattern to avoid" : "Pattern to repeat",
                        text: tabIsLoss ? selectedPattern.avoid : selectedPattern.repeat,
                      },
                      evidence: orderedDeals.slice(0, 4).map((d) => ({
                        label: d.company,
                        value: `${tabIsLoss && d.lostAtStage ? `Lost at ${d.lostAtStage}` : d.stage} · ${analyticsMoney(d.value)} · ${d.summary || ""}`.replace(/ · $/, ""),
                      })),
                      primaryLabel: tabIsLoss ? "Brief the team" : "Update playbook",
                      onConfirm: () => {
                        if (typeof window.fireToast === "function") {
                          window.fireToast(`✓ ${tabIsLoss ? "Coaching brief" : "Playbook update"} queued · ${selectedPattern.label}`);
                        }
                      },
                    });
                  }}
                >
                  <span className="coach-cta-text">
                    {tabIsLoss ? "Brief the team on this pattern" : "Replicate this pattern across pipeline"}
                  </span>
                  <span className="coach-cta-chip">
                    {selectedPattern.count} {selectedPattern.count === 1 ? "deal" : "deals"} · {analyticsMoney(selectedPattern.value)}
                  </span>
                  <span className="coach-cta-track" aria-hidden="true">
                    <span className="coach-cta-dot" />
                    <span className="coach-cta-dot" />
                    <span className="coach-cta-dot" />
                    <Icon name="arrow" size={14} className="coach-cta-arrow" />
                  </span>
                </button>
              </div>
            </article>
          )}
        </div>
      )}
    </section>
  );
};

// PipelineBriefing — the funnel section ("Letter from Addy"). Reusable in
// both the AE Analytics screen and the Manager's Model section. Computes
// the stage breakdown (active deals per stage + closed-lost deals
// attributed to the stage they slipped at) and renders the funnel + drawer.
const PipelineBriefing = ({ deals, openDeal, lens = "ae", headingEyebrow, showHeader = true }) => {
  const [selectedStage, setSelectedStage] = useState(null);
  const isManagerLens = lens === "manager";
  const eyebrow = headingEyebrow || `Letter from Addy · ${isManagerLens ? "manager lens" : "AE lens"}`;
  const lensTitleSubject = isManagerLens ? "Team" : "Your";
  const lensBuyers = isManagerLens ? "team buyers" : "your buyers";
  const lensClosedLost = isManagerLens ? "the team's closed-lost dollars" : "your closed-lost dollars";

  const stageReport = useMemo(() => {
    const open = deals.filter((deal) => !isClosedAnalyticsDeal(deal));
    const closedLost = deals.filter((deal) => isClosedAnalyticsDeal(deal) && isLostAnalyticsDeal(deal));
    const stageOrder = ["Discovery", "Qualification", "Proposal", "Negotiation"];
    const byStage = stageOrder.map((stageName) => {
      const stageDeals = open.filter((deal) => (deal.stage || "").toLowerCase() === stageName.toLowerCase());
      const lostDeals = closedLost.filter((deal) => (deal.lostAtStage || "").toLowerCase() === stageName.toLowerCase());
      const stageValue = stageDeals.reduce((sum, d) => sum + (d.value || 0), 0);
      const lostValue = lostDeals.reduce((sum, d) => sum + (d.value || 0), 0);
      return {
        name: stageName,
        count: stageDeals.length,
        value: stageValue,
        deals: stageDeals,
        lostDeals,
        lostCount: lostDeals.length,
        lostValue,
      };
    });
    const worstLossStage = [...byStage].sort((a, b) => b.lostValue - a.lostValue)[0];
    return { byStage, worstLossStage };
  }, [deals]);

  const worstStage = stageReport.worstLossStage;
  const hasConcentratedLoss = worstStage && worstStage.lostValue > 0;

  return (
    <div className="pipeline-briefing">
      {showHeader && (
        <header className="briefing-head">
          <span className="cp-eyebrow">
            <span className={`cp-eyebrow-dot ${hasConcentratedLoss ? "warn" : "good"}`} aria-hidden="true" />
            {eyebrow}
          </span>
          <h1 className="briefing-title">
            {hasConcentratedLoss
              ? `${lensTitleSubject} buyer drop-off is concentrated at ${worstStage.name}`
              : `Where ${lensBuyers} drop off`}
          </h1>
          <p className="briefing-sub">
            {hasConcentratedLoss
              ? `${analyticsMoney(worstStage.lostValue)} of ${lensClosedLost} stalled at this stage. Click a stage to inspect the deals.`
              : `Click any stage to inspect the deals moving through it and the ones ${isManagerLens ? "the team" : "you"} lost there.`}
          </p>
        </header>
      )}

      <section className="briefing-block">
        <PipelineFunnel
          stages={stageReport.byStage}
          worstStageName={worstStage ? worstStage.name : null}
          onSelectStage={(name) => setSelectedStage((cur) => (cur === name ? null : name))}
          selectedStage={selectedStage}
        />
        {selectedStage && (
          <StageDrawer
            key={selectedStage}
            stage={stageReport.byStage.find((s) => s.name === selectedStage)}
            onClose={() => setSelectedStage(null)}
            openDeal={openDeal}
          />
        )}
      </section>

      <section className="briefing-block">
        <WonLossAnalysis deals={deals} openDeal={openDeal} />
      </section>
    </div>
  );
};

const AnalyticsScreen = ({ deals, openDeal, showPageHeader = true }) => {
  const today = new Date().toLocaleString("en-US", {
    month: "short",
    day: "numeric",
    year: "numeric",
  });

  return (
    <div className="scroll briefing-screen" data-screen-label="03 Addy briefing" data-tour="analytics-page">
      {showPageHeader && (
        <div className="topbar">
          <Brand />
          <div className="muted mono" style={{ fontSize: 11 }}>Addy briefing · {today}</div>
        </div>
      )}
      <PipelineBriefing deals={deals} openDeal={openDeal} showHeader={showPageHeader} />
    </div>
  );
};

// ---------- ALERTS / NUDGES FEED ----------
function AlertsScreen({ deals = [], openDeal, showPageHeader = true }) {
  return (
    <div className="scroll" data-screen-label="04 Alerts" data-tour="alerts-page">
      {showPageHeader && (
        <>
          <div className="topbar">
            <Brand />
          </div>
          <header className="platform-page-header">
            <div className="platform-page-copy">
              <span className="platform-eyebrow">
                <span className="cp-eyebrow-dot amber" aria-hidden />
                Addy queue
              </span>
              <h1 className="platform-page-title">Nudges</h1>
              <p className="platform-page-subtitle">Team Addy — Scout, Drafter, and Forecaster — surface actions ranked by deal risk and decay. Click any agent chip for the receipt.</p>
            </div>
            <div className="platform-page-meta">
              <span><b>5</b> active nudges</span>
            </div>
          </header>
        </>
      )}

      <div style={{ display: "flex", flexDirection: "column", maxWidth: 880 }}>
        {SEED_NUDGES_FEED.map((n) => {
          const deal = deals.find((d) => d.id === n.dealId);
          return (
            <div
              key={n.id}
              className={`flow-row ${n.severity}`}
              style={{ gridTemplateColumns: "4px 1fr auto auto", padding: "16px 0", gap: 14 }}
              data-tour={n.id === SEED_NUDGES_FEED[0]?.id ? "alerts-first" : undefined}
            >
              <div className="marker" />
              <div className="body" style={{ minWidth: 0 }}>
                <div style={{ display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" }}>
                  <AgentChip nudge={n} deal={deal} />
                  <span className="eyebrow">{n.deal}</span>
                  <span className="mono sub" style={{ fontSize: 10 }}>· {n.time}</span>
                </div>
                <div className="t" style={{ marginTop: 4 }}>{n.title}</div>
                <p className="muted" style={{ fontSize: 12.5, margin: "4px 0 0", lineHeight: 1.5 }}>{n.body}</p>
                <EvidenceQuote
                  recommendation={n}
                  deal={deal}
                />
              </div>
              <button className="btn sm" onClick={() => openDeal(n.dealId)}>Open</button>
              <button className="btn sm accent">{n.action} <Icon name="arrow" size={12} /></button>
            </div>
          );
        })}
      </div>
    </div>
  );
}

// ---------- SETUP / ONBOARDING ----------
function SetupScreen({ goToDeals, showPageHeader = true }) {
  const [step, setStep] = useState(0);
  const steps = [
    { k: "welcome", label: "Welcome" },
    { k: "verify", label: "Verify" },
    { k: "details", label: "Details" },
    { k: "tools", label: "Connect Tools" },
    { k: "sync", label: "Sync Inbox" },
    { k: "intel", label: "Intel Report" },
  ];

  return (
    <div className="scroll" data-screen-label="05 Setup" data-tour="setup-page">
      {showPageHeader && (
        <>
          <div className="topbar"><Brand /></div>

          <header className="platform-page-header">
            <div className="platform-page-copy">
              <span className="platform-eyebrow">
                <span className="cp-eyebrow-dot good" aria-hidden />
                Onboarding
              </span>
              <h1 className="platform-page-title">Set up Nudge</h1>
              <p className="platform-page-subtitle">Verify your account, connect the sales stack, and generate the first buyer-proof readout.</p>
            </div>
            <div className="platform-page-meta">
              <span><b>{step + 1}</b> of {steps.length}</span>
            </div>
          </header>
        </>
      )}

      <div style={{ display: "grid", gridTemplateColumns: "1fr 320px", gap: 16, maxWidth: 1100, margin: "0 auto" }}>
        <div className="card" style={{ padding: 32, minHeight: 520 }} data-tour="setup-card">
          <div style={{ display: "flex", gap: 6, marginBottom: 28 }}>
            {steps.map((s, i) => (
              <div key={s.k} style={{
                flex: 1, height: 4, borderRadius: 999,
                background: i <= step ? "var(--accent)" : "var(--border)",
                transition: "background 200ms ease",
              }} />
            ))}
          </div>

          {step === 0 && <SetupWelcome onNext={() => setStep(1)} />}
          {step === 1 && <SetupVerify onNext={() => setStep(2)} onBack={() => setStep(0)} />}
          {step === 2 && <SetupDetails onNext={() => setStep(3)} onBack={() => setStep(1)} />}
          {step === 3 && <SetupTools onNext={() => setStep(4)} onBack={() => setStep(2)} />}
          {step === 4 && <SetupSync onNext={() => setStep(5)} onBack={() => setStep(3)} />}
          {step === 5 && <SetupIntel onBack={() => setStep(4)} goToDeals={goToDeals} />}
        </div>
        <SetupSidekick step={step} />
      </div>
    </div>
  );
}

function SetupWelcome({ onNext }) {
  const [email, setEmail] = useState("");
  return (
    <div style={{ maxWidth: 380, margin: "20px auto" }}>
      <div className="brand" style={{ fontSize: 24, marginBottom: 24 }}>
        <span className="braille">•••</span>
        <span>Nudge<sup style={{ fontSize: 14, color: "var(--text-3)" }}>®</sup></span>
      </div>
      <h2 className="h2" style={{ fontSize: 22 }}>Welcome to Nudge</h2>
      <p className="muted" style={{ fontSize: 13.5, marginTop: 6 }}>I'm an intelligence layer for your sales workflow.</p>
      <div className="eyebrow" style={{ marginTop: 24, marginBottom: 8 }}>Work email</div>
      <input className="input" placeholder="you@company.com" value={email} onChange={(e) => setEmail(e.target.value)} />
      <button className="btn accent lg" style={{ width: "100%", justifyContent: "center", marginTop: 16 }} onClick={onNext}>
        Continue with email
      </button>
      <div className="sub" style={{ textAlign: "center", margin: "12px 0" }}>or use single sign-on</div>
      <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
        <button className="btn" style={{ justifyContent: "center" }} disabled title="Prototype only — SSO is not wired yet">Continue with Google</button>
        <button className="btn" style={{ justifyContent: "center" }} disabled title="Prototype only — SSO is not wired yet">Continue with Microsoft</button>
      </div>
    </div>
  );
}

function SetupVerify({ onNext, onBack }) {
  const [code, setCode] = useState(["", "", "", "", "", ""]);
  const refs = useRef([]);
  const handle = (i, v) => {
    if (!/^[0-9]?$/.test(v)) return;
    const c = [...code]; c[i] = v; setCode(c);
    if (v && i < 5) refs.current[i + 1]?.focus();
  };
  return (
    <div style={{ maxWidth: 380, margin: "20px auto" }}>
      <div className="brand" style={{ fontSize: 24, marginBottom: 24 }}><span className="braille">•••</span><span>Nudge</span></div>
      <h2 className="h2" style={{ fontSize: 22 }}>Verify your identity</h2>
      <p className="muted" style={{ fontSize: 13.5, marginTop: 6 }}>We've sent a 6-digit code to your inbox.</p>
      <div className="eyebrow" style={{ marginTop: 24, marginBottom: 8 }}>One-time code</div>
      <div style={{ display: "flex", gap: 8 }}>
        {code.map((v, i) => (
          <input key={i} ref={(el) => (refs.current[i] = el)} className="input"
            style={{ textAlign: "center", fontSize: 20, fontWeight: 500, height: 52, padding: 0, fontFamily: "var(--font-mono)" }}
            maxLength={1} value={v} onChange={(e) => handle(i, e.target.value)} />
        ))}
      </div>
      <button className="btn accent lg" style={{ width: "100%", justifyContent: "center", marginTop: 24 }} onClick={onNext}>Verify & continue</button>
      <button className="btn ghost sm" style={{ width: "100%", justifyContent: "center", marginTop: 8 }} disabled title="Prototype only — resend is not wired yet">Resend code</button>
      <button className="btn ghost sm" style={{ marginTop: 16 }} onClick={onBack}><Icon name="arrowL" size={12} /> Back</button>
    </div>
  );
}

function SetupDetails({ onNext, onBack }) {
  return (
    <div style={{ maxWidth: 380, margin: "20px auto" }}>
      <h2 className="h2" style={{ fontSize: 22 }}>Confirm your details</h2>
      <p className="muted" style={{ fontSize: 13.5, marginTop: 6 }}>So Addy speaks for you, not at you.</p>
      <div style={{ display: "flex", flexDirection: "column", gap: 12, marginTop: 24 }}>
        <Field label="Full name" defaultValue="Ridha Mohamed" />
        <Field label="Job title" defaultValue="Account Executive" />
        <Field label="Company" defaultValue="Velo Labs" />
        <Field label="Primary timezone" defaultValue="America / New York" />
      </div>
      <button className="btn accent lg" style={{ width: "100%", justifyContent: "center", marginTop: 24 }} onClick={onNext}>Continue</button>
      <button className="btn ghost sm" style={{ marginTop: 12 }} onClick={onBack}><Icon name="arrowL" size={12} /> Back</button>
    </div>
  );
}

const Field = ({ label, defaultValue }) => (
  <label style={{ display: "flex", flexDirection: "column", gap: 6 }}>
    <span className="eyebrow">{label}</span>
    <input className="input" defaultValue={defaultValue} />
  </label>
);

function SetupTools({ onNext, onBack }) {
  const tools = [
    { name: "Salesforce", color: "oklch(0.7 0.15 220)", connected: true },
    { name: "HubSpot", color: "oklch(0.7 0.18 30)", connected: false },
    { name: "Outreach", color: "oklch(0.6 0.18 280)", connected: true },
    { name: "Slack", color: "oklch(0.7 0.18 350)", connected: false },
    { name: "Gong", color: "oklch(0.7 0.18 80)", connected: false },
  ];
  const [conns, setConns] = useState(tools.map((t) => t.connected));
  return (
    <div style={{ maxWidth: 480, margin: "20px auto" }}>
      <h2 className="h2" style={{ fontSize: 22 }}>Connect your stack</h2>
      <p className="muted" style={{ fontSize: 13.5, marginTop: 6 }}>I learn from where your work already lives.</p>
      <div style={{ display: "flex", flexDirection: "column", gap: 8, marginTop: 24 }}>
        {tools.map((t, i) => (
          <button key={t.name} onClick={() => setConns((s) => s.map((v, j) => j === i ? !v : v))}
            className="card" style={{ display: "flex", alignItems: "center", gap: 12, padding: 14, textAlign: "left", cursor: "pointer" }}>
            <div style={{ width: 28, height: 28, borderRadius: 8, background: t.color }} />
            <span style={{ flex: 1, fontWeight: 500 }}>{t.name}</span>
            {conns[i]
              ? <span className="chip good"><Icon name="check" size={12} /> Connected</span>
              : <span className="chip">Connect</span>}
          </button>
        ))}
      </div>
      <div style={{ display: "flex", gap: 8, marginTop: 24 }}>
        <button className="btn" onClick={onBack}>Back</button>
        <button className="btn accent" style={{ flex: 1, justifyContent: "center" }} onClick={onNext}>Continue</button>
      </div>
    </div>
  );
}

function SetupSync({ onNext, onBack }) {
  return (
    <div style={{ maxWidth: 480, margin: "20px auto" }}>
      <h2 className="h2" style={{ fontSize: 22 }}>Sync your inbox</h2>
      <p className="muted" style={{ fontSize: 13.5, marginTop: 6 }}>I'll read past 90 days to learn deal patterns. Encrypted, never shared.</p>
      <div className="card" style={{ marginTop: 20, padding: 20, background: "var(--surface-2)" }}>
        <div className="placeholder-stripe" style={{ height: 60, marginBottom: 16 }}>Connect Mail/Calendar</div>
        <Step ok label="Inbox connected" />
        <Step ok label="Reading recent threads" />
        <Step ok label="Mapping deals to contacts" running />
        <Step label="Generating intelligence report" />
      </div>
      <div style={{ display: "flex", gap: 8, marginTop: 20 }}>
        <button className="btn" onClick={onBack}>Back</button>
        <button className="btn accent" style={{ flex: 1, justifyContent: "center" }} onClick={onNext}>Generate report</button>
      </div>
    </div>
  );
}
const Step = ({ ok, running, label }) => (
  <div style={{ display: "flex", alignItems: "center", gap: 10, padding: "8px 0" }}>
    <span style={{
      width: 16, height: 16, borderRadius: 999,
      border: `1.5px solid ${ok ? "var(--good)" : "var(--border-strong)"}`,
      display: "grid", placeItems: "center", color: "var(--good)",
    }}>
      {ok && <Icon name="check" size={10} />}
      {running && <span style={{ width: 6, height: 6, background: "var(--accent)", borderRadius: 999, animation: "pulse 1s infinite" }} />}
    </span>
    <span style={{ fontSize: 13, color: ok ? "var(--text)" : "var(--text-2)" }}>{label}</span>
  </div>
);

function SetupIntel({ onBack, goToDeals }) {
  const findings = [
    "12 deals stalled — 3 missing economic buyer, 4 silent >7 days.",
    "Outreach reply rate: 21% (above team avg). Best subject pattern: question + name.",
    "Strongest accounts: Acme, Vertex, Lyric Health. Recommend expansion plays.",
    "Closing risk: Q2 pipeline concentrated in 4 accounts (62% of forecast).",
  ];
  return (
    <div style={{ maxWidth: 520, margin: "20px auto" }}>
      <h2 className="h2" style={{ fontSize: 22 }}>Addy's intelligence report</h2>
      <p className="muted" style={{ fontSize: 13.5, marginTop: 6 }}>Here's what I learned from your last 90 days.</p>
      <div className="card" style={{ marginTop: 20 }}>
        <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
          {findings.map((f, i) => (
            <div key={i} className="card" style={{ background: "var(--surface-2)", padding: 12, display: "flex", gap: 10 }}>
              <span className="dot-status info" style={{ marginTop: 6 }} />
              <span style={{ fontSize: 13 }}>{f}</span>
            </div>
          ))}
        </div>
      </div>
      <div style={{ display: "flex", gap: 8, marginTop: 24 }}>
        <button className="btn" onClick={onBack}>Back</button>
        <button className="btn accent" style={{ flex: 1, justifyContent: "center" }} onClick={goToDeals}>Take me to my deals</button>
      </div>
    </div>
  );
}

function SetupSidekick({ step }) {
  const blurbs = [
    { title: "I'm Addy.", body: "I'll use what's already in your tools to surface the next move on every deal — never busywork." },
    { title: "Quick check.", body: "We use one-time codes so you don't have to remember another password." },
    { title: "Your context.", body: "I'll personalise drafts in your voice. You can re-train me anytime in Settings." },
    { title: "Connect once.", body: "Salesforce, calendar, mail. I'll quietly read so I can speak intelligently later." },
    { title: "Reading…", body: "I look for stalled threads, missing stakeholders, momentum changes — the things you'd miss." },
    { title: "We're ready.", body: "Open your home and I'll show you the 3 deals that need attention today." },
  ];
  const b = blurbs[step] || blurbs[0];
  return (
    <div className="card" style={{ padding: 18, alignSelf: "flex-start", display: "flex", flexDirection: "column", gap: 14 }}>
      <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
        <div className="avatar addy">A</div>
        <div>
          <div style={{ fontWeight: 500 }}>Addy</div>
          <div className="sub" style={{ fontSize: 11 }}>Setup guide</div>
        </div>
      </div>
      <div style={{ fontWeight: 500 }}>{b.title}</div>
      <p className="muted" style={{ fontSize: 13, margin: 0, lineHeight: 1.55 }}>{b.body}</p>
      <div className="placeholder-stripe" style={{ height: 200 }}>Coach portrait</div>
      <div className="card" style={{ background: "var(--surface-2)", padding: 12 }}>
        <div className="eyebrow" style={{ marginBottom: 4 }}>Tip</div>
        <span style={{ fontSize: 12.5 }}>You can press <span className="mono chip" style={{ height: 22, fontSize: 11 }}>⌘K</span> any time to ask me something.</span>
      </div>
    </div>
  );
}

// ---------- PLAYBOOKS ----------
function PlaybooksScreen({ showPageHeader = true }) {
  const plays = [
    { name: "Re-engage cold champion", uses: 142, win: 0.41, color: "var(--accent)" },
    { name: "Loop in economic buyer", uses: 98, win: 0.55, color: "var(--info)" },
    { name: "Unblock legal review", uses: 67, win: 0.38, color: "var(--good)" },
    { name: "Drive verbal commit", uses: 51, win: 0.62, color: "var(--accent)" },
  ];
  return (
    <div className="scroll" data-screen-label="06 Playbooks" data-tour="playbooks-page">
      {showPageHeader && (
        <>
          <div className="topbar"><Brand /></div>
          <header className="platform-page-header">
            <div className="platform-page-copy">
              <span className="platform-eyebrow">
                <span className="cp-eyebrow-dot good" aria-hidden />
                Automation library
              </span>
              <h1 className="platform-page-title">Playbooks</h1>
              <p className="platform-page-subtitle">Repeatable plays Addy runs on your behalf. Each one is a sequence of nudges Addy will trigger on matching deals.</p>
            </div>
            <div className="platform-page-meta">
              <span><b>4</b> active playbooks</span>
            </div>
          </header>
        </>
      )}
      <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(260px, 1fr))", gap: 14 }}>
        {plays.map((p, i) => (
          <div key={i} className="card" style={{ display: "flex", flexDirection: "column", gap: 14 }} data-tour={i === 0 ? "playbook-first" : undefined}>
            <div className="eyebrow">Play {String(i + 1).padStart(2, "0")}</div>
            <h3 className="h3">{p.name}</h3>
            <div style={{ display: "flex", gap: 16, fontSize: 12, color: "var(--text-2)" }}>
              <div><span className="mono" style={{ color: "var(--text)", fontWeight: 500 }}>{p.uses}</span> runs</div>
              <div><span className="mono" style={{ color: "var(--text)", fontWeight: 500 }}>{Math.round(p.win * 100)}%</span> win-back</div>
            </div>
            <div className="bar" style={{ height: 6 }}>
              <div className="fill" style={{ width: `${p.win * 100}%`, background: p.color }} />
            </div>
            <button className="btn sm" style={{ alignSelf: "flex-start" }}>Configure <Icon name="arrow" size={12} /></button>
          </div>
        ))}
      </div>
    </div>
  );
}

window.AlertsScreen = AlertsScreen;
window.AnalyticsScreen = AnalyticsScreen;
window.PipelineBriefing = PipelineBriefing;
window.WonLossAnalysis = WonLossAnalysis;
window.SetupScreen = SetupScreen;
window.PlaybooksScreen = PlaybooksScreen;
