// DataLoop Cabinet — view components
const { useState, useMemo, useEffect, useRef } = React;

// ---------- Sparkline ----------
function Sparkline({ data, color, fill = true, h = 32, w = 80 }) {
  if (!data || data.length === 0) return null;
  const min = Math.min(...data);
  const max = Math.max(...data);
  const range = max - min || 1;
  const step = w / (data.length - 1);
  const pts = data.map((v, i) => [i * step, h - ((v - min) / range) * (h - 4) - 2]);
  const d = pts.map((p, i) => (i === 0 ? `M${p[0]},${p[1]}` : `L${p[0]},${p[1]}`)).join(" ");
  const dFill = `${d} L${w},${h} L0,${h} Z`;
  return (
    <svg width={w} height={h} viewBox={`0 0 ${w} ${h}`} style={{ display: "block" }}>
      {fill && <path d={dFill} fill={color} opacity="0.12" />}
      <path d={d} fill="none" stroke={color} strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round" />
    </svg>
  );
}

// ---------- Big area chart ----------
function AreaChart({ data, errors, days = 14 }) {
  const W = 1000, H = 200, padL = 38, padR = 12, padT = 14, padB = 26;
  const innerW = W - padL - padR;
  const innerH = H - padT - padB;
  const max = Math.max(...data) * 1.05;
  const xStep = innerW / (data.length - 1);
  const xy = (v, i) => [padL + i * xStep, padT + innerH - (v / max) * innerH];

  const pts = data.map((v, i) => xy(v, i));
  const path = pts.map((p, i) => (i === 0 ? `M${p[0]},${p[1]}` : `L${p[0]},${p[1]}`)).join(" ");
  const fill = `${path} L${pts[pts.length-1][0]},${padT+innerH} L${pts[0][0]},${padT+innerH} Z`;

  // y-axis ticks
  const ticks = 4;
  const tickVals = Array.from({ length: ticks + 1 }, (_, i) => Math.round((max / ticks) * i));
  const fmt = (n) => n >= 1000000 ? (n/1000000).toFixed(1)+"М" : n >= 1000 ? Math.round(n/1000)+"К" : n;

  // x-axis labels (dates) — synthetic last N days
  const today = new Date();
  const xLabels = [];
  for (let i = data.length - 1; i >= 0; i -= Math.ceil(data.length / 7)) {
    const d = new Date(today);
    d.setDate(d.getDate() - (data.length - 1 - i));
    xLabels.push({ i, label: `${d.getDate()}.${String(d.getMonth()+1).padStart(2,"0")}` });
  }

  // errors mini bars at bottom
  const errMax = Math.max(...errors);
  const errH = 18;
  const errBars = errors.map((e, i) => {
    const x = padL + i * xStep - 4;
    const bh = (e / errMax) * errH;
    return <rect key={i} x={x} y={H - padB - bh + 18} width="8" height={bh} fill="#d8504c" opacity="0.55" rx="1" />;
  });

  return (
    <svg className="cab-chart" viewBox={`0 0 ${W} ${H}`} preserveAspectRatio="none">
      {/* grid */}
      {tickVals.map((tv, i) => {
        const y = padT + innerH - (tv / max) * innerH;
        return (
          <g key={i}>
            <line x1={padL} y1={y} x2={W - padR} y2={y} stroke="var(--line)" strokeWidth="1" />
            <text x={padL - 8} y={y + 4} textAnchor="end" fontSize="10" fill="var(--ink-3)" fontFamily="var(--mono)">{fmt(tv)}</text>
          </g>
        );
      })}
      {/* area */}
      <path d={fill} fill="var(--accent)" opacity="0.12" />
      <path d={path} fill="none" stroke="var(--accent)" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
      {/* dots */}
      {pts.map((p, i) => (
        <circle key={i} cx={p[0]} cy={p[1]} r={i === pts.length - 1 ? 4 : 2.5}
                fill={i === pts.length - 1 ? "var(--accent)" : "var(--bg-3)"}
                stroke="var(--accent)" strokeWidth="1.5" />
      ))}
      {/* x labels */}
      {xLabels.map((xl, i) => (
        <text key={i} x={padL + xl.i * xStep} y={H - 6} textAnchor="middle" fontSize="10" fill="var(--ink-3)" fontFamily="var(--mono)">{xl.label}</text>
      ))}
    </svg>
  );
}

// ---------- Icons ----------
function Icon({ name, size = 18 }) {
  const p = { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.7, strokeLinecap: "round", strokeLinejoin: "round" };
  switch (name) {
    case "home":     return <svg {...p}><path d="M3 12l9-8 9 8" /><path d="M5 10v10h14V10" /></svg>;
    case "key":      return <svg {...p}><circle cx="8" cy="15" r="4" /><path d="M11 12l8-8M16 6l2 2M14 9l2 2" /></svg>;
    case "logs":     return <svg {...p}><path d="M4 4h14a2 2 0 0 1 2 2v14H6a2 2 0 0 1-2-2z" /><path d="M8 9h8M8 13h6M8 17h4" /></svg>;
    case "billing":  return <svg {...p}><rect x="3" y="6" width="18" height="13" rx="2" /><path d="M3 10h18M7 15h3" /></svg>;
    case "team":     return <svg {...p}><circle cx="9" cy="9" r="3.5" /><circle cx="17" cy="10" r="2.5" /><path d="M3 19c0-3 2.5-5 6-5s6 2 6 5" /><path d="M15 19c0-2 2-3 4-3s2 1 2 3" /></svg>;
    case "docs":     return <svg {...p}><path d="M5 4h10l4 4v12H5z" /><path d="M15 4v4h4M8 13h8M8 17h6" /></svg>;
    case "settings": return <svg {...p}><circle cx="12" cy="12" r="3" /><path d="M19 12a7 7 0 0 0-.1-1.4l2-1.5-2-3.4-2.3.8a7 7 0 0 0-2.4-1.4L13.6 3h-3.2l-.6 2.1a7 7 0 0 0-2.4 1.4l-2.3-.8-2 3.4 2 1.5A7 7 0 0 0 5 12c0 .5 0 1 .1 1.4l-2 1.5 2 3.4 2.3-.8a7 7 0 0 0 2.4 1.4l.6 2.1h3.2l.6-2.1a7 7 0 0 0 2.4-1.4l2.3.8 2-3.4-2-1.5c.1-.4.1-.9.1-1.4z" /></svg>;
    case "search":   return <svg {...p}><circle cx="11" cy="11" r="7" /><path d="m17 17 4 4" /></svg>;
    case "bell":     return <svg {...p}><path d="M6 9a6 6 0 0 1 12 0v5l2 3H4l2-3z" /><path d="M10 19a2 2 0 0 0 4 0" /></svg>;
    case "plus":     return <svg {...p}><path d="M12 5v14M5 12h14" /></svg>;
    case "arrow-up": return <svg {...p}><path d="M12 19V5M5 12l7-7 7 7" /></svg>;
    case "arrow-down": return <svg {...p}><path d="M12 5v14M5 12l7 7 7-7" /></svg>;
    case "arrow-right": return <svg {...p}><path d="M5 12h14M13 5l7 7-7 7" /></svg>;
    case "copy":     return <svg {...p}><rect x="8" y="8" width="12" height="12" rx="2" /><path d="M16 8V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h2" /></svg>;
    case "eye":      return <svg {...p}><path d="M1 12s4-7 11-7 11 7 11 7-4 7-11 7-11-7-11-7z" /><circle cx="12" cy="12" r="3" /></svg>;
    case "trash":    return <svg {...p}><path d="M3 6h18M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2M6 6l1 14a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2l1-14" /></svg>;
    case "logout":   return <svg {...p}><path d="M9 4H5a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h4" /><path d="M16 17l5-5-5-5M21 12H9" /></svg>;
    case "chevron":  return <svg {...p}><path d="m9 6 6 6-6 6" /></svg>;
    default: return null;
  }
}

// ============================================================
// OVERVIEW
// ============================================================
function ViewOverview({ goto }) {
  const D = window.__CAB;
  const quotaPct = Math.round((D.account.quotaUsedToday / D.account.quotaDaily) * 100);
  const requestsToday = D.usage14[D.usage14.length - 1];
  const requestsYesterday = D.usage14[D.usage14.length - 2];
  const deltaPct = Math.round(((requestsToday - requestsYesterday) / requestsYesterday) * 100);

  return (
    <>
      <div className="cab-page-head">
        <div>
          <h1>Здравствуйте, {D.user.name.split(" ")[0]}</h1>
          <div className="cab-page-sub">Сегодня {new Date().toLocaleDateString("ru-RU", { day: "numeric", month: "long" })} · {D.account.org}</div>
        </div>
        <div className="cab-page-head-actions">
          <button className="cab-btn cab-btn-ghost"><Icon name="docs" size={14} /> Документация</button>
          <button className="cab-btn cab-btn-accent" onClick={() => goto("keys")}><Icon name="plus" size={14} /> Новый ключ</button>
        </div>
      </div>

      {/* Stats */}
      <div className="cab-stat-row">
        <div className="cab-stat">
          <div className="cab-stat-label">Запросы сегодня</div>
          <div className="cab-stat-value">{(requestsToday / 1000).toFixed(1)}<span className="unit">К</span></div>
          <div className="cab-quota">
            <div className="cab-quota-bar"><div className="cab-quota-fill" style={{ width: `${quotaPct}%` }} /></div>
            <span className="cab-quota-pct">{quotaPct}% от {(D.account.quotaDaily/1000)}К</span>
          </div>
          <div className="cab-stat-spark"><Sparkline data={D.sparks.requests} color="var(--accent)" /></div>
        </div>
        <div className="cab-stat">
          <div className="cab-stat-label">Медиана ответа</div>
          <div className="cab-stat-value">27<span className="unit">мс</span></div>
          <div className="cab-stat-delta down"><Icon name="arrow-down" size={11} /> −2 мс к вчера</div>
          <div className="cab-stat-spark"><Sparkline data={D.sparks.latency} color="#1fa66f" /></div>
        </div>
        <div className="cab-stat">
          <div className="cab-stat-label">Ошибки 4xx/5xx</div>
          <div className="cab-stat-value">198<span className="unit">/24ч</span></div>
          <div className="cab-stat-delta up"><Icon name="arrow-up" size={11} /> 0.06% от запросов</div>
          <div className="cab-stat-spark"><Sparkline data={D.sparks.errors} color="#d8504c" /></div>
        </div>
        <div className="cab-stat">
          <div className="cab-stat-label">Доступность · 30 дн</div>
          <div className="cab-stat-value">99.99<span className="unit">%</span></div>
          <div className="cab-stat-delta"><span className="status-dot" style={{ background: "#1fa66f", boxShadow: "0 0 0 3px color-mix(in oklab, #1fa66f 25%, transparent)" }}></span> все системы в норме</div>
          <div className="cab-stat-spark"><Sparkline data={[99.97, 99.98, 99.99, 99.99, 99.98, 99.99, 99.99, 99.99, 99.99, 99.99, 99.99, 99.99, 99.99, 99.99]} color="#1fa66f" /></div>
        </div>
      </div>

      {/* Chart */}
      <div className="cab-chart-card">
        <div className="cab-card-head">
          <div>
            <div className="cab-card-title">Запросы по дням</div>
            <div className="cab-card-sub">за последние 14 дней · ошибки выделены красным</div>
          </div>
          <div className="cab-chart-toolbar">
            <button>24ч</button>
            <button>7 дн</button>
            <button className="active">14 дн</button>
            <button>30 дн</button>
          </div>
        </div>
        <AreaChart data={D.usage14} errors={D.errors14} />
        <div className="cab-chart-legend">
          <span className="cab-chart-legend-item"><span className="swatch" style={{ background: "var(--accent)" }}></span> успешные запросы</span>
          <span className="cab-chart-legend-item"><span className="swatch" style={{ background: "#d8504c", opacity: 0.55 }}></span> ошибки 4xx/5xx</span>
        </div>
      </div>

      {/* Two-column: keys + live feed */}
      <div className="cab-grid-2">
        <div className="cab-card" style={{ padding: 0 }}>
          <div className="cab-card-head" style={{ padding: "22px 24px 12px", marginBottom: 0 }}>
            <div>
              <div className="cab-card-title">API ключи</div>
              <div className="cab-card-sub">4 активных · 2 в production</div>
            </div>
            <span className="cab-card-link" onClick={() => goto("keys")}>управление <Icon name="arrow-right" size={11} /></span>
          </div>
          <table className="cab-table">
            <thead><tr><th>Имя</th><th>Префикс</th><th>Использован</th><th>За 7 дней</th></tr></thead>
            <tbody>
              {D.keys.slice(0, 4).map((k) => (
                <tr key={k.id}>
                  <td>
                    <div style={{ fontWeight: 600 }}>{k.name}</div>
                    <div className="muted mono" style={{ fontSize: 11, marginTop: 2 }}>{k.env === "live" ? "live · " : "test · "}{k.scope}</div>
                  </td>
                  <td className="mono">{k.prefix}<span className="muted">{k.tail}</span></td>
                  <td className="muted mono">{k.lastUsed}</td>
                  <td className="mono">{k.requests7d}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>

        <div className="cab-card">
          <div className="cab-card-head">
            <div>
              <div className="cab-card-title">Лента запросов</div>
              <div className="cab-card-sub">в реальном времени</div>
            </div>
            <span className="cab-card-link" onClick={() => goto("logs")}>все логи <Icon name="arrow-right" size={11} /></span>
          </div>
          <div className="cab-feed">
            {D.logs.slice(0, 10).map((l, i) => (
              <div className="cab-feed-row" key={i}>
                <span className="cab-feed-time">{l.t}</span>
                <span className="cab-method">{l.m}</span>
                <span className="cab-feed-endpoint">{l.p}</span>
                <span className={`cab-badge s-${l.s}`}><span className="dot"></span>{l.s}</span>
                <span className="cab-feed-latency">{l.ms} мс</span>
              </div>
            ))}
          </div>
        </div>
      </div>

      {/* Quickstart + Plan */}
      <div className="cab-grid-2-flat">
        <div className="cab-card">
          <div className="cab-card-head">
            <div>
              <div className="cab-card-title">Быстрый старт</div>
              <div className="cab-card-sub">три шага до первого запроса</div>
            </div>
          </div>
          <div className="cab-quickstart">
            <div className="cab-qs-tile">
              <div className="cab-qs-tile-num">01</div>
              <div className="cab-qs-tile-title">Создать ключ</div>
              <div className="cab-qs-tile-meta">для test или live окружения</div>
            </div>
            <div className="cab-qs-tile">
              <div className="cab-qs-tile-num">02</div>
              <div className="cab-qs-tile-title">Установить SDK</div>
              <div className="cab-qs-tile-meta">npm · pip · go get</div>
            </div>
            <div className="cab-qs-tile">
              <div className="cab-qs-tile-num">03</div>
              <div className="cab-qs-tile-title">Первый запрос</div>
              <div className="cab-qs-tile-meta">POST /v1/suggest/address</div>
            </div>
          </div>
          <div className="cab-code" style={{ marginTop: 16 }}>
            <button className="copy-btn">копировать</button>
            <span style={{ color: "#6e6c66" }}># Первый запрос — подсказки адресов</span><br />
            <span style={{ color: "#ff8aa0" }}>curl</span> -X POST <span style={{ color: "#a8d987" }}>https://api.dataloop.ru/v1/suggest/address</span> \<br />
            &nbsp;&nbsp;-H <span style={{ color: "#a8d987" }}>"Authorization: Token sk_live_a1b2····8c4f"</span> \<br />
            &nbsp;&nbsp;-H <span style={{ color: "#a8d987" }}>"Content-Type: application/json"</span> \<br />
            &nbsp;&nbsp;-d <span style={{ color: "#a8d987" }}>'{`{ "query": "тверская 12", "count": 5 }`}'</span>
          </div>
        </div>

        <div className="cab-plan-card">
          <div className="label">текущий план</div>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 18 }}>
            <div className="price">{D.account.plan}</div>
            <div className="price" style={{ fontSize: 28 }}>{D.account.planPrice}<span className="per">₽/мес</span></div>
          </div>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14, fontSize: 13, opacity: 0.85 }}>
            <div>
              <div style={{ opacity: 0.6, fontSize: 11, textTransform: "uppercase", letterSpacing: "0.06em", marginBottom: 4, fontFamily: "var(--mono)" }}>Лимит</div>
              <div style={{ fontFamily: "var(--mono)" }}>500 000 / сутки</div>
            </div>
            <div>
              <div style={{ opacity: 0.6, fontSize: 11, textTransform: "uppercase", letterSpacing: "0.06em", marginBottom: 4, fontFamily: "var(--mono)" }}>Продление</div>
              <div style={{ fontFamily: "var(--mono)" }}>{D.account.planRenews}</div>
            </div>
            <div>
              <div style={{ opacity: 0.6, fontSize: 11, textTransform: "uppercase", letterSpacing: "0.06em", marginBottom: 4, fontFamily: "var(--mono)" }}>SLA</div>
              <div style={{ fontFamily: "var(--mono)" }}>99.95%</div>
            </div>
            <div>
              <div style={{ opacity: 0.6, fontSize: 11, textTransform: "uppercase", letterSpacing: "0.06em", marginBottom: 4, fontFamily: "var(--mono)" }}>Поддержка</div>
              <div style={{ fontFamily: "var(--mono)" }}>Telegram · 4 ч</div>
            </div>
          </div>
          <div className="cab-plan-card-actions">
            <button className="cab-btn cab-btn-accent" onClick={() => goto("billing")}>Изменить план</button>
            <button className="cab-btn cab-btn-ghost" onClick={() => goto("billing")}>Счета</button>
          </div>
        </div>
      </div>
    </>
  );
}

// ============================================================
// API KEYS
// ============================================================
function ViewKeys() {
  const D = window.__CAB;
  const [keys, setKeys] = useState(D.keys);
  const [creating, setCreating] = useState(false);
  const [newName, setNewName] = useState("");
  const [newScope, setNewScope] = useState("full");
  const [newEnv, setNewEnv] = useState("test");
  const [revealed, setRevealed] = useState(null);

  function createKey() {
    if (!newName.trim()) return;
    const id = "k" + Math.random().toString(36).slice(2, 6);
    const rand = Math.random().toString(36).slice(2, 6) + Math.random().toString(36).slice(2, 6);
    const prefix = `sk_${newEnv}_${rand.slice(0, 4)}`;
    const full = `${prefix}${rand.slice(4, 8)}f2c8a1b9d4e6${rand.slice(0, 8)}`;
    const k = {
      id, name: newName, prefix, tail: "····" + rand.slice(4, 8),
      created: "только что", lastUsed: "никогда",
      scope: newScope, env: newEnv, requests7d: "0",
    };
    setKeys([k, ...keys]);
    setRevealed(full);
    setCreating(false);
    setNewName("");
  }

  function revokeKey(id) {
    setKeys(keys.filter((k) => k.id !== id));
  }

  return (
    <>
      <div className="cab-page-head">
        <div>
          <h1>API ключи</h1>
          <div className="cab-page-sub">{keys.length} активных ключей · ротация раз в 90 дней рекомендуется</div>
        </div>
        <div className="cab-page-head-actions">
          <button className="cab-btn cab-btn-ghost">Экспорт CSV</button>
          <button className="cab-btn cab-btn-accent" onClick={() => setCreating(true)}><Icon name="plus" size={14} /> Создать ключ</button>
        </div>
      </div>

      {revealed && (
        <div className="cab-key-reveal">
          <div>
            <div className="label">★ Новый ключ создан · показывается один раз</div>
            <div className="key">{revealed}</div>
            <div className="note">Скопируйте сейчас. После закрытия этого окна полный ключ будет недоступен — мы храним только префикс.</div>
          </div>
          <div style={{ display: "flex", gap: 8 }}>
            <button className="cab-btn cab-btn-accent" onClick={() => { navigator.clipboard?.writeText(revealed); }}><Icon name="copy" size={13} /> Копировать</button>
            <button className="cab-btn cab-btn-ghost" onClick={() => setRevealed(null)}>Закрыть</button>
          </div>
        </div>
      )}

      {creating && (
        <div className="cab-create-key">
          <h4>Новый ключ</h4>
          <div className="cab-form-row">
            <label>Название</label>
            <input className="cab-input" value={newName} onChange={(e) => setNewName(e.target.value)} placeholder="например, Backend · production" autoFocus />
          </div>
          <div className="cab-form-row">
            <label>Окружение</label>
            <div className="cab-radio-group">
              <button className={newEnv === "test" ? "active" : ""} onClick={() => setNewEnv("test")}>TEST</button>
              <button className={newEnv === "live" ? "active" : ""} onClick={() => setNewEnv("live")}>LIVE</button>
            </div>
          </div>
          <div className="cab-form-row">
            <label>Права доступа</label>
            <div className="cab-radio-group">
              <button className={newScope === "full" ? "active" : ""} onClick={() => setNewScope("full")}>full</button>
              <button className={newScope === "suggest" ? "active" : ""} onClick={() => setNewScope("suggest")}>suggest only</button>
              <button className={newScope === "readonly" ? "active" : ""} onClick={() => setNewScope("readonly")}>read only</button>
            </div>
          </div>
          <div style={{ display: "flex", gap: 10, justifyContent: "flex-end" }}>
            <button className="cab-btn cab-btn-ghost" onClick={() => setCreating(false)}>Отмена</button>
            <button className="cab-btn cab-btn-primary" onClick={createKey}>Создать ключ</button>
          </div>
        </div>
      )}

      <div className="cab-table-wrap">
        <table className="cab-table">
          <thead>
            <tr>
              <th>Ключ</th>
              <th>Окружение</th>
              <th>Права</th>
              <th>Создан</th>
              <th>Использован</th>
              <th>За 7 дней</th>
              <th className="col-actions"></th>
            </tr>
          </thead>
          <tbody>
            {keys.map((k) => (
              <tr key={k.id}>
                <td>
                  <div style={{ fontWeight: 600, marginBottom: 4 }}>{k.name}</div>
                  <span className="mono muted">{k.prefix}<span style={{ color: "var(--ink-3)" }}>{k.tail}</span></span>
                </td>
                <td>
                  <span className="cab-scope" style={{
                    color: k.env === "live" ? "#1fa66f" : "var(--ink-2)",
                    background: k.env === "live" ? "color-mix(in oklab, #1fa66f 12%, var(--bg-2))" : "var(--bg-2)",
                  }}>{k.env}</span>
                </td>
                <td><span className="cab-scope">{k.scope}</span></td>
                <td className="muted mono">{k.created}</td>
                <td className="muted mono">{k.lastUsed}</td>
                <td className="mono">{k.requests7d}</td>
                <td className="col-actions">
                  <button className="cab-btn cab-btn-sm cab-btn-ghost" style={{ marginRight: 6 }}>Ротация</button>
                  <button className="cab-btn cab-btn-sm cab-btn-danger" onClick={() => revokeKey(k.id)}><Icon name="trash" size={12} /></button>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      <div style={{ marginTop: 22, padding: "16px 20px", background: "var(--bg-2)", border: "1px solid var(--line)", borderRadius: 8, fontSize: 13, color: "var(--ink-2)", display: "flex", gap: 12, alignItems: "flex-start" }}>
        <div style={{ fontFamily: "var(--mono)", fontSize: 12, color: "var(--accent)", marginTop: 2 }}>NB</div>
        <div>
          <strong style={{ color: "var(--ink)" }}>Безопасность ключей.</strong> Не публикуйте ключи в публичных репозиториях. Используйте переменные окружения. При компрометации — мгновенная ротация без простоя через API <span className="mono" style={{ color: "var(--ink)" }}>POST /v1/keys/rotate</span>.
        </div>
      </div>
    </>
  );
}

// ============================================================
// LOGS
// ============================================================
function ViewLogs() {
  const D = window.__CAB;
  const [selected, setSelected] = useState(D.logs[0]);
  const [filterStatus, setFilterStatus] = useState("all");
  const [filterEp, setFilterEp] = useState("all");

  const logs = D.logs.filter((l) => {
    if (filterStatus === "ok" && l.s >= 400) return false;
    if (filterStatus === "err" && l.s < 400) return false;
    if (filterEp !== "all" && !l.p.includes(filterEp)) return false;
    return true;
  });

  return (
    <>
      <div className="cab-page-head">
        <div>
          <h1>Логи запросов</h1>
          <div className="cab-page-sub">Хранятся 30 дней · экспорт в S3 доступен на тарифе Прод</div>
        </div>
        <div className="cab-page-head-actions">
          <button className="cab-btn cab-btn-ghost">Экспорт JSONL</button>
          <button className="cab-btn cab-btn-ghost">Webhook</button>
        </div>
      </div>

      <div className="cab-filter-bar">
        <span className="cab-filter-chip" style={{ background: "transparent", border: "none", padding: 0, color: "var(--ink-3)" }}>Статус:</span>
        <button className={`cab-filter-chip ${filterStatus === "all" ? "active" : ""}`} onClick={() => setFilterStatus("all")}>все</button>
        <button className={`cab-filter-chip ${filterStatus === "ok" ? "active" : ""}`} onClick={() => setFilterStatus("ok")}>2xx</button>
        <button className={`cab-filter-chip ${filterStatus === "err" ? "active" : ""}`} onClick={() => setFilterStatus("err")}>4xx · 5xx</button>
        <span className="cab-filter-chip" style={{ background: "transparent", border: "none", padding: "0 0 0 12px", color: "var(--ink-3)" }}>Эндпоинт:</span>
        <button className={`cab-filter-chip ${filterEp === "all" ? "active" : ""}`} onClick={() => setFilterEp("all")}>все</button>
        <button className={`cab-filter-chip ${filterEp === "suggest" ? "active" : ""}`} onClick={() => setFilterEp("suggest")}>/suggest</button>
        <button className={`cab-filter-chip ${filterEp === "geocode" ? "active" : ""}`} onClick={() => setFilterEp("geocode")}>/geocode</button>
        <button className={`cab-filter-chip ${filterEp === "parse" ? "active" : ""}`} onClick={() => setFilterEp("parse")}>/parse</button>
        <button className={`cab-filter-chip ${filterEp === "batch" ? "active" : ""}`} onClick={() => setFilterEp("batch")}>/batch</button>
        <span style={{ marginLeft: "auto", fontFamily: "var(--mono)", fontSize: 11, color: "var(--ink-3)" }}>{logs.length} записей</span>
      </div>

      <div className="cab-logs-layout">
        <div className="cab-table-wrap">
          <table className="cab-table">
            <thead>
              <tr><th>Время</th><th>Метод</th><th>Эндпоинт</th><th>Статус</th><th>Латентность</th><th>Ключ</th><th>IP</th></tr>
            </thead>
            <tbody>
              {logs.map((l, i) => (
                <tr key={i} onClick={() => setSelected(l)} style={{ background: selected?.req === l.req ? "var(--bg-2)" : undefined }}>
                  <td className="muted mono">{l.t}</td>
                  <td><span className="cab-method">{l.m}</span></td>
                  <td className="mono">{l.p}</td>
                  <td><span className={`cab-badge s-${l.s}`}><span className="dot"></span>{l.s}</span></td>
                  <td className="mono">{l.ms} мс</td>
                  <td className="mono muted">{l.key}</td>
                  <td className="mono muted">{l.ip}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>

        {selected && (
          <div className="cab-log-detail">
            <div className="cab-card-head" style={{ marginBottom: 8 }}>
              <div>
                <div className="cab-card-title">{selected.m} {selected.p}</div>
                <div className="cab-card-sub">{selected.t}</div>
              </div>
              <span className={`cab-badge s-${selected.s}`}><span className="dot"></span>{selected.s}</span>
            </div>
            <dl className="cab-kv">
              <dt>Request ID</dt><dd>{selected.req}</dd>
              <dt>Латентность</dt><dd>{selected.ms} мс</dd>
              <dt>API-ключ</dt><dd>{selected.key}</dd>
              <dt>IP клиента</dt><dd>{selected.ip}</dd>
              <dt>User-Agent</dt><dd>dataloop-sdk/node@2.4.1</dd>
            </dl>
            <div className="cab-card-sub" style={{ marginTop: 16, marginBottom: 8 }}>Запрос · body</div>
            <div className="cab-code">
              <button className="copy-btn">копировать</button>
              <span style={{ color: "#a8d987" }}>{selected.body}</span>
            </div>
            <div className="cab-card-sub" style={{ marginTop: 16, marginBottom: 8 }}>Ответ · 200 OK</div>
            <div className="cab-code">
              <button className="copy-btn">копировать</button>
              <span>{"{"}</span><br />
              &nbsp;&nbsp;<span style={{ color: "#ffb86b" }}>"suggestions"</span>: [<br />
              &nbsp;&nbsp;&nbsp;&nbsp;{"{"} <span style={{ color: "#ffb86b" }}>"value"</span>: <span style={{ color: "#a8d987" }}>"г Москва, ул Тверская, д 12"</span>, ... {"}"},<br />
              &nbsp;&nbsp;&nbsp;&nbsp;... 4 ещё<br />
              &nbsp;&nbsp;]<br />
              <span>{"}"}</span>
            </div>
          </div>
        )}
      </div>
    </>
  );
}

// ============================================================
// BILLING
// ============================================================
function ViewBilling() {
  const D = window.__CAB;
  return (
    <>
      <div className="cab-page-head">
        <div>
          <h1>Биллинг</h1>
          <div className="cab-page-sub">Оплата помесячно · автосписание с привязанной карты</div>
        </div>
        <div className="cab-page-head-actions">
          <button className="cab-btn cab-btn-ghost">Реквизиты юр.лица</button>
          <button className="cab-btn cab-btn-primary">Изменить план</button>
        </div>
      </div>

      <div className="cab-grid-2-flat" style={{ marginTop: 0 }}>
        <div className="cab-plan-card">
          <div className="label">текущий план</div>
          <div className="price" style={{ marginBottom: 18 }}>{D.account.plan} <span className="per" style={{ marginLeft: 14 }}>{D.account.planPrice} ₽/мес</span></div>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16, fontSize: 13, opacity: 0.9 }}>
            <div>
              <div style={{ opacity: 0.6, fontSize: 11, textTransform: "uppercase", letterSpacing: "0.06em", marginBottom: 4, fontFamily: "var(--mono)" }}>Запросов в сутки</div>
              <div style={{ fontFamily: "var(--mono)" }}>500 000</div>
            </div>
            <div>
              <div style={{ opacity: 0.6, fontSize: 11, textTransform: "uppercase", letterSpacing: "0.06em", marginBottom: 4, fontFamily: "var(--mono)" }}>SLA</div>
              <div style={{ fontFamily: "var(--mono)" }}>99.95% · &lt; 50 мс</div>
            </div>
            <div>
              <div style={{ opacity: 0.6, fontSize: 11, textTransform: "uppercase", letterSpacing: "0.06em", marginBottom: 4, fontFamily: "var(--mono)" }}>Поддержка</div>
              <div style={{ fontFamily: "var(--mono)" }}>Telegram · ответ 4 ч</div>
            </div>
            <div>
              <div style={{ opacity: 0.6, fontSize: 11, textTransform: "uppercase", letterSpacing: "0.06em", marginBottom: 4, fontFamily: "var(--mono)" }}>Следующее списание</div>
              <div style={{ fontFamily: "var(--mono)" }}>{D.account.planRenews}</div>
            </div>
          </div>
        </div>

        <div className="cab-card">
          <div className="cab-card-head">
            <div>
              <div className="cab-card-title">Расход за май</div>
              <div className="cab-card-sub">по тарифу Прод</div>
            </div>
          </div>
          <div style={{ display: "flex", alignItems: "baseline", gap: 6, marginBottom: 12 }}>
            <span style={{ fontFamily: "var(--display)", fontSize: 44, fontWeight: 700, letterSpacing: "-0.03em", lineHeight: 1 }}>5.8</span>
            <span style={{ fontFamily: "var(--mono)", color: "var(--ink-3)" }}>М запросов</span>
            <span style={{ marginLeft: "auto", fontFamily: "var(--mono)", fontSize: 12, color: "var(--ink-3)" }}>из 15 М</span>
          </div>
          <div className="cab-quota-bar"><div className="cab-quota-fill" style={{ width: "39%" }} /></div>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 16, marginTop: 24, fontSize: 13 }}>
            <div>
              <div className="cab-card-sub" style={{ marginBottom: 4 }}>Suggest</div>
              <div className="mono" style={{ fontSize: 14 }}>4.2 М</div>
            </div>
            <div>
              <div className="cab-card-sub" style={{ marginBottom: 4 }}>Geocode</div>
              <div className="mono" style={{ fontSize: 14 }}>1.1 М</div>
            </div>
            <div>
              <div className="cab-card-sub" style={{ marginBottom: 4 }}>Batch</div>
              <div className="mono" style={{ fontSize: 14 }}>0.5 М</div>
            </div>
          </div>
          <div style={{ marginTop: 18, paddingTop: 16, borderTop: "1px solid var(--line)", display: "flex", justifyContent: "space-between", alignItems: "center", fontSize: 13 }}>
            <span style={{ color: "var(--ink-2)" }}>Сверх лимита (0.02 ₽/запрос)</span>
            <span className="mono">0 ₽</span>
          </div>
        </div>
      </div>

      <div className="cab-card" style={{ marginTop: 22, padding: 0 }}>
        <div className="cab-card-head" style={{ padding: "22px 24px 12px", marginBottom: 0 }}>
          <div>
            <div className="cab-card-title">История счетов</div>
            <div className="cab-card-sub">PDF и акты доступны после оплаты</div>
          </div>
          <span className="cab-card-link">показать все →</span>
        </div>
        <div className="cab-invoices">
          <table className="cab-table">
            <thead><tr><th>Счёт</th><th>Период</th><th>Дата</th><th>Сумма</th><th>Статус</th><th className="col-actions"></th></tr></thead>
            <tbody>
              {D.invoices.map((inv) => (
                <tr key={inv.id}>
                  <td className="mono">{inv.id}</td>
                  <td>{inv.period}</td>
                  <td className="muted mono">{inv.date}</td>
                  <td className="mono">{inv.amount} ₽</td>
                  <td><span className="cab-badge s-200"><span className="dot"></span>{inv.status}</span></td>
                  <td className="col-actions">
                    <button className="cab-btn cab-btn-sm cab-btn-ghost" style={{ marginRight: 6 }}>PDF</button>
                    <button className="cab-btn cab-btn-sm cab-btn-ghost">Акт</button>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>

      <div style={{ marginTop: 22, padding: 24, background: "var(--bg-2)", border: "1px solid var(--line)", borderRadius: 10, display: "flex", justifyContent: "space-between", alignItems: "center", gap: 24 }}>
        <div>
          <div className="cab-card-title" style={{ marginBottom: 4 }}>Способ оплаты</div>
          <div className="mono" style={{ color: "var(--ink-2)", fontSize: 13 }}>Visa •••• 4242 · действует до 11/28</div>
        </div>
        <button className="cab-btn cab-btn-ghost">Изменить карту</button>
      </div>
    </>
  );
}

// ============================================================
// TEAM
// ============================================================
function ViewTeam() {
  const D = window.__CAB;
  return (
    <>
      <div className="cab-page-head">
        <div>
          <h1>Команда</h1>
          <div className="cab-page-sub">{D.team.length} участника · приглашения отправляются по email</div>
        </div>
        <div className="cab-page-head-actions">
          <button className="cab-btn cab-btn-accent"><Icon name="plus" size={14} /> Пригласить</button>
        </div>
      </div>
      <div className="cab-table-wrap">
        <table className="cab-table">
          <thead><tr><th>Участник</th><th>Email</th><th>Роль</th><th>Добавлен</th><th className="col-actions"></th></tr></thead>
          <tbody>
            {D.team.map((m, i) => (
              <tr key={i}>
                <td>
                  <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
                    <div className="cab-avatar" style={{ width: 32, height: 32, fontSize: 12 }}>{m.initials}</div>
                    <span style={{ fontWeight: 600 }}>{m.name}</span>
                  </div>
                </td>
                <td className="mono muted">{m.email}</td>
                <td><span className="cab-scope">{m.role}</span></td>
                <td className="muted mono">{m.added}</td>
                <td className="col-actions">
                  <button className="cab-btn cab-btn-sm cab-btn-ghost">Изменить</button>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </>
  );
}

// ============================================================
// SETTINGS
// ============================================================
function ViewSettings() {
  const D = window.__CAB;
  return (
    <>
      <div className="cab-page-head">
        <div>
          <h1>Настройки</h1>
          <div className="cab-page-sub">Профиль организации, безопасность, вебхуки</div>
        </div>
      </div>

      <div className="cab-card" style={{ marginBottom: 18 }}>
        <div className="cab-card-head">
          <div>
            <div className="cab-card-title">Организация</div>
            <div className="cab-card-sub">отображается в счетах и API</div>
          </div>
        </div>
        <div className="cab-form-row"><label>Название</label><input className="cab-input" defaultValue={D.account.org} /></div>
        <div className="cab-form-row" style={{ marginTop: 10 }}><label>ИНН</label><input className="cab-input mono" defaultValue="7728168971" /></div>
        <div className="cab-form-row" style={{ marginTop: 10 }}><label>Email для счетов</label><input className="cab-input" defaultValue="billing@npd.io" /></div>
        <div style={{ display: "flex", justifyContent: "flex-end", marginTop: 14 }}>
          <button className="cab-btn cab-btn-primary">Сохранить</button>
        </div>
      </div>

      <div className="cab-card" style={{ marginBottom: 18 }}>
        <div className="cab-card-head">
          <div>
            <div className="cab-card-title">Webhooks</div>
            <div className="cab-card-sub">уведомления о превышении лимита и ошибках</div>
          </div>
          <button className="cab-btn cab-btn-sm cab-btn-ghost"><Icon name="plus" size={12} /> Добавить</button>
        </div>
        <div style={{ padding: "16px 0", borderTop: "1px solid var(--line)", display: "flex", alignItems: "center", justifyContent: "space-between" }}>
          <div>
            <div style={{ fontFamily: "var(--mono)", fontSize: 13 }}>https://hooks.npd.io/dataloop/alerts</div>
            <div className="cab-card-sub" style={{ marginTop: 4 }}>quota.exceeded · key.compromised · error.spike</div>
          </div>
          <span className="cab-badge s-200"><span className="dot"></span>активен</span>
        </div>
      </div>

      <div className="cab-card">
        <div className="cab-card-head">
          <div>
            <div className="cab-card-title">Опасная зона</div>
            <div className="cab-card-sub">действия необратимы</div>
          </div>
        </div>
        <div style={{ padding: "16px 0", borderTop: "1px solid var(--line)", display: "flex", alignItems: "center", justifyContent: "space-between" }}>
          <div>
            <div style={{ fontWeight: 600, marginBottom: 4 }}>Удалить организацию</div>
            <div className="cab-card-sub">все ключи будут отозваны, логи удалены через 30 дней</div>
          </div>
          <button className="cab-btn cab-btn-danger">Удалить</button>
        </div>
      </div>
    </>
  );
}

Object.assign(window, { ViewOverview, ViewKeys, ViewLogs, ViewBilling, ViewTeam, ViewSettings, Icon, Sparkline });
