// pages-overview.jsx — Home (2 variants) + Stats

const { useState: useStateO, useMemo: useMemoO, useRef: useRefO, useEffect: useEffectO } = React;

/* ============================
   HOME — variant A (current)
============================ */

function useOverviewData() {
  /* Общий хук для HomeA/HomeB/StatsPage — грузит accounts + dashboard + events
     + status, обновляется каждые 15 сек. */
  const [accounts, setAccounts] = useStateO([]);
  const [dashboard, setDashboard] = useStateO(null);
  const [events, setEvents] = useStateO([]);
  const [statusPills, setStatusPills] = useStateO(STATUS_PILLS);
  const [loading, setLoading] = useStateO(true);

  useEffectO(() => {
    let stopped = false;
    const refresh = async () => {
      const [a, d, e, s] = await Promise.all([
        fetchAccounts(), fetchDashboard(), fetchEvents(30), fetchStatus(),
      ]);
      if (stopped) return;
      setAccounts(a);
      setDashboard(d);
      setEvents(e);
      setStatusPills(s);
      setLoading(false);
    };
    refresh();
    const id = setInterval(refresh, 15_000);
    return () => { stopped = true; clearInterval(id); };
  }, []);

  // Принудительный refresh статуса — для дёргания после bot start/stop,
  // чтобы UI не ждал 15-секундного polling-тика.
  const refreshStatus = React.useCallback(async () => {
    try {
      const s = await fetchStatus();
      setStatusPills(s);
    } catch {}
  }, []);

  return { accounts, dashboard, events, statusPills, loading, refreshStatus };
}

function HomeA() {
  const { accounts, dashboard, events, loading } = useOverviewData();
  const clients = dashboard?.clients || {};
  const totalToday = clients.clientsToday || 0;
  const totalYesterday = clients.clientsYesterday || 0;
  const totalWeek = clients.clients7d || 0;
  const diff = totalToday - totalYesterday;
  const active = accounts.filter((a) => a.today > 0).length;
  const messagesOutgoing = dashboard?.messagesTodayOutgoing || 0;

  return (
    <div className="space-y-6">
      <SectionTitle
        title="Главная"
        subtitle="Состояние бота и ключевые метрики за сегодня"
      />

      <div className="grid grid-cols-4 gap-4">
        <Metric label="Клиентов сегодня" value={totalToday} delta={(diff >= 0 ? "+" : "") + diff} deltaPositive={diff >= 0} sublabel={"вчера: " + totalYesterday} />
        <Metric label="Сообщений сегодня" value={messagesOutgoing.toLocaleString("ru")} sublabel="отправлено ботом" />
        <Metric label="За 7 дней" value={totalWeek} sublabel={"средн. " + Math.round(totalWeek / 7) + "/день"} />
        <Metric label="Активных аккаунтов" value={active} sublabel={"из " + accounts.length} />
      </div>

      <div className="grid grid-cols-3 gap-4">
        <Card className="col-span-2 p-5">
          <div className="flex items-center justify-between mb-5">
            <div>
              <div className="text-sm font-semibold">Клиенты по дням</div>
              <div className="text-xs text-zinc-500 mt-0.5">последние 7 дней</div>
            </div>
          </div>
          <TrafficChart data={dashboard?.trafficWeekly} />
        </Card>

        <Card className="p-5">
          <div className="flex items-center justify-between mb-4">
            <div className="text-sm font-semibold">Последние события</div>
            <Icon name="bell" className="w-4 h-4 text-zinc-500" />
          </div>
          <div className="space-y-3">
            {loading && Array.from({ length: 5 }).map((_, i) => (
              <div key={"sk" + i} className="flex items-start gap-3">
                <div className="w-1.5 h-1.5 rounded-full mt-2 shrink-0 bg-zinc-700" />
                <div className="flex-1 space-y-1">
                  <div className="h-3 bg-zinc-800/60 rounded animate-pulse w-3/4" />
                  <div className="h-2 bg-zinc-800/40 rounded animate-pulse w-1/4" />
                </div>
              </div>
            ))}
            {!loading && events.length === 0 && (
              <div className="text-center text-sm text-zinc-500 py-4">Событий пока нет</div>
            )}
            {!loading && events.slice(0, 8).map((e, i) => (
              <div key={i} className="flex items-start gap-3">
                <div
                  className={"w-1.5 h-1.5 rounded-full mt-2 shrink-0 " + (e.type === "ok" ? "bg-emerald-400" : e.type === "warn" ? "bg-amber-400" : e.type === "error" ? "bg-rose-400" : "bg-zinc-500")}
                />
                <div className="flex-1 min-w-0">
                  <div className="text-[13px] text-zinc-300 leading-snug">{e.text}</div>
                  <div className="text-[11px] text-zinc-500 mt-0.5">{e.time}</div>
                </div>
              </div>
            ))}
          </div>
        </Card>
      </div>
    </div>
  );
}

/* ============================
   HOME — variant B (live-feed focused)
============================ */

function HomeB() {
  const { accounts, dashboard, events, statusPills, loading, refreshStatus } = useOverviewData();
  const clients = dashboard?.clients || {};
  const totalToday = clients.clientsToday || 0;
  const diff = (clients.clientsToday || 0) - (clients.clientsYesterday || 0);
  const top5 = [...accounts].sort((a, b) => b.today - a.today).slice(0, 5);
  const receiptSummary = dashboard?.receipts || {};
  const pendingCount = receiptSummary.pending || 0;
  const approvedToday = receiptSummary.approvedTodayByCurrency || {};
  const sumRub = approvedToday["Rub"] || 0;

  return (
    <div className="space-y-6">
      <SectionTitle title="Главная" subtitle="Живой пульс бота · обновляется каждые 15 сек">
        <BotControls statusPills={statusPills} refreshStatus={refreshStatus} />
      </SectionTitle>

      {/* Hero band */}
      <div className="grid grid-cols-12 gap-4">
        <Card className="col-span-7 p-6 relative overflow-hidden">
          <div className="absolute -right-20 -top-20 w-72 h-72 rounded-full bg-indigo-500/10 blur-3xl" />
          <div className="relative">
            <div className="text-xs text-zinc-500 uppercase tracking-wider font-medium">Сегодня</div>
            <div className="flex items-baseline gap-3 mt-2">
              <div className="text-5xl font-semibold tracking-tight tabular-nums">{totalToday}</div>
              <div className="text-sm text-zinc-400">клиентов написали</div>
            </div>
            <div className="flex items-center gap-2 mt-3">
              <Pill tone={diff >= 0 ? "emerald" : "rose"}>
                <Icon name={diff >= 0 ? "up" : "down"} className="w-3 h-3"/> {(diff >= 0 ? "+" : "") + diff} к вчера
              </Pill>
              <Pill tone={pendingCount > 0 ? "amber" : "zinc"}>{pendingCount} чеков на проверке</Pill>
              <Pill tone="zinc">{sumRub.toLocaleString("ru")} ₽ за день</Pill>
            </div>
            <div className="mt-6">
              <TrafficChart compact data={dashboard?.trafficWeekly} />
            </div>
          </div>
        </Card>

        <Card className="col-span-5 p-5 flex flex-col">
          <div className="flex items-center justify-between mb-4">
            <div className="text-sm font-semibold">Топ аккаунтов сегодня</div>
            <span className="text-[11px] text-zinc-500">обновлено 2 мин назад</span>
          </div>
          <div className="space-y-3 flex-1">
            {loading && Array.from({ length: 5 }).map((_, i) => (
              <div key={"sk" + i} className="flex items-center gap-3">
                <span className="text-[11px] text-zinc-500 w-4 tabular-nums">{i + 1}</span>
                <div className="w-7 h-7 rounded-full bg-zinc-800/60 animate-pulse" />
                <div className="flex-1 space-y-1">
                  <div className="h-3 bg-zinc-800/60 rounded animate-pulse w-1/2" />
                  <div className="h-1 bg-zinc-800/40 rounded animate-pulse w-full" />
                </div>
              </div>
            ))}
            {!loading && top5.length === 0 && (
              <div className="text-center text-sm text-zinc-500 py-4">Активных аккаунтов сегодня нет</div>
            )}
            {!loading && top5.length > 0 && top5.map((a, i) => {
              const max = Math.max(top5[0].today, 1);
              const pct = (a.today / max) * 100;
              return (
                <div key={a.id} className="flex items-center gap-3">
                  <span className="text-[11px] text-zinc-500 w-4 tabular-nums">{i + 1}</span>
                  <Avatar name={a.name} color={a.color} avatarUrl={a.avatarUrl} size={28} />
                  <div className="flex-1 min-w-0">
                    <div className="flex items-baseline justify-between mb-1">
                      <div className="text-sm font-medium truncate">{a.name}</div>
                      <div className="text-xs text-zinc-400 tabular-nums">{a.today}</div>
                    </div>
                    <div className="h-1 bg-zinc-800 rounded-full overflow-hidden">
                      <div
                        className={"h-full rounded-full bg-gradient-to-r " + a.color}
                        style={{ width: pct + "%", transition: "width .6s ease" }}
                      />
                    </div>
                  </div>
                </div>
              );
            })}
          </div>
        </Card>
      </div>

      <div className="grid grid-cols-12 gap-4">
        <Card className="col-span-8 p-5">
          <div className="flex items-center justify-between mb-4">
            <div>
              <div className="text-sm font-semibold">Активность за час</div>
              <div className="text-[11px] text-zinc-500 mt-0.5">сообщения, чеки, диалоги</div>
            </div>
            <SegmentedControl
              value="hour"
              onChange={() => {}}
              options={[
                { id: "hour", label: "Час" },
                { id: "day", label: "День" },
                { id: "week", label: "Неделя" },
              ]}
              size="sm"
            />
          </div>
          <HourlyChart data={dashboard?.trafficHourly} />
        </Card>

        <Card className="col-span-4 p-5">
          <div className="flex items-center justify-between mb-4">
            <div className="text-sm font-semibold">Лента</div>
            <Pill tone="emerald">
              <span className="w-1 h-1 rounded-full bg-emerald-400" /> live
            </Pill>
          </div>
          <div className="space-y-2.5">
            {loading && Array.from({ length: 6 }).map((_, i) => (
              <div key={"sk" + i} className="flex items-start gap-3 p-2 -m-2 rounded-lg">
                <div className="w-1.5 h-1.5 rounded-full mt-2 shrink-0 bg-zinc-700" />
                <div className="flex-1 space-y-1">
                  <div className="h-2.5 bg-zinc-800/60 rounded animate-pulse w-3/4" />
                  <div className="h-2 bg-zinc-800/40 rounded animate-pulse w-1/4" />
                </div>
              </div>
            ))}
            {!loading && events.length === 0 && (
              <div className="text-center text-sm text-zinc-500 py-4">Событий пока нет</div>
            )}
            {!loading && events.map((e, i) => (
              <div key={i} className={"flex items-start gap-3 p-2 -m-2 rounded-lg " + (i === 0 ? "event-flash" : "")}>
                <div className={"w-1.5 h-1.5 rounded-full mt-2 shrink-0 " + (e.type === "ok" ? "bg-emerald-400" : e.type === "warn" ? "bg-amber-400" : e.type === "error" ? "bg-rose-400" : "bg-zinc-500")} />
                <div className="flex-1 min-w-0">
                  <div className="text-[12.5px] text-zinc-300 leading-snug">{e.text}</div>
                  <div className="text-[10px] text-zinc-500 mt-0.5 font-mono">{e.time}</div>
                </div>
              </div>
            ))}
          </div>
        </Card>
      </div>
    </div>
  );
}

function HomePage({ variant = "A" }) {
  return variant === "B" ? <HomeB /> : <HomeA />;
}

function TrafficChart({ compact = false, data }) {
  // data ожидается в формате [{day:"Пн", value:N, isToday:bool}] (7 элементов).
  // Если не пришло — рисуем placeholder с нулями.
  const series = Array.isArray(data) && data.length === 7
    ? data
    : ["Пн","Вт","Ср","Чт","Пт","Сб","Вс"].map((day, i) => ({ day, value: 0, isToday: i === 6 }));
  const max = Math.max(...series.map((s) => s.value), 1);
  return (
    <div className={"flex items-end gap-3 " + (compact ? "h-28" : "h-40")}>
      {series.map((s, i) => {
        const h = (s.value / max) * 100;
        return (
          <div key={i} className="flex-1 flex flex-col items-center gap-2">
            <div className="text-[11px] text-zinc-500 font-medium tabular-nums">{s.value}</div>
            <div className="w-full flex-1 flex items-end">
              <div
                style={{ height: h + "%", transition: "height .8s cubic-bezier(.2,.7,.2,1)" }}
                className={"w-full rounded-t-lg " + (s.isToday ? "bg-gradient-to-t from-indigo-600 to-indigo-400 shadow-lg shadow-indigo-500/30" : "bg-zinc-700/70 hover:bg-zinc-600/70")}
              />
            </div>
            <div className={"text-[11px] " + (s.isToday ? "text-indigo-400 font-medium" : "text-zinc-500")}>{s.day}</div>
          </div>
        );
      })}
    </div>
  );
}

function HourlyChart({ data }) {
  // data: [{hour:0, messages:N, checks:N}, ...] (24 элемента).
  // Если не пришло — нулевая полоса.
  const series = Array.isArray(data) && data.length === 24
    ? data
    : Array.from({ length: 24 }, (_, h) => ({ hour: h, messages: 0, checks: 0 }));
  const hours = series.map((s) => s.hour);
  const msgs = series.map((s) => s.messages);
  const checks = series.map((s) => s.checks);
  const max = Math.max(...msgs, 1);
  const H = 128; // px
  const nowHour = new Date().getHours();
  return (
    <div>
      <div className="flex items-end gap-1.5" style={{ height: H }}>
        {hours.map((h) => {
          const mh = (msgs[h] / max) * H;
          const ch = (checks[h] / max) * H;
          const isNow = h === nowHour;
          return (
            <div key={h} className="flex-1 flex items-end gap-0.5 relative group" style={{ height: H }}>
              <div className="absolute opacity-0 group-hover:opacity-100 -top-7 left-1/2 -translate-x-1/2 bg-zinc-800 border border-zinc-700 rounded px-1.5 py-0.5 text-[10px] whitespace-nowrap font-mono z-10 pointer-events-none">
                {h}:00 · {msgs[h]} / {checks[h]}
              </div>
              <div
                style={{ height: mh + "px" }}
                className={"flex-1 rounded-sm transition-colors " + (isNow ? "bg-indigo-400" : "bg-zinc-700 group-hover:bg-zinc-600")}
              />
              <div
                style={{ height: ch + "px" }}
                className={"flex-1 rounded-sm transition-colors " + (isNow ? "bg-emerald-400" : "bg-emerald-500/40 group-hover:bg-emerald-500/60")}
              />
            </div>
          );
        })}
      </div>
      <div className="flex justify-between mt-2 text-[10px] text-zinc-600 font-mono">
        <span>00:00</span>
        <span>06:00</span>
        <span>12:00</span>
        <span>18:00</span>
        <span>23:00</span>
      </div>
      <div className="flex items-center gap-4 mt-3 text-[11px] text-zinc-500">
        <div className="flex items-center gap-1.5"><span className="w-2 h-2 rounded-sm bg-zinc-700" /> сообщения</div>
        <div className="flex items-center gap-1.5"><span className="w-2 h-2 rounded-sm bg-emerald-500/60" /> чеки</div>
      </div>
    </div>
  );
}

/* ============================
   STATS
============================ */

function StatsPage() {
  const { accounts, dashboard, loading } = useOverviewData();
  const [period, setPeriod] = useStateO("today");
  const metric = period === "today" ? "today" : period === "yesterday" ? "yesterday" : "week";
  const clients = dashboard?.clients || {};
  const totalToday = clients.clientsToday || 0;
  const totalYesterday = clients.clientsYesterday || 0;
  const totalWeek = clients.clients7d || 0;
  const diff = totalToday - totalYesterday;
  const receiptSummary = dashboard?.receipts || {};
  const approvedToday = receiptSummary.approvedTodayByCurrency || {};

  // ── Парето-раскладка: активные аккаунты за выбранный период ──
  const active = accounts
    .filter((a) => (a[metric] || 0) > 0)
    .sort((a, b) => (b[metric] || 0) - (a[metric] || 0));
  const total = active.reduce((s, a) => s + (a[metric] || 0), 0);
  // сколько топ-аккаунтов суммарно дают ≥80% клиентов
  let vital = 0;
  if (total > 0) {
    let cum = 0;
    for (const a of active) {
      cum += a[metric] || 0;
      vital += 1;
      if (cum >= total * 0.8) break;
    }
  }
  // Столбцы: ВСЕ активные аккаунты тонкими барами — честный Парето.
  // (Агрегат «ещё K» убран: при ровном распределении хвост из 80+ аккаунтов
  // становился гигантским столбом, ломал масштаб и плющил реальные столбцы.)
  let cumSum = 0;
  const bars = active.map((a) => {
    const v = a[metric] || 0;
    cumSum += v;
    return { id: a.id, name: a.name, v, cum: total > 0 ? (cumSum / total) * 100 : 0 };
  });
  const leader = active[0];
  const periodLabel = period === "today" ? "сегодня" : period === "yesterday" ? "вчера" : "7 дней";

  return (
    <div className="space-y-6">
      <SectionTitle title="Статистика" subtitle="Активность клиентов по аккаунтам и периодам" />

      <div className="grid grid-cols-4 gap-4">
        <Metric label="Сегодня" value={totalToday} delta={(diff >= 0 ? "+" : "") + diff} deltaPositive={diff >= 0} sublabel="клиентов написало" />
        <Metric label="Вчера" value={totalYesterday} sublabel="клиентов написало" />
        <Metric label="7 дней" value={totalWeek} sublabel="суммарно" />
        <Metric label="Среднее в день" value={Math.round(totalWeek / 7)} sublabel="по 7 дням" />
      </div>

      <Card className="p-6">
        <div className="flex items-center justify-between mb-6">
          <div>
            <div className="text-sm font-semibold">Клиенты по аккаунтам</div>
            <div className="text-xs text-zinc-500 mt-0.5">диаграмма Парето — кто делает кассу, а кто простаивает</div>
          </div>
          <SegmentedControl
            value={period}
            onChange={setPeriod}
            options={[
              { id: "today", label: "Сегодня" },
              { id: "yesterday", label: "Вчера" },
              { id: "week", label: "7 дней" },
            ]}
          />
        </div>

        {active.length === 0 ? (
          <div className="text-center text-sm text-zinc-500 py-16">
            {loading ? "Загрузка…" : "Пока нет активности за период"}
          </div>
        ) : (
          <>
            {/* Insight + метрики */}
            <div className="flex items-stretch mb-5">
              <div
                className="flex items-center gap-3.5 rounded-[14px] border mr-6 py-3.5 pl-4 pr-6"
                style={{
                  background: "linear-gradient(135deg, rgba(156,204,82,0.16), rgba(156,204,82,0.05))",
                  borderColor: "rgba(127,181,57,0.28)",
                }}
              >
                <div className="font-bold leading-none tabular-nums" style={{ fontSize: 34, letterSpacing: "-0.02em", color: "#659827" }}>
                  {vital}
                  <span className="font-semibold" style={{ fontSize: 19, color: "rgba(101,152,39,0.5)" }}>/{active.length}</span>
                </div>
                <div className="text-[13px] leading-snug">
                  аккаунтов приносят<br />
                  <b className="font-semibold">80% клиентов</b> за {periodLabel}
                </div>
              </div>

              <div className="flex flex-col justify-center gap-1.5 pr-6">
                <span className="text-[10.5px] font-semibold uppercase text-zinc-500" style={{ letterSpacing: "0.07em" }}>Всего клиентов</span>
                <span className="text-[23px] font-semibold leading-none tabular-nums">{total.toLocaleString("ru")}</span>
              </div>
              <div className="flex flex-col justify-center gap-1.5 px-6 border-l" style={{ borderColor: "rgba(20,22,26,0.08)" }}>
                <span className="text-[10.5px] font-semibold uppercase text-zinc-500" style={{ letterSpacing: "0.07em" }}>Активных аккаунтов</span>
                <span className="text-[23px] font-semibold leading-none tabular-nums">{active.length}</span>
              </div>
              <div className="flex flex-col justify-center gap-1.5 px-6 border-l min-w-0" style={{ borderColor: "rgba(20,22,26,0.08)" }}>
                <span className="text-[10.5px] font-semibold uppercase text-zinc-500" style={{ letterSpacing: "0.07em" }}>Лидер</span>
                <span className="flex items-center gap-2">
                  <Avatar name={leader.name} color={leader.color} avatarUrl={leader.avatarUrl} size={24} />
                  <span className="text-[16px] font-semibold leading-none truncate max-w-[150px]">{leader.name}</span>
                  <span className="text-[13px] text-zinc-500 font-medium tabular-nums">{leader[metric]}</span>
                </span>
              </div>
            </div>

            {/* Легенда */}
            <div className="flex gap-5 text-[11.5px] text-zinc-500 mb-1">
              <span className="inline-flex items-center gap-[7px]">
                <span className="inline-block w-[11px] h-[11px] rounded-[3px]" style={{ background: "#9ccc52" }} /> Ключевые (80%)
              </span>
              <span className="inline-flex items-center gap-[7px]">
                <span className="inline-block w-[11px] h-[11px] rounded-[3px]" style={{ background: "#c9c3b6" }} /> Остальные
              </span>
              <span className="inline-flex items-center gap-[7px]">
                <span className="inline-block w-[18px] rounded-[2px]" style={{ borderTop: "2.5px solid #c1762e" }} /> Накопительный %
              </span>
            </div>

            <AccountsPareto bars={bars} vital={vital} key={period} />
          </>
        )}
      </Card>

      <div className="grid grid-cols-3 gap-4">
        {[
          { label: "RUB", key: "Rub", symbol: "₽" },
          { label: "UAH", key: "Uah", symbol: "₴" },
          { label: "USD", key: "Usd", symbol: "$" },
        ].map(({ label, key, symbol }) => {
          const todayAmt = approvedToday[key] || 0;
          return (
            <Card key={key} className="p-5">
              <div className="flex items-center justify-between">
                <div className="text-xs text-zinc-500 uppercase tracking-wider font-medium">{label}</div>
                <Pill tone={todayAmt > 0 ? "emerald" : "zinc"}>{symbol}</Pill>
              </div>
              <div className="mt-3 text-3xl font-semibold tracking-tight tabular-nums">{todayAmt.toLocaleString("ru")}</div>
              <div className="text-xs text-zinc-500 mt-1">подтверждено сегодня</div>
            </Card>
          );
        })}
      </div>
    </div>
  );
}

/* ============================
   ОПЛАТЫ — чеки по аккаунтам за период
============================ */

function _localISODate(offsetDays) {
  const d = new Date();
  if (offsetDays) d.setDate(d.getDate() + offsetDays);
  const p = (n) => String(n).padStart(2, "0");
  return d.getFullYear() + "-" + p(d.getMonth() + 1) + "-" + p(d.getDate());
}

function PaymentsPage() {
  const [period, setPeriod] = useStateO("today");
  const [start, setStart] = useStateO(_localISODate(-2));
  const [end, setEnd] = useStateO(_localISODate(0));
  const [data, setData] = useStateO(null);
  const [loading, setLoading] = useStateO(true);

  useEffectO(() => {
    let stopped = false;
    setLoading(true);
    fetchPaymentsStats(period, start, end).then((d) => {
      if (!stopped) { setData(d); setLoading(false); }
    });
    return () => { stopped = true; };
  }, [period, start, end]);

  const accounts = (data && data.accounts) || [];
  const total = (data && data.total) || 0;
  const days = (data && data.days) || 1;
  const label = (data && data.label) || "";
  const top = accounts[0];
  const max = (top && top.count) || 1;
  const inputCls = "bg-zinc-800/60 border border-zinc-700/60 rounded-lg px-3 py-1.5 text-sm focus:outline-none focus:border-indigo-500/50";

  return (
    <div className="space-y-6">
      <SectionTitle title="Оплаты" subtitle="Сколько чеков пришло по каждому аккаунту">
        <SegmentedControl
          value={period}
          onChange={setPeriod}
          options={[
            { id: "today", label: "Сегодня" },
            { id: "yesterday", label: "Вчера" },
            { id: "7d", label: "7 дней" },
            { id: "custom", label: "Свой период" },
          ]}
        />
      </SectionTitle>

      {period === "custom" && (
        <div className="flex items-center gap-3 text-sm text-zinc-500 -mt-3">
          <span>с</span>
          <input type="date" value={start} max={end} onChange={(e) => setStart(e.target.value)} className={inputCls} />
          <span>по</span>
          <input type="date" value={end} min={start} onChange={(e) => setEnd(e.target.value)} className={inputCls} />
        </div>
      )}

      <div className="grid grid-cols-3 gap-4">
        <Metric label="Всего оплат" value={total.toLocaleString("ru")} accent sublabel={label + (accounts.length ? ` · ${accounts.length} аккаунтов` : "")} />
        <Card className="p-5 hover-lift">
          <div className="text-xs text-zinc-500 font-medium uppercase tracking-wider">Топ аккаунт</div>
          {top ? (
            <div className="flex items-center gap-2.5 mt-3">
              <Avatar name={top.name} color={top.color} avatarUrl={top.avatarUrl} size={36} />
              <div className="min-w-0">
                <div className="text-[17px] font-semibold leading-tight truncate">{top.name}</div>
                <div className="text-[11px] text-zinc-500 tabular-nums">{top.count} оплат</div>
              </div>
            </div>
          ) : (
            <div className="text-[34px] font-semibold mt-2 text-zinc-400">—</div>
          )}
        </Card>
        <Metric label="В среднем в день" value={Math.round(total / Math.max(1, days))} sublabel="оплат / день" />
      </div>

      <Card className="p-6">
        <div className="flex items-center justify-between px-1 pb-3 text-[10.5px] font-semibold uppercase text-zinc-500" style={{ letterSpacing: "0.07em" }}>
          <span>Аккаунт</span>
          <span>Оплат</span>
        </div>
        {loading && !data ? (
          <div className="text-center text-sm text-zinc-500 py-16">Загрузка…</div>
        ) : accounts.length === 0 ? (
          <div className="text-center text-sm text-zinc-500 py-16">Нет оплат за период</div>
        ) : (
          <div className="stagger-rows" key={period + start + end}>
            {accounts.map((a) => (
              <div key={a.id} className="flex items-center gap-3.5 py-2.5" style={{ borderTop: "1px solid rgba(27,25,21,0.06)" }}>
                <Avatar name={a.name} color={a.color} avatarUrl={a.avatarUrl} size={34} />
                <div className="text-sm font-medium truncate" style={{ minWidth: 90, maxWidth: 170 }}>{a.name}</div>
                <div className="flex-1 h-[7px] rounded-full overflow-hidden" style={{ background: "rgba(27,25,21,0.07)" }}>
                  <div style={{ width: Math.round((a.count / max) * 100) + "%", height: "100%", borderRadius: 5, background: "linear-gradient(90deg,#9ccc52,#7fb539)" }} />
                </div>
                <div className="text-base font-semibold tabular-nums text-right" style={{ minWidth: 34 }}>{a.count}</div>
              </div>
            ))}
          </div>
        )}
      </Card>
    </div>
  );
}

/**
 * Парето-диаграмма «клиенты по аккаунтам» (SVG-презентация, данные готовит StatsPage).
 * bars: [{id, name, v, cum}] — ВСЕ активные аккаунты по убыванию (тонкие бары),
 * cum — накопительный % (0..100). vital — сколько первых входят в «ключевые 80%».
 * Имя/значение — в hover-tooltip (столбцов ~100, подписи не влезают).
 */
function AccountsPareto({ bars, vital }) {
  const W = 1400, H = 330;
  const padL = 48, padR = 58, padT = 30, padB = 40;
  const plotW = W - padL - padR;
  const plotH = H - padT - padB;
  const n = bars.length;
  const max = Math.max(...bars.map((b) => b.v), 1);
  // потолок — кратен 4 (целые деления оси) и близок к максимуму: 12 → 12
  const niceMax = Math.max(4, Math.ceil(max / 4) * 4);
  const slot = plotW / n;
  const barW = Math.max(Math.min(slot * 0.7, 40), 1.5);
  const baseY = padT + plotH;
  const ticks = 4;

  const yL = (v) => padT + plotH - (v / niceMax) * plotH;
  const yR = (pct) => padT + plotH - (pct / 100) * plotH;
  const cx = (i) => padL + slot * i + slot / 2;

  const pts = bars.map((b, i) => [cx(i), yR(Math.min(b.cum, 100))]);
  const linePath = pts.map((p, i) => (i === 0 ? "M " : "L ") + p[0].toFixed(1) + " " + p[1].toFixed(1)).join(" ");
  const areaPath = n >= 2
    ? linePath + " L " + pts[n - 1][0].toFixed(1) + " " + baseY + " L " + pts[0][0].toFixed(1) + " " + baseY + " Z"
    : "";
  const y80 = yR(80);
  const splitX = padL + slot * Math.min(vital, n);
  // точек на линии не больше ~14 (+ последняя); подписи значений — только
  // когда столбцам просторно; ось X — номера аккаунтов (1, 10, 20, …, N)
  const dotStep = Math.max(1, Math.ceil(n / 14));
  const showVals = slot >= 26;
  const xTicks = [];
  for (let i = 0; i < n; i++) {
    const num = i + 1;
    if (num === 1 || num % 10 === 0 || num === n) xTicks.push(i);
  }

  const LINE = "#c1762e";
  const MUTED = "#8a8272";

  return (
    <div className="w-full">
      <svg viewBox={"0 0 " + W + " " + H} className="w-full h-auto block" preserveAspectRatio="xMidYMid meet">
        <defs>
          <linearGradient id="paretoAreaGrad" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0" stopColor={LINE} stopOpacity="0.16" />
            <stop offset="1" stopColor={LINE} stopOpacity="0" />
          </linearGradient>
        </defs>

        {/* зона «ключевых» аккаунтов */}
        <rect x={padL} y={padT} width={Math.max(splitX - padL, 0)} height={plotH} fill="#9ccc52" opacity="0.06" rx="6" />

        {/* сетка + левая ось (клиенты) */}
        {Array.from({ length: ticks + 1 }, (_, i) => {
          const v = (niceMax * (ticks - i)) / ticks;
          const y = padT + (plotH * i) / ticks;
          return (
            <g key={"gy" + i}>
              <line x1={padL} y1={y} x2={W - padR} y2={y} stroke="rgba(27,25,21,0.07)" strokeWidth="1" />
              <text x={padL - 10} y={y + 3.5} textAnchor="end" fontSize="11" fill={MUTED} className="tabular-nums">{paretoFmt(v)}</text>
            </g>
          );
        })}

        {/* правая ось (%) */}
        {[0, 50, 80, 100].map((pct) => (
          <text key={"pr" + pct} x={W - padR + 10} y={yR(pct) + 3.5} textAnchor="start" fontSize="11" fill={LINE} opacity="0.7" className="tabular-nums">{pct}%</text>
        ))}

        {/* референс 80% */}
        <line x1={padL} y1={y80} x2={W - padR} y2={y80} stroke={LINE} strokeWidth="1.5" strokeDasharray="2 5" opacity="0.5" strokeLinecap="round" />
        <g transform={"translate(" + (padL + 8) + ", " + (y80 - 22) + ")"}>
          <rect x="0" y="0" width="34" height="16" rx="8" fill={LINE} opacity="0.12" />
          <text x="17" y="11.5" textAnchor="middle" fontSize="10" fontWeight="700" fill={LINE}>80%</text>
        </g>

        {/* вертикальная граница «ключевых»: на этом аккаунте накопилось 80% */}
        {vital > 0 && vital < n && (
          <g>
            <line x1={splitX} y1={padT} x2={splitX} y2={baseY} stroke="#659827" strokeWidth="1.2" strokeDasharray="3 4" opacity="0.4" />
            <rect x={splitX - 44} y={padT - 24} width="88" height="17" rx="8.5" fill="#9ccc52" opacity="0.16" />
            <text x={splitX} y={padT - 11.5} textAnchor="middle" fontSize="10" fontWeight="700" fill="#4c761c">{vital} акк. → 80%</text>
          </g>
        )}

        {/* столбцы — тонкие, имя/цифры в hover-tooltip */}
        {bars.map((b, i) => {
          const bh = Math.max((b.v / niceMax) * plotH, 1);
          const isVital = i < vital;
          return (
            <g key={b.id} className="pareto-bar-g">
              <rect
                x={cx(i) - barW / 2} y={yL(b.v)} width={barW} height={bh} rx={Math.min(3, barW / 2)}
                fill={isVital ? "#9ccc52" : "#c9c3b6"}
                className="pareto-bar"
                style={{ animationDelay: ((i / Math.max(n, 1)) * 0.8).toFixed(2) + "s" }}
              >
                <title>{b.name}: {b.v} клиентов ({b.cum.toFixed(1)}% накопительно)</title>
              </rect>
              {showVals && (
                <text
                  x={cx(i)} y={yL(b.v) - 8} textAnchor="middle" fontSize="11"
                  fontWeight={isVital ? "700" : "600"} fill={isVital ? "#659827" : MUTED}
                  className="tabular-nums"
                >{paretoFmt(b.v)}</text>
              )}
            </g>
          );
        })}

        {/* ось X: номера аккаунтов */}
        {xTicks.map((i) => (
          <text key={"xt" + i} x={cx(i)} y={baseY + 18} textAnchor="middle" fontSize="10" fill={MUTED} className="tabular-nums">{i + 1}</text>
        ))}

        {/* накопительная линия + область под ней */}
        {n >= 2 && <path d={areaPath} fill="url(#paretoAreaGrad)" className="pareto-area-anim" />}
        {n >= 2 && (
          <path
            d={linePath} pathLength="1" fill="none" stroke={LINE} strokeWidth="2"
            strokeLinejoin="round" strokeLinecap="round" opacity="0.6" className="pareto-line-anim"
          />
        )}
        {pts.map((p, i) => ((i % dotStep === 0 || i === n - 1) ? (
          <circle
            key={"dot" + i} cx={p[0]} cy={p[1]} r="3" fill="#fff" stroke={LINE} strokeWidth="1.75"
            opacity="0.6" className="pareto-dot-anim"
            style={{ animationDelay: ((i / Math.max(n - 1, 1)) * 0.9).toFixed(2) + "s" }}
          >
            <title>{bars[i].cum.toFixed(1)}% накопительно</title>
          </circle>
        ) : null))}
      </svg>
    </div>
  );
}

// компактный формат значений (1200 → «1,2k»)
function paretoFmt(v) {
  if (v >= 1000) return (v / 1000).toFixed(v % 1000 === 0 ? 0 : 1).replace(".", ",") + "k";
  return Math.round(v).toString();
}

/**
 * Управление ботом: статус-pill + кнопки Запустить/Остановить.
 * Статус берётся из statusPills (приходит из /api/status). После каждого
 * действия дёргаем refreshStatus() чтобы UI обновился сразу, не ждал
 * 10-сек polling-а. refreshStatus — prop из App, который зовёт fetchStatus
 * и setStatusPills.
 */
function BotControls({ statusPills, refreshStatus }) {
  const botPill = statusPills.find((p) => p.label === "Бот") || { value: "…", color: "zinc" };
  const running = botPill.color === "emerald";
  const dotColor = {
    emerald: "bg-emerald-400",
    rose: "bg-rose-400",
    amber: "bg-amber-400",
    zinc: "bg-zinc-500",
  }[botPill.color] || "bg-zinc-500";

  const [busy, setBusy] = useStateO("");  // 'start' | 'stop' | 'restart' | ''
  const [err, setErr] = useStateO("");

  const action = async (kind) => {
    setBusy(kind);
    setErr("");
    try {
      if (kind === "start") {
        await botStart();
        if (window.__toast) window.__toast.push({ kind: "ok", text: "Бот запущен" });
      } else if (kind === "stop") {
        await botStop();
        if (window.__toast) window.__toast.push({ kind: "info", text: "Бот остановлен" });
      } else if (kind === "restart") {
        await botRestart();
        if (window.__toast) window.__toast.push({ kind: "ok", text: "Бот перезапущен" });
      }
      // Force-refresh статуса чтобы UI отразил новое состояние сразу,
      // не ждал следующего polling-tick.
      if (refreshStatus) {
        try { await refreshStatus(); } catch {}
      }
    } catch (e) {
      const msg = String(e.message || e).slice(0, 120);
      setErr(msg);
      if (window.__toast) window.__toast.push({ kind: "err", text: "Ошибка: " + msg });
    } finally {
      setBusy("");
    }
  };

  return (
    <div className="flex items-center gap-2">
      <Pill tone={botPill.color}>
        <span className={"w-1.5 h-1.5 rounded-full " + dotColor + (running ? " live-pulse" : "")} />
        {botPill.value === "запущен" ? "онлайн" : botPill.value}
      </Pill>
      {!running && (
        <button
          onClick={() => action("start")}
          disabled={!!busy}
          className="flex items-center gap-2 px-3.5 py-2 rounded-lg bg-emerald-500 hover:bg-emerald-600 disabled:opacity-50 text-white text-sm font-medium transition-colors"
        >
          <Icon name="play" fill="currentColor" className="w-3.5 h-3.5" />
          {busy === "start" ? "Запускаю…" : "Запустить"}
        </button>
      )}
      {running && (
        <>
          <button
            onClick={() => action("restart")}
            disabled={!!busy}
            className="flex items-center gap-2 px-3.5 py-2 rounded-lg bg-indigo-500/20 border border-indigo-500/40 text-indigo-200 hover:bg-indigo-500/30 disabled:opacity-50 transition-colors text-sm font-medium"
            title="Stop + 1с пауза + Start"
          >
            <Icon name="refresh" className="w-3.5 h-3.5" />
            {busy === "restart" ? "Перезапускаю…" : "Перезапустить"}
          </button>
          <button
            onClick={() => action("stop")}
            disabled={!!busy}
            className="flex items-center gap-2 px-3.5 py-2 rounded-lg bg-zinc-800/60 border border-zinc-700/60 hover:bg-zinc-800 disabled:opacity-50 transition-colors text-sm text-zinc-300"
          >
            <Icon name="square" className="w-3.5 h-3.5" />
            {busy === "stop" ? "Останавливаю…" : "Остановить"}
          </button>
        </>
      )}
      {err && (
        <div className="text-[11px] text-rose-400 bg-rose-500/10 rounded px-2 py-1 max-w-[200px] truncate" title={err}>
          {err}
        </div>
      )}
    </div>
  );
}

Object.assign(window, { HomePage, StatsPage, TrafficChart, AccountsPareto, HourlyChart, BotControls });
