/* Results table + Detail overlay + Settings */
/* YOUN-30: fix full_name → profiles via PATCH /api/profile, убрана аватарка */
/* YOUN-93: убраны тирные проверки экспорта — экспорт доступен всем тирам */

const API_URL = "https://younalyse-api-646149995822.europe-west1.run.app";
const getVideoId = (url) => {
  try {
    return new URLSearchParams(new URL(url).search).get("v");
  } catch {
    return null;
  }
};
const getThumbnail = (url) => {
  const vid = getVideoId(url);
  return vid ? `https://i.ytimg.com/vi/${vid}/mqdefault.jpg` : null;
};

// ── Outlier Score ──────────────────────────────────────────────────────────
const computeOutliers = (results) => {
  const channelSum = {};
  const channelCount = {};
  results.forEach((r) => {
    if (!channelSum[r.channelName]) {
      channelSum[r.channelName] = 0;
      channelCount[r.channelName] = 0;
    }
    channelSum[r.channelName] += r.views;
    channelCount[r.channelName]++;
  });
  const avg = {};
  Object.keys(channelSum).forEach((ch) => {
    avg[ch] = channelSum[ch] / channelCount[ch];
  });
  return avg;
};

const getOutlier = (video, channelAvg) => {
  const avg = channelAvg[video.channelName];
  if (!avg || avg === 0) return null;
  return video.views / avg;
};

const OutlierBadge = ({ score }) => {
  if (score === null || score === undefined)
    return <span style={{ color: "var(--fg-faint)" }}>—</span>;
  let icon, bg;
  if (score >= 2) {
    icon = "🔥";
    bg = "var(--good)";
  } else if (score >= 1.2) {
    icon = "↑";
    bg = "var(--accent)";
  } else if (score >= 0.8) {
    icon = "→";
    bg = "var(--fg-faint)";
  } else {
    icon = "↓";
    bg = "var(--bad)";
  }
  return (
    <span
      style={{
        display: "inline-flex",
        alignItems: "center",
        gap: 4,
        padding: "2px 7px",
        borderRadius: 4,
        background: bg,
        color: "#fff",
        fontSize: 11,
        fontFamily: "var(--mono)",
        fontWeight: 600,
        whiteSpace: "nowrap",
      }}
    >
      {icon} {score.toFixed(1)}x
    </span>
  );
};

const decodeHtml = (html) => {
  if (!html) return "";
  return html
    .replace(/&quot;/g, '"')
    .replace(/&#39;/g, "'")
    .replace(/&amp;/g, "&")
    .replace(/&lt;/g, "<")
    .replace(/&gt;/g, ">")
    .replace(/<br\s*\/?>/gi, "\n")
    .replace(/<[^>]+>/g, "");
};

// ── Transcript block ───────────────────────────────────────────────────────
const TranscriptBlock = ({ transcript }) => {
  const [expanded, setExpanded] = React.useState(false);
  const [copied, setCopied] = React.useState(false);
  const PREVIEW_CHARS = 400;
  const text = transcript || "";
  const isEmpty = !text || text.trim() === "";
  const isLong = text.length > PREVIEW_CHARS;
  const preview = isLong ? text.slice(0, PREVIEW_CHARS) + "…" : text;
  const copyTranscript = () => {
    navigator.clipboard.writeText(text);
    setCopied(true);
    setTimeout(() => setCopied(false), 2000);
  };
  if (isEmpty) {
    return (
      <div
        className="transcript"
        style={{ color: "var(--fg-faint)", fontStyle: "italic", fontSize: 13 }}
      >
        {window.PRODUCT_MODE === "ru"
          ? "Транскрипт недоступен"
          : "Transcript not available"}
      </div>
    );
  }
  return (
    <>
      <div
        className="transcript"
        style={{ whiteSpace: "pre-wrap", lineHeight: 1.7 }}
      >
        {expanded || !isLong ? text : preview}
      </div>
      <div style={{ display: "flex", gap: 8, marginTop: 8 }}>
        {isLong && (
          <button
            className="btn ghost sm"
            onClick={() => setExpanded(!expanded)}
            style={{ fontSize: 12, color: "var(--accent)" }}
          >
            {expanded
              ? window.PRODUCT_MODE === "ru"
                ? "↑ Свернуть"
                : "↑ Collapse"
              : window.PRODUCT_MODE === "ru"
                ? "↓ Показать полностью"
                : "↓ Show full transcript"}
          </button>
        )}
        <button
          className="btn ghost sm"
          onClick={copyTranscript}
          style={{ fontSize: 12 }}
        >
          <Icon name={copied ? "check" : "download"} size={12} />
          {copied
            ? window.PRODUCT_MODE === "ru"
              ? "Скопировано!"
              : "Copied!"
            : window.PRODUCT_MODE === "ru"
              ? "Копировать"
              : "Copy transcript"}
        </button>
      </div>
    </>
  );
};

// ── Channels tab ───────────────────────────────────────────────────────────
const ChannelsTab = ({ userId }) => {
  const [channels, setChannels] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [disconnecting, setDisconnecting] = React.useState(null);
  const [confirmChannel, setConfirmChannel] = React.useState(null);

  const loadChannels = () => {
    if (!userId) {
      setLoading(false);
      return;
    }
    setLoading(true);
    fetch(`${API_URL}/api/analytics/channels?user_id=${userId}`)
      .then((r) => r.json())
      .then((json) => {
        setChannels(json.channels || []);
        setLoading(false);
      })
      .catch(() => setLoading(false));
  };

  React.useEffect(() => {
    loadChannels();
  }, [userId]);

  const handleConnect = () => {
    window.location.href = `${API_URL}/auth/youtube?user_id=${userId}`;
  };

  const handleDisconnect = async () => {
    if (!confirmChannel) return;
    setDisconnecting(confirmChannel.channel_id);
    setConfirmChannel(null);
    await fetch(
      `${API_URL}/api/analytics/channels/${confirmChannel.channel_id}?user_id=${userId}`,
      {
        method: "DELETE",
      },
    );
    setDisconnecting(null);
    loadChannels();
  };

  return (
    <>
      <div className="form-card">
        <h3>{window.T?.channelsTitle || "Connected YouTube channels"}</h3>
        <p className="hint">
          {window.T?.channelsHint ||
            "Connect your YouTube channels via OAuth to access Analytics API data — retention, CTR, traffic sources."}
        </p>
        {loading ? (
          <div
            style={{
              padding: "32px 0",
              textAlign: "center",
              color: "var(--fg-faint)",
              fontSize: 13,
            }}
          >
            {window.T?.loading || "Загружаем…"}
          </div>
        ) : channels.length === 0 ? (
          <div
            style={{
              padding: "32px 0",
              textAlign: "center",
              color: "var(--fg-faint)",
            }}
          >
            <div style={{ fontSize: 32, marginBottom: 12 }}>📺</div>
            <div style={{ fontSize: 13, marginBottom: 16 }}>
              {window.T?.channelsEmpty || "No channels connected yet"}
            </div>
            <button className="btn primary" onClick={handleConnect}>
              {window.T?.channelsConnect || "Подключить YouTube канал"}
            </button>
            <div
              style={{ fontSize: 11, color: "var(--fg-faint)", marginTop: 8 }}
            >
              {window.T?.channelsOauthHint || "Redirects to Google OAuth"}
            </div>
          </div>
        ) : (
          <div
            style={{
              display: "flex",
              flexDirection: "column",
              gap: 10,
              marginTop: 16,
            }}
          >
            {channels.map((ch) => (
              <div
                key={ch.channel_id}
                style={{
                  display: "flex",
                  alignItems: "center",
                  gap: 12,
                  padding: "12px 14px",
                  border: "1px solid var(--border)",
                  borderRadius: "var(--radius)",
                  background: "var(--bg-elev)",
                }}
              >
                {ch.channel_thumbnail && (
                  <img
                    src={ch.channel_thumbnail}
                    style={{ width: 36, height: 36, borderRadius: "50%" }}
                    alt=""
                  />
                )}
                <div style={{ flex: 1 }}>
                  <div style={{ fontWeight: 500, fontSize: 13 }}>
                    {ch.channel_name}
                  </div>
                  <div
                    style={{
                      fontSize: 11,
                      color: "var(--fg-faint)",
                      fontFamily: "var(--mono)",
                    }}
                  >
                    {ch.channel_id}
                  </div>
                </div>
                <span className="status ok">
                  {window.T?.settingsConnected || "подключено"}
                </span>
                <button
                  className="btn ghost sm"
                  onClick={() =>
                    window.dispatchEvent(
                      new CustomEvent("navigate", { detail: "analytics" }),
                    )
                  }
                >
                  {window.T?.channelsViewAnalytics || "View analytics"} →
                </button>
                <button
                  className="btn danger sm"
                  disabled={disconnecting === ch.channel_id}
                  onClick={() =>
                    setConfirmChannel({
                      channel_id: ch.channel_id,
                      channel_name: ch.channel_name,
                    })
                  }
                  title="Отключить канал"
                >
                  {disconnecting === ch.channel_id ? (
                    <Icon name="spinner" size={13} />
                  ) : (
                    "Отключить"
                  )}
                </button>
              </div>
            ))}
            <div style={{ marginTop: 8 }}>
              <button className="btn" onClick={handleConnect}>
                {window.T?.channelsAddAnother || "+ Добавить ещё канал"}
              </button>
            </div>
          </div>
        )}
      </div>
      {confirmChannel && (
        <ConfirmPopup
          title={`Отключить канал "${confirmChannel.channel_name}"?`}
          message="Данные анализов, комментарии и транскрипты сохранятся. Отключается только доступ к YouTube Analytics API (retention, CTR, трафик). При повторном подключении доступ восстановится автоматически."
          confirmLabel="Отключить"
          confirmDanger={true}
          onConfirm={handleDisconnect}
          onCancel={() => setConfirmChannel(null)}
        />
      )}
    </>
  );
};

// ── BillingTab ─────────────────────────────────────────────────────────────
const BillingTab = ({ userId, userProfile }) => {
  const [usage, setUsage] = React.useState(null);
  const [purchases, setPurchases] = React.useState([]);
  const [catalog, setCatalog] = React.useState({});
  const [loading, setLoading] = React.useState(true);
  const [preview, setPreview] = React.useState(null);
  const [previewSku, setPreviewSku] = React.useState(null);

  const load = () => {
    if (!userId) return;
    setLoading(true);
    Promise.all([
      fetch(`${API_URL}/api/profile/usage?user_id=${userId}`).then((r) =>
        r.json(),
      ),
      fetch(`${API_URL}/api/purchases?user_id=${userId}`).then((r) => r.json()),
      fetch(`${API_URL}/api/purchases/catalog`).then((r) => r.json()),
    ])
      .then(([usageData, purchasesData, catalogData]) => {
        setUsage(usageData);
        setPurchases(purchasesData.purchases || []);
        setCatalog(catalogData.catalog || {});
        setLoading(false);
      })
      .catch(() => setLoading(false));
  };

  React.useEffect(() => {
    load();
  }, [userId]);

  const skuRubPrices = {
    ai_runs_1: 390,
    ai_runs_5: 1490,
    oauth_channels: 490,
    team_members: 790,
  };

  const handlePreview = (sku) => {
    setPreviewSku(sku);
    fetch(`${API_URL}/api/purchases/preview?user_id=${userId}&sku=${sku}`)
      .then((r) => r.json())
      .then((d) => {
        const fullRub = skuRubPrices[sku] || null;
        let nowRub = fullRub;
        if (
          fullRub &&
          d.period_end &&
          d.price_now_eur &&
          d.price_recurring_eur
        ) {
          const ratio =
            d.price_recurring_eur > 0
              ? d.price_now_eur / d.price_recurring_eur
              : 1;
          nowRub = Math.round(fullRub * ratio);
        }
        setPreview({
          ...d,
          price_now_rub: nowRub,
          price_recurring_rub: d.is_recurring ? fullRub : 0,
        });
      })
      .catch(() => {});
  };

  const handleDeactivate = async (purchaseId) => {
    await fetch(`${API_URL}/api/purchases/${purchaseId}?user_id=${userId}`, {
      method: "DELETE",
    });
    load();
  };

  const tier = userProfile?.subscription_tier || "trial";
  const tierLabel =
    {
      free: "Free",
      trial: "Trial",
      start: window.PRODUCT_MODE === "en" ? "🌱 Start" : "🌱 Старт",
      pro: window.PRODUCT_MODE === "en" ? "🚀 Pro" : "🚀 Про",
      producer: window.PRODUCT_MODE === "en" ? "🎬 Producer" : "🎬 Продюсер",
      studio: window.PRODUCT_MODE === "en" ? "🏢 Studio" : "🏢 Студия",
      superadmin: "Superadmin",
    }[tier] || tier;

  if (loading)
    return (
      <div
        style={{
          padding: "32px 0",
          textAlign: "center",
          color: "var(--fg-faint)",
          fontSize: 13,
        }}
      >
        {window.T?.loading || "Загружаем…"}
      </div>
    );

  const periodicPurchases = purchases.filter(
    (p) => p.type === "oauth_channels" || p.type === "team_members",
  );

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>
      <div className="form-card">
        <h3>{window.T?.billingCurrentPlan || "Текущий план"}</h3>
        <div
          style={{
            display: "flex",
            alignItems: "center",
            gap: 12,
            padding: "14px 16px",
            background: "var(--accent-soft)",
            borderRadius: "var(--radius)",
            border: "1px solid var(--accent)",
            marginBottom: 16,
          }}
        >
          <div style={{ flex: 1 }}>
            <div
              style={{ fontWeight: 600, color: "var(--accent)", fontSize: 15 }}
            >
              {tierLabel}
            </div>
            {usage?.period_end && (
              <div
                style={{ fontSize: 12, color: "var(--fg-muted)", marginTop: 2 }}
              >
                {window.T?.billingNextPayment || "Следующий платёж:"}{" "}
                {new Date(usage.period_end).toLocaleDateString("ru")}
              </div>
            )}
          </div>
          {tier !== "superadmin" && tier !== "studio" && (
            <button
              className="btn primary sm"
              onClick={() =>
                window.dispatchEvent(
                  new CustomEvent("navigate", { detail: "plans" }),
                )
              }
            >
              Upgrade
            </button>
          )}
        </div>
        {usage && (
          <div
            style={{
              display: "grid",
              gridTemplateColumns: "repeat(3,1fr)",
              gap: 12,
            }}
          >
            <div className="kpi">
              <div className="label">
                {window.T?.billingRunsUsed || "Ранов использовано"}
              </div>
              <div className="value" style={{ fontSize: 18 }}>
                {usage.runs?.used} /{" "}
                {usage.runs?.limit === 999999 ? "∞" : usage.runs?.limit}
              </div>
              {usage.runs?.extra > 0 && (
                <div className="delta">
                  +{usage.runs.extra} {window.T?.billingExtra || "докуплено"}
                </div>
              )}
            </div>
            <div className="kpi">
              <div className="label">
                {window.T?.billingOauthChannels || "OAuth каналов"}
              </div>
              <div className="value" style={{ fontSize: 18 }}>
                {usage.oauth_channels?.used} /{" "}
                {usage.oauth_channels?.limit === 999999
                  ? "∞"
                  : usage.oauth_channels?.limit}
              </div>
            </div>
            <div className="kpi">
              <div className="label">
                {window.T?.billingExtraMembers || "Доп. членов команды"}
              </div>
              <div className="value" style={{ fontSize: 18 }}>
                {usage.team_members?.extra || 0}
              </div>
            </div>
          </div>
        )}
      </div>

      {periodicPurchases.length > 0 && (
        <div className="form-card">
          <h3>{window.T?.billingActiveAddons || "Активные докупки"}</h3>
          <p className="hint">
            {window.T?.billingActiveAddonsHint ||
              "Активны до конца текущего периода. При отключении не продлеваются."}
          </p>
          {periodicPurchases.map((p) => (
            <div
              key={p.id}
              style={{
                display: "flex",
                alignItems: "center",
                gap: 12,
                padding: "10px 0",
                borderBottom: "1px solid var(--border)",
              }}
            >
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 13, fontWeight: 500 }}>
                  {p.type === "oauth_channels"
                    ? window.T?.billingAddonChannel ||
                      "📺 Доп. YouTube канал (OAuth)"
                    : window.T?.billingAddonMember || "👥 Доп. член команды"}
                </div>
                <div style={{ fontSize: 11, color: "var(--fg-faint)" }}>
                  {window.PRODUCT_MODE === "ru" && skuRubPrices[p.type]
                    ? `₽${skuRubPrices[p.type]}`
                    : `€${p.price_eur}`}
                  /{window.T?.billingPerMonth || "мес"} ·{" "}
                  {window.T?.billingUntil || "до"}{" "}
                  {p.period_end
                    ? new Date(p.period_end).toLocaleDateString("ru")
                    : "—"}
                </div>
              </div>
              <span className="status ok">
                {window.T?.billingActive || "активно"}
              </span>
              <button
                className="btn danger sm"
                onClick={() => handleDeactivate(p.id)}
              >
                {window.T?.billingDeactivate || "Отключить"}
              </button>
            </div>
          ))}
        </div>
      )}

      <div className="form-card">
        <h3>{window.T?.billingAddons || "Докупить"}</h3>
        <p className="hint">
          {window.T?.billingAddonsHint ||
            "Дополнительные блоки сверх вашего тира без смены подписки."}
        </p>
        <div
          style={{
            display: "grid",
            gridTemplateColumns: "1fr 1fr",
            gap: 12,
            marginBottom: 16,
          }}
        >
          {Object.entries(catalog).map(([sku, item]) => (
            <div
              key={sku}
              style={{
                padding: "14px 16px",
                border: `1px solid ${previewSku === sku ? "var(--accent)" : "var(--border)"}`,
                borderRadius: "var(--radius)",
                background:
                  previewSku === sku ? "var(--accent-soft)" : "var(--bg-elev)",
              }}
            >
              <div style={{ fontWeight: 600, fontSize: 13, marginBottom: 4 }}>
                {item.label}
              </div>
              <div style={{ fontSize: 20, fontWeight: 700, marginBottom: 8 }}>
                {window.PRODUCT_MODE === "ru" && skuRubPrices[sku]
                  ? `₽${skuRubPrices[sku].toLocaleString()}`
                  : `€${item.price_eur}`}
                {item.type !== "ai_runs" && (
                  <span
                    style={{
                      fontSize: 12,
                      fontWeight: 400,
                      color: "var(--fg-faint)",
                    }}
                  >
                    /{window.T?.billingPerMonth || "мес"}
                  </span>
                )}
              </div>
              <button
                className="btn primary sm"
                style={{ width: "100%" }}
                onClick={() => handlePreview(sku)}
              >
                {window.T?.billingDetails || "Подробнее"}
              </button>
            </div>
          ))}
        </div>
        {preview && previewSku && (
          <div
            style={{
              padding: "14px 16px",
              borderRadius: "var(--radius)",
              background: "var(--bg-sunk)",
              border: "1px solid var(--border)",
            }}
          >
            <div style={{ fontWeight: 600, fontSize: 13, marginBottom: 10 }}>
              {preview.label}
            </div>
            <div
              style={{
                display: "flex",
                gap: 24,
                fontSize: 13,
                marginBottom: 12,
              }}
            >
              <div>
                <div
                  style={{
                    color: "var(--fg-faint)",
                    fontSize: 11,
                    marginBottom: 2,
                  }}
                >
                  {window.T?.billingDueNow || "К ОПЛАТЕ СЕЙЧАС"}
                </div>
                <div style={{ fontWeight: 700, fontSize: 20 }}>
                  {window.PRODUCT_MODE === "ru" && preview.price_now_rub
                    ? `₽${preview.price_now_rub.toLocaleString()}`
                    : `€${preview.price_now_eur}`}
                </div>
                {preview.is_recurring && preview.period_end && (
                  <div style={{ fontSize: 11, color: "var(--fg-faint)" }}>
                    {window.T?.billingDaysLeft1 || "за"}{" "}
                    {Math.max(
                      0,
                      Math.round(
                        (new Date(preview.period_end) - new Date()) / 86400000,
                      ),
                    )}{" "}
                    {window.T?.billingDaysLeft2 || "дней до конца периода"}
                  </div>
                )}
              </div>
              {preview.is_recurring && (
                <div>
                  <div
                    style={{
                      color: "var(--fg-faint)",
                      fontSize: 11,
                      marginBottom: 2,
                    }}
                  >
                    {window.T?.billingNextPeriod || "В СЛЕДУЮЩЕМ ПЕРИОДЕ"}
                  </div>
                  <div style={{ fontWeight: 700, fontSize: 20 }}>
                    {window.PRODUCT_MODE === "ru" && preview.price_recurring_rub
                      ? `₽${preview.price_recurring_rub.toLocaleString()}`
                      : `€${preview.price_recurring_eur}`}
                    <span style={{ fontSize: 12, fontWeight: 400 }}>
                      /{window.T?.billingPerMonth || "мес"}
                    </span>
                  </div>
                </div>
              )}
            </div>
            <div style={{ display: "flex", gap: 8 }}>
              <a
                href={`mailto:hello@younalyse.app?subject=${window.T?.billingRequestSubject || "Докупка"}: ${preview.label}&body=${window.T?.billingRequestBody || "Хочу докупить"}: ${preview.label}.%0A${window.T?.billingRequestUserId || "Мой user_id"}: ${userId}`}
                className="btn primary sm"
              >
                {window.T?.billingRequestBtn || "Запросить докупку"} →
              </a>
              <button
                className="btn sm"
                onClick={() => {
                  setPreview(null);
                  setPreviewSku(null);
                }}
              >
                {window.T?.cancel || "Отмена"}
              </button>
            </div>
            <div
              style={{ fontSize: 11, color: "var(--fg-faint)", marginTop: 8 }}
            >
              {window.T?.billingManualHint ||
                "Пока платёжка не подключена — отправьте запрос, зачислим вручную в течение часа."}
            </div>
          </div>
        )}
      </div>
    </div>
  );
};

// ── QuotasTab ──────────────────────────────────────────────────────────────
const QuotasTab = ({ userId }) => {
  const [usage, setUsage] = React.useState(null);
  const [loading, setLoading] = React.useState(true);

  React.useEffect(() => {
    if (!userId) return;
    fetch(`${API_URL}/api/profile/usage?user_id=${userId}`)
      .then((r) => r.json())
      .then((d) => {
        setUsage(d);
        setLoading(false);
      })
      .catch(() => setLoading(false));
  }, [userId]);

  if (loading)
    return (
      <div
        style={{
          padding: "32px 0",
          textAlign: "center",
          color: "var(--fg-faint)",
          fontSize: 13,
        }}
      >
        {window.T?.loading || "Загружаем…"}
      </div>
    );
  if (!usage)
    return (
      <div className="form-card">
        <p className="hint">
          {window.T?.quotasLoadError ||
            "Не удалось загрузить квоты. Попробуйте обновить страницу."}
        </p>
      </div>
    );

  const QuotaRow = ({ label, used, limit, extra, hint }) => {
    const isInf = limit === 999999 || limit == null;
    const pct =
      !isInf && limit > 0 && used != null
        ? Math.min(100, (used / limit) * 100)
        : 0;
    const isLow = !isInf && pct > 80;
    return (
      <div
        style={{ padding: "10px 0", borderBottom: "1px solid var(--border)" }}
      >
        <div
          style={{
            display: "flex",
            justifyContent: "space-between",
            alignItems: "baseline",
            marginBottom: used != null && !isInf ? 6 : 0,
          }}
        >
          <div>
            <span style={{ fontSize: 13, fontWeight: 500 }}>{label}</span>
            {hint && (
              <span
                style={{
                  fontSize: 11,
                  color: "var(--fg-faint)",
                  marginLeft: 8,
                }}
              >
                {hint}
              </span>
            )}
          </div>
          <div
            style={{
              fontFamily: "var(--mono)",
              fontSize: 12,
              fontWeight: 600,
              color: isLow ? "var(--warn)" : "var(--fg)",
            }}
          >
            {used != null ? `${used} / ` : ""}
            {isInf ? "∞" : limit}
            {extra > 0 && (
              <span
                style={{ color: "var(--good)", marginLeft: 6, fontWeight: 400 }}
              >
                +{extra} {window.T?.billingExtra || "докуп."}
              </span>
            )}
          </div>
        </div>
        {used != null && !isInf && limit > 0 && (
          <div
            style={{
              height: 4,
              borderRadius: 2,
              background: "var(--bg-sunk)",
              overflow: "hidden",
            }}
          >
            <div
              style={{
                height: "100%",
                borderRadius: 2,
                width: `${pct}%`,
                background: isLow ? "var(--warn)" : "var(--accent)",
                transition: "width 0.3s",
              }}
            />
          </div>
        )}
      </div>
    );
  };

  return (
    <div className="form-card">
      <h3>{window.T?.settingsTabQuotas || "Квоты"}</h3>
      <p className="hint">
        {window.T?.quotasTier || "Тир"}: <strong>{usage.tier}</strong>
        {usage.period_end &&
          ` · ${window.T?.quotasReset || "Сброс"}: ${new Date(usage.period_end).toLocaleDateString("ru")}`}
      </p>
      <div style={{ marginTop: 8 }}>
        <div
          style={{
            fontSize: 11,
            fontWeight: 600,
            textTransform: "uppercase",
            letterSpacing: "0.06em",
            color: "var(--fg-faint)",
            marginBottom: 4,
          }}
        >
          {window.T?.quotasSectionAnalysis || "Анализ"}
        </div>
        <QuotaRow
          label={window.T?.quotasRunsMonth || "Ранов в месяц"}
          used={usage.runs?.used}
          limit={usage.runs?.limit}
          extra={usage.runs?.extra || 0}
          hint={window.T?.quotasResetsHint || "сбрасывается каждые 30 дней"}
        />
        <QuotaRow
          label={window.T?.quotasVideosRun || "Видео на ран"}
          limit={usage.videos_per_run}
          hint={window.T?.quotasVideosRunHint || "макс. видео за один запуск"}
        />
        <QuotaRow
          label={
            window.T?.quotasCommentsVideo || "Комментариев на видео (Claude)"
          }
          limit={usage.comments_per_video}
        />
        <QuotaRow
          label={window.T?.quotasClaudeRuns || "Ранов с Claude AI в месяц"}
          limit={usage.claude_runs?.limit}
        />
        <div
          style={{
            fontSize: 11,
            fontWeight: 600,
            textTransform: "uppercase",
            letterSpacing: "0.06em",
            color: "var(--fg-faint)",
            margin: "16px 0 4px",
          }}
        >
          {window.T?.quotasSectionKeywords || "Ключевые слова"}
        </div>
        <QuotaRow
          label={window.T?.quotasKwDay || "Keyword поисков в день"}
          used={usage.keywords_daily?.used}
          limit={usage.keywords_daily?.limit}
        />
        <QuotaRow
          label={window.T?.quotasKwMonth || "Keyword поисков в месяц"}
          limit={usage.keywords_monthly?.limit}
        />
        <div
          style={{
            fontSize: 11,
            fontWeight: 600,
            textTransform: "uppercase",
            letterSpacing: "0.06em",
            color: "var(--fg-faint)",
            margin: "16px 0 4px",
          }}
        >
          {window.T?.quotasSectionAccount || "Аккаунт"}
        </div>
        <QuotaRow
          label={window.T?.quotasOauth || "OAuth YouTube каналов"}
          used={usage.oauth_channels?.used}
          limit={usage.oauth_channels?.limit}
          extra={usage.oauth_channels?.extra || 0}
        />
        <QuotaRow
          label={window.T?.quotasTeamMembers || "Членов команды (доп.)"}
          limit={usage.team_members?.limit}
          extra={usage.team_members?.extra || 0}
        />
      </div>
      <div style={{ marginTop: 16 }}>
        <button
          className="btn sm"
          onClick={() =>
            window.dispatchEvent(
              new CustomEvent("navigate", { detail: "plans" }),
            )
          }
        >
          {window.T?.billingComparePlans || "Сравнить планы →"}
        </button>
      </div>
    </div>
  );
};

// ── TeamTab ────────────────────────────────────────────────────────────────
const TeamTab = ({ userId, userProfile, onGoBilling }) => {
  const [teamData, setTeamData] = React.useState(null);
  const [loading, setLoading] = React.useState(true);
  const [adding, setAdding] = React.useState(false);
  const [newName, setNewName] = React.useState("");
  const [newEmail, setNewEmail] = React.useState("");
  const [error, setError] = React.useState("");
  const [success, setSuccess] = React.useState("");

  const load = () => {
    if (!userId) return;
    setLoading(true);
    fetch(`${API_URL}/api/team?user_id=${userId}`)
      .then((r) => r.json())
      .then((d) => {
        setTeamData(d);
        setLoading(false);
      })
      .catch(() => setLoading(false));
  };

  React.useEffect(() => {
    load();
  }, [userId]);

  const handleAdd = async () => {
    if (!newEmail.trim() || !newName.trim()) {
      setError(window.T?.teamErrorNameEmail || "Введите имя и email");
      return;
    }
    setError("");
    setAdding(true);
    try {
      const resp = await fetch(`${API_URL}/api/team`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          user_id: userId,
          email: newEmail.trim(),
          name: newName.trim(),
        }),
      });
      const data = await resp.json();
      if (!resp.ok) {
        setError(data.detail || window.T?.teamErrorAdd || "Ошибка добавления");
        return;
      }
      setNewName("");
      setNewEmail("");
      setSuccess(
        (window.T?.teamInviteSent || "Приглашение отправлено на ") +
          newEmail.trim(),
      );
      setTimeout(() => setSuccess(""), 4000);
      load();
    } catch (e) {
      setError(window.T?.teamErrorNetwork || "Ошибка сети");
    } finally {
      setAdding(false);
    }
  };

  const handleRemove = async (memberId) => {
    await fetch(`${API_URL}/api/team/${memberId}?user_id=${userId}`, {
      method: "DELETE",
    });
    load();
  };

  const tier = userProfile?.subscription_tier || "free";
  const canManageTeam = ["studio", "producer", "superadmin"].includes(tier);

  if (loading)
    return (
      <div
        style={{
          padding: "32px 0",
          textAlign: "center",
          color: "var(--fg-faint)",
          fontSize: 13,
        }}
      >
        {window.T?.loading || "Загружаем…"}
      </div>
    );

  const count = teamData?.count || 0;
  const limit = teamData?.limit || 0;
  const canAdd = count < limit || tier === "superadmin";

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>
      <div className="form-card">
        <div
          style={{
            display: "flex",
            alignItems: "center",
            justifyContent: "space-between",
            marginBottom: 16,
          }}
        >
          <div>
            <h3 style={{ margin: 0 }}>
              {window.T?.teamMembersTitle || "Члены команды"}
            </h3>
            <p className="hint" style={{ margin: "4px 0 0" }}>
              {window.T?.teamMembersHint ||
                "Члены команды имеют полный доступ к данным аккаунта, кроме биллинга и управления командой."}
            </p>
          </div>
          <div style={{ textAlign: "right", flexShrink: 0 }}>
            <div
              style={{
                fontSize: 28,
                fontWeight: 700,
                color: canAdd ? "var(--fg)" : "var(--warn)",
              }}
            >
              {count} / {tier === "superadmin" ? "∞" : limit}
            </div>
            <div style={{ fontSize: 11, color: "var(--fg-faint)" }}>
              {window.T?.teamMembersCount || "членов команды"}
            </div>
          </div>
        </div>

        {count === 0 ? (
          <div
            style={{
              padding: "24px 0",
              textAlign: "center",
              color: "var(--fg-faint)",
              fontSize: 13,
            }}
          >
            {window.T?.teamEmpty || "Пока нет членов команды"}
          </div>
        ) : (
          <div style={{ marginBottom: 16 }}>
            {teamData.members.map((m) => (
              <div
                key={m.id}
                style={{
                  display: "flex",
                  alignItems: "center",
                  gap: 12,
                  padding: "10px 0",
                  borderBottom: "1px solid var(--border)",
                }}
              >
                <div
                  style={{
                    width: 32,
                    height: 32,
                    borderRadius: "50%",
                    background: "var(--accent-soft)",
                    color: "var(--accent)",
                    display: "flex",
                    alignItems: "center",
                    justifyContent: "center",
                    fontWeight: 700,
                    fontSize: 14,
                    flexShrink: 0,
                  }}
                >
                  {(m.full_name || m.email || "?")[0].toUpperCase()}
                </div>
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: 13, fontWeight: 500 }}>
                    {m.full_name || m.invited_name || "—"}
                  </div>
                  <div style={{ fontSize: 11, color: "var(--fg-faint)" }}>
                    {m.email || m.invited_email}
                  </div>
                </div>
                <span
                  className={"status " + (m.status === "active" ? "ok" : "run")}
                >
                  {m.status === "active"
                    ? window.T?.teamStatusActive || "активен"
                    : window.T?.teamStatusInvited || "приглашён"}
                </span>
                <button
                  className="btn ghost sm"
                  style={{ color: "var(--bad)" }}
                  onClick={() => handleRemove(m.member_id)}
                  title="Удалить"
                >
                  <Icon name="x" size={13} />
                </button>
              </div>
            ))}
          </div>
        )}

        {canManageTeam ? (
          canAdd ? (
            <div
              style={{
                display: "flex",
                gap: 8,
                flexWrap: "wrap",
                marginTop: 8,
              }}
            >
              <input
                className="input"
                placeholder={window.T?.teamNamePlaceholder || "Имя"}
                value={newName}
                onChange={(e) => setNewName(e.target.value)}
                style={{ flex: "1 1 140px", minWidth: 120 }}
              />
              <input
                className="input"
                placeholder="Email"
                type="email"
                value={newEmail}
                onChange={(e) => setNewEmail(e.target.value)}
                onKeyDown={(e) => e.key === "Enter" && handleAdd()}
                style={{ flex: "2 1 200px", minWidth: 160 }}
              />
              <button
                className="btn primary"
                onClick={handleAdd}
                disabled={adding}
              >
                {adding ? (
                  <>
                    <Icon name="spinner" size={13} />{" "}
                    {window.T?.teamAdding || "Добавляем…"}
                  </>
                ) : (
                  window.T?.teamAddBtn || "+ Добавить"
                )}
              </button>
            </div>
          ) : (
            <div
              style={{
                marginTop: 8,
                display: "flex",
                alignItems: "center",
                gap: 12,
                padding: "12px 14px",
                borderRadius: "var(--radius)",
                background: "var(--bg-sunk)",
                border: "1px solid var(--border)",
              }}
            >
              <div style={{ flex: 1, fontSize: 13, color: "var(--fg-muted)" }}>
                {window.T?.teamLimitReached || "Лимит членов команды исчерпан"}{" "}
                ({count}/{limit})
              </div>
              <button className="btn primary sm" onClick={onGoBilling}>
                {window.T?.teamBuySlot || "Докупить слот"} →
              </button>
            </div>
          )
        ) : (
          <div
            style={{
              marginTop: 8,
              padding: "12px 14px",
              borderRadius: "var(--radius)",
              background: "var(--bg-sunk)",
              fontSize: 13,
              color: "var(--fg-muted)",
            }}
          >
            {window.T?.teamUnavailable ||
              "Члены команды доступны на тирах Продюсер и Студия."}{" "}
            <button
              className="btn ghost sm"
              style={{ color: "var(--accent)", padding: 0 }}
              onClick={() =>
                window.dispatchEvent(
                  new CustomEvent("navigate", { detail: "plans" }),
                )
              }
            >
              {window.T?.teamChangePlan || "Сменить план"} →
            </button>
          </div>
        )}

        {error && (
          <div
            style={{
              marginTop: 10,
              fontSize: 13,
              color: "var(--bad)",
              padding: "8px 12px",
              background: "rgba(220,38,38,0.08)",
              borderRadius: 6,
            }}
          >
            {error}
          </div>
        )}
        {success && (
          <div
            style={{
              marginTop: 10,
              fontSize: 13,
              color: "var(--good)",
              padding: "8px 12px",
              background: "rgba(22,163,74,0.08)",
              borderRadius: 6,
            }}
          >
            ✓ {success}
          </div>
        )}
      </div>

      {canManageTeam && (
        <div
          className="form-card"
          style={{ display: "flex", alignItems: "center", gap: 16 }}
        >
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 13, fontWeight: 500, marginBottom: 2 }}>
              {window.T?.teamBuySlotTitle || "Докупить дополнительный слот"}
            </div>
            <div style={{ fontSize: 12, color: "var(--fg-faint)" }}>
              {window.PRODUCT_MODE === "ru"
                ? window.T?.teamBuySlotHintRu ||
                  "₽790/мес за каждого дополнительного члена команды"
                : window.T?.teamBuySlotHint ||
                  "€7.99/mo per additional team member"}
            </div>
          </div>
          <button className="btn primary sm" onClick={onGoBilling}>
            {window.T?.teamBuySlot || "Докупить"} →
          </button>
        </div>
      )}
    </div>
  );
};

// ── TeamMemberBanner ───────────────────────────────────────────────────────
const TeamMemberBanner = ({ ownerName }) => {
  if (!ownerName) return null;
  return (
    <div
      style={{
        padding: "8px 20px",
        background: "var(--accent-soft)",
        borderBottom: "1px solid var(--accent)",
        fontSize: 12,
        color: "var(--accent)",
        display: "flex",
        alignItems: "center",
        gap: 8,
      }}
    >
      <Icon name="sparkle" size={13} />
      <>
        {window.T?.teamBannerText || "Вы работаете в команде:"}{" "}
        <strong>{ownerName}</strong>
      </>
    </div>
  );
};

const ConfirmPopup = ({
  title,
  message,
  confirmLabel,
  confirmDanger,
  onConfirm,
  onCancel,
}) => (
  <div
    style={{
      position: "fixed",
      inset: 0,
      zIndex: 200,
      background: "rgba(0,0,0,0.45)",
      display: "flex",
      alignItems: "center",
      justifyContent: "center",
    }}
    onClick={(e) => {
      if (e.target === e.currentTarget) onCancel();
    }}
  >
    <div
      style={{
        background: "var(--bg)",
        border: "1px solid var(--border)",
        borderRadius: "var(--radius-lg)",
        padding: "28px 32px",
        width: 380,
        boxShadow: "var(--shadow-lg)",
      }}
    >
      <h3 style={{ margin: "0 0 8px", fontSize: 16, fontWeight: 600 }}>
        {title}
      </h3>
      <p
        style={{
          margin: "0 0 24px",
          color: "var(--fg-muted)",
          fontSize: 13,
          lineHeight: 1.5,
        }}
      >
        {message}
      </p>
      <div style={{ display: "flex", gap: 8, justifyContent: "flex-end" }}>
        <button className="btn" onClick={onCancel}>
          {window.T?.cancel || "Cancel"}
        </button>
        <button className="btn primary" onClick={onConfirm}>
          {confirmLabel}
        </button>
      </div>
    </div>
  </div>
);

// ── Results screen ─────────────────────────────────────────────────────────
const ResultsScreen = ({
  results,
  onOpen,
  density,
  userProfile,
  userId,
  selectedRunFilter,
  onRunFilterChange,
  onClearAllFilters,
  showHidden,
  onToggleHidden,
  activeChannel,
  onToast,
}) => {
  const COLUMNS_KEY = "youna_columns_v1";
  const COLUMNS_DEFAULT = {
    title: true,
    channel: true,
    published: true,
    analyzed: true,
    duration: true,
    views: true,
    likes: true,
    comments: true,
    engagement: true,
    outlier: true,
    transcript: true,
    tags: true,
  };
  const [columns, setColumns] = React.useState(() => {
    try {
      const saved = localStorage.getItem(COLUMNS_KEY);
      return saved
        ? { ...COLUMNS_DEFAULT, ...JSON.parse(saved) }
        : COLUMNS_DEFAULT;
    } catch {
      return COLUMNS_DEFAULT;
    }
  });
  const [showColMenu, setShowColMenu] = React.useState(false);
  const toggleColumn = (key) => {
    setColumns((prev) => {
      const next = { ...prev, [key]: !prev[key] };
      try {
        localStorage.setItem(COLUMNS_KEY, JSON.stringify(next));
      } catch {}
      return next;
    });
  };
  // COLUMN_LABELS — вычисляется при каждом рендере напрямую
  const _T = window.T || {};
  const COLUMN_LABELS = {
    title: _T.colTitle || "Title",
    channel: _T.colChannel || "Channel",
    published: _T.colPublished || "Published",
    analyzed: _T.colAnalyzed || "Analyzed",
    duration: _T.colDuration || "Duration",
    views: _T.colViews || "Views",
    likes: _T.colLikes || "Likes",
    comments: _T.colComments || "Comments",
    engagement: _T.colEngagement || "Engagement",
    outlier: _T.colOutlier || "Outlier",
    transcript: _T.colTranscript || "Transcript",
    tags: _T.colTags || "Tags",
  };

  const [search, setSearch] = React.useState("");
  const [channel, setChannel] = React.useState("all");
  const channelFilteredResults = React.useMemo(() => {
    if (!activeChannel) return results;
    return results.filter((r) => r.channelName === activeChannel.channel_name);
  }, [results, activeChannel]);
  const [sortBy, setSortBy] = React.useState("publishedAt");
  const [sortDir, setSortDir] = React.useState("desc");
  const [minViews, setMinViews] = React.useState(0);
  const [minEng, setMinEng] = React.useState(0);
  const [dateRange, setDateRange] = React.useState("all");
  const [dateFrom, setDateFrom] = React.useState("");
  const [dateTo, setDateTo] = React.useState("");
  const [runs, setRuns] = React.useState([]);
  const [selected, setSelected] = React.useState(new Set());
  const [confirm, setConfirm] = React.useState(null);
  const [actionLoading, setActionLoading] = React.useState(false);
  const [pageSize, setPageSize] = React.useState(50);
  const [page, setPage] = React.useState(0);

  React.useEffect(() => {
    const seen = new Map();
    results.forEach((r) => {
      if (r.runId && !seen.has(r.runId)) seen.set(r.runId, r.analyzedAt);
    });
    const sorted = [...seen.entries()].sort(
      (a, b) => new Date(b[1]) - new Date(a[1]),
    );
    setRuns(
      sorted.map(([id, date]) => ({
        id,
        label: date ? window.fmtDate(date) : id.slice(0, 8),
      })),
    );
  }, [results]);

  React.useEffect(() => {
    setPage(0);
  }, [search, channel, minViews, minEng, dateFrom, dateTo, selectedRunFilter]);

  React.useEffect(() => {
    setSelected(new Set());
    setPage(0);
  }, [showHidden]);

  const channels = ["all", ...new Set(results.map((r) => r.channelName))];
  const selectedRun = selectedRunFilter || "all";

  const handleClear = () => {
    setSearch("");
    setChannel("all");
    setDateRange("all");
    setDateFrom("");
    setDateTo("");
    setMinViews(0);
    setMinEng(0);
    setPage(0);
    if (onClearAllFilters) onClearAllFilters();
  };

  const toggleSelect = (id, e) => {
    e.stopPropagation();
    setSelected((prev) => {
      const next = new Set(prev);
      next.has(id) ? next.delete(id) : next.add(id);
      return next;
    });
  };

  const toggleSelectAll = (ids) => {
    if (ids.every((id) => selected.has(id))) {
      setSelected(new Set());
    } else {
      setSelected(new Set(ids));
    }
  };

  const executeAction = async (type) => {
    setActionLoading(true);
    const ids = [...selected];
    try {
      if (type === "delete") {
        await Promise.all(
          ids.map((id) =>
            fetch(`${API_URL}/api/results/${id}`, { method: "DELETE" }),
          ),
        );
      } else if (type === "hide") {
        await Promise.all(
          ids.map((id) =>
            fetch(`${API_URL}/api/results/${id}`, {
              method: "PATCH",
              headers: { "Content-Type": "application/json" },
              body: JSON.stringify({ hidden: true }),
            }),
          ),
        );
      } else if (type === "restore") {
        await Promise.all(
          ids.map((id) =>
            fetch(`${API_URL}/api/results/${id}`, {
              method: "PATCH",
              headers: { "Content-Type": "application/json" },
              body: JSON.stringify({ hidden: false }),
            }),
          ),
        );
      }
      setSelected(new Set());
      setConfirm(null);
      if (onClearAllFilters) onClearAllFilters();
    } catch (e) {
      console.error("Action error:", e);
    } finally {
      setActionLoading(false);
    }
  };

  let filtered = channelFilteredResults.filter((r) => {
    if (channel !== "all" && r.channelName !== channel) return false;
    if (
      search &&
      !r.title.toLowerCase().includes(search.toLowerCase()) &&
      !r.channelName.toLowerCase().includes(search.toLowerCase())
    )
      return false;
    if (r.views < minViews) return false;
    if (r.engagementPct < minEng) return false;
    if (selectedRun !== "all" && r.runId !== selectedRun) return false;
    if (
      dateRange === "7d" &&
      Date.now() - new Date(r.publishedAt).getTime() > 7 * 86400000
    )
      return false;
    if (
      dateRange === "30d" &&
      Date.now() - new Date(r.publishedAt).getTime() > 30 * 86400000
    )
      return false;
    return true;
  });

  filtered.sort((a, b) => {
    let av, bv;
    if (sortBy === "outlier") {
      av = getOutlier(a, channelAvg) ?? 0;
      bv = getOutlier(b, channelAvg) ?? 0;
    } else {
      av = a[sortBy];
      bv = b[sortBy];
    }
    let cmp =
      typeof av === "number" ? av - bv : String(av).localeCompare(String(bv));
    return sortDir === "asc" ? cmp : -cmp;
  });

  const toggleSort = (col) => {
    if (sortBy === col) setSortDir(sortDir === "asc" ? "desc" : "asc");
    else {
      setSortBy(col);
      setSortDir("desc");
    }
  };
  const SortIco = ({ col }) =>
    sortBy === col ? (
      <Icon
        name={sortDir === "asc" ? "chevron-up" : "chevron-down"}
        size={11}
        className="sort"
      />
    ) : null;

  const totalFiltered = filtered.length;
  const totalPages = Math.ceil(totalFiltered / pageSize);
  const paginatedFiltered = filtered.slice(
    page * pageSize,
    (page + 1) * pageSize,
  );

  const filteredIds = filtered.map((r) => r.id);
  const allSelected =
    filteredIds.length > 0 && filteredIds.every((id) => selected.has(id));
  const someSelected = selected.size > 0;

  const [channelAvg, setChannelAvg] = React.useState({});
  React.useEffect(() => {
    fetch(`${API_URL}/api/channels/avg-views`)
      .then((r) => r.json())
      .then((d) => setChannelAvg(d.channel_avg_views || {}))
      .catch(() => {});
  }, [results]);

  if (results.length === 0) {
    return (
      <div className="page" style={{ maxWidth: 1400 }}>
        <div
          style={{
            display: "flex",
            flexDirection: "column",
            alignItems: "center",
            justifyContent: "center",
            padding: "80px 32px",
            textAlign: "center",
            border: "1px dashed var(--border-strong)",
            borderRadius: "var(--radius-lg)",
            background: "var(--bg-elev)",
          }}
        >
          <div style={{ fontSize: 48, marginBottom: 16 }}>
            {showHidden ? "🫥" : "📊"}
          </div>
          <div style={{ fontSize: 18, fontWeight: 600, marginBottom: 8 }}>
            {showHidden
              ? window.T?.resultsNoHidden || "No hidden videos"
              : window.T?.resultsNoResults || "No results yet"}
          </div>
          <div
            style={{
              fontSize: 14,
              color: "var(--fg-muted)",
              maxWidth: 360,
              lineHeight: 1.6,
              marginBottom: 24,
            }}
          >
            {showHidden
              ? window.T?.resultsNoHiddenHint ||
                "Videos you hide will appear here."
              : window.T?.resultsNoResultsHint ||
                "Run your first analysis to see video metrics, engagement data, and AI insights from any YouTube channel."}
          </div>
          {showHidden ? (
            <button className="btn" onClick={() => onToggleHidden(false)}>
              {window.T?.resultsBackToResults || "← Back to results"}
            </button>
          ) : (
            <a
              href="#"
              onClick={(e) => {
                e.preventDefault();
                window.dispatchEvent(
                  new CustomEvent("navigate", { detail: "analysis" }),
                );
              }}
              className="btn primary lg"
            >
              <Icon name="play" size={13} />{" "}
              {window.T?.resultsStartAnalysis || "Start first analysis"}
            </a>
          )}
        </div>
      </div>
    );
  }

  return (
    <>
      <div className="page" style={{ maxWidth: 1400 }}>
        {/* ── Action bar — появляется при выборе ── */}
        {someSelected && (
          <div
            style={{
              display: "flex",
              alignItems: "center",
              gap: 12,
              padding: "10px 16px",
              marginBottom: 12,
              background: "var(--accent-soft)",
              border: "1px solid var(--accent)",
              borderRadius: "var(--radius-lg)",
            }}
          >
            <span
              style={{ fontSize: 13, fontWeight: 500, color: "var(--accent)" }}
            >
              {selected.size} {window.T?.resultsSelected || "selected"}
            </span>
            <div style={{ flex: 1 }} />
            {/* Порядок: Экспорт → Скрыть/Восстановить → Удалить → Отмена */}
            <ResultsExportMenu
              selectedIds={selected}
              userId={userId}
              onToast={onToast}
              label={window.T?.exportBtn || "Экспорт"}
            />
            {showHidden ? (
              <button
                className="btn sm"
                onClick={() => setConfirm({ type: "restore" })}
              >
                {window.T?.resultsRestore || "Restore"}
              </button>
            ) : (
              <button
                className="btn sm"
                onClick={() => setConfirm({ type: "hide" })}
              >
                <Icon name="eye" size={13} /> {window.T?.resultsHide || "Hide"}
              </button>
            )}
            <button
              className="btn sm"
              onClick={() => setConfirm({ type: "delete" })}
            >
              <Icon name="trash" size={13} />{" "}
              {window.T?.resultsDelete || "Delete"}
            </button>
            <button className="btn sm" onClick={() => setSelected(new Set())}>
              ✕ {window.T?.resultsClearSelection || "Clear"}
            </button>
          </div>
        )}

        <div className="table-wrap">
          <div className="table-toolbar">
            {(() => {
              const channelNames = [
                "all",
                ...new Set(results.map((r) => r.channelName)),
              ];
              if (channelNames.length <= 2) return null;
              return (
                <select
                  className="select"
                  value={channel}
                  onChange={(e) => setChannel(e.target.value)}
                  style={{ height: 30, fontSize: 12, width: 180 }}
                >
                  <option value="all">
                    {window.T?.resultsAllChannels || "Все каналы"}
                  </option>
                  {channelNames
                    .filter((c) => c !== "all")
                    .map((c) => (
                      <option key={c} value={c}>
                        {c}
                      </option>
                    ))}
                </select>
              );
            })()}

            <span className="pill">
              {window.T?.resultsMinViews || "Min views"}{" "}
              <input
                type="number"
                value={minViews || ""}
                onChange={(e) => setMinViews(+e.target.value || 0)}
                placeholder="0"
              />
            </span>
            <span className="pill">
              {window.T?.resultsMinEng || "Min eng %"}{" "}
              <input
                type="number"
                value={minEng || ""}
                onChange={(e) => setMinEng(+e.target.value || 0)}
                placeholder="0"
              />
            </span>
            {/* Фильтр даты анализа ОТ/ДО */}
            <div style={{ display: "flex", alignItems: "center", gap: 4 }}>
              <span
                style={{
                  fontSize: 12,
                  color: "var(--fg-muted)",
                  whiteSpace: "nowrap",
                }}
              >
                {window.T?.resultsAnalysedFilter || "Analysed"}:
              </span>
              <input
                type="date"
                value={dateFrom}
                onChange={(e) => setDateFrom(e.target.value)}
                style={{
                  height: 30,
                  fontSize: 12,
                  padding: "0 6px",
                  border: "1px solid var(--border-strong)",
                  borderRadius: "var(--radius)",
                  background: "var(--bg)",
                  color: "var(--fg)",
                  width: 130,
                }}
                title={window.T?.resultsDateFrom || "From"}
              />
              <span style={{ fontSize: 12, color: "var(--fg-muted)" }}>–</span>
              <input
                type="date"
                value={dateTo}
                onChange={(e) => setDateTo(e.target.value)}
                style={{
                  height: 30,
                  fontSize: 12,
                  padding: "0 6px",
                  border: "1px solid var(--border-strong)",
                  borderRadius: "var(--radius)",
                  background: "var(--bg)",
                  color: "var(--fg)",
                  width: 130,
                }}
                title={window.T?.resultsDateTo || "To"}
              />
            </div>
            <div style={{ flex: 1 }} />
            {/* Hidden кнопка */}
            <button
              className={"btn" + (showHidden ? " primary" : "")}
              style={{ height: 30 }}
              onClick={() => onToggleHidden(!showHidden)}
              title={
                showHidden
                  ? window.T?.resultsActive || "Active"
                  : window.T?.resultsHidden || "Hidden"
              }
            >
              <Icon name="eye" size={13} />
              {showHidden
                ? window.T?.resultsActive || "Active"
                : window.T?.resultsHidden || "Hidden"}
            </button>
            <div style={{ position: "relative" }}>
              <button
                className={"btn" + (showColMenu ? " primary" : "")}
                style={{ height: 30 }}
                onClick={() => setShowColMenu((v) => !v)}
              >
                {window.T?.resultsColumns || "Columns"}
                {Object.values(columns).some((v) => !v)
                  ? ` (${Object.values(columns).filter(Boolean).length}/${Object.keys(columns).length})`
                  : ""}
              </button>
              {showColMenu && (
                <div
                  ref={(el) => {
                    if (el) {
                      const handler = (e) => {
                        if (
                          !el.contains(e.target) &&
                          !e.target.closest(".btn")
                        ) {
                          setShowColMenu(false);
                          document.removeEventListener("mousedown", handler);
                        }
                      };
                      setTimeout(
                        () => document.addEventListener("mousedown", handler),
                        0,
                      );
                      const rect = el.parentElement?.getBoundingClientRect?.();
                      if (rect) {
                        el.style.top = rect.bottom + 6 + "px";
                        el.style.left = Math.max(8, rect.right - 180) + "px";
                      }
                    }
                  }}
                  style={{
                    position: "fixed",
                    background: "var(--bg)",
                    border: "1px solid var(--border-strong)",
                    borderRadius: "var(--radius-lg)",
                    boxShadow: "var(--shadow-lg)",
                    padding: "8px 0",
                    zIndex: 200,
                    minWidth: 180,
                    maxHeight: "80vh",
                    overflowY: "auto",
                  }}
                >
                  {Object.entries(COLUMN_LABELS).map(([key, label]) => (
                    <label
                      key={key}
                      style={{
                        display: "flex",
                        alignItems: "center",
                        gap: 8,
                        padding: "6px 14px",
                        fontSize: 13,
                        cursor: "pointer",
                        userSelect: "none",
                      }}
                      onClick={() => toggleColumn(key)}
                    >
                      <input
                        type="checkbox"
                        checked={!!columns[key]}
                        onChange={() => {}}
                        style={{ cursor: "pointer" }}
                      />
                      {label}
                    </label>
                  ))}
                  <div
                    style={{
                      borderTop: "1px solid var(--border)",
                      margin: "6px 0",
                    }}
                  />
                  <button
                    className="btn ghost sm"
                    style={{
                      width: "100%",
                      justifyContent: "center",
                      fontSize: 12,
                    }}
                    onClick={() => {
                      setColumns(COLUMNS_DEFAULT);
                      try {
                        localStorage.setItem(
                          COLUMNS_KEY,
                          JSON.stringify(COLUMNS_DEFAULT),
                        );
                      } catch {}
                    }}
                  >
                    {window.T?.resultsResetColumns || "Reset to default"}
                  </button>
                </div>
              )}
            </div>
            <button
              className="btn"
              style={{ height: 30 }}
              onClick={handleClear}
            >
              {window.T?.resultsClearFilters || "Clear filters"}
            </button>
            <div
              style={{
                display: "flex",
                alignItems: "center",
                gap: 6,
                fontSize: 12,
                color: "var(--fg-muted)",
              }}
            >
              <span>
                {window.PRODUCT_MODE === "ru" ? "На странице:" : "Per page:"}
              </span>
              <div className="segmented">
                {[25, 50, 100].map((n) => (
                  <button
                    key={n}
                    className={pageSize === n ? "active" : ""}
                    onClick={() => {
                      setPageSize(n);
                      setPage(0);
                    }}
                  >
                    {n}
                  </button>
                ))}
              </div>
            </div>
          </div>

          <div className="table-scroll">
            {filtered.length === 0 ? (
              <div
                style={{
                  padding: "60px 32px",
                  textAlign: "center",
                  color: "var(--fg-muted)",
                }}
              >
                <div style={{ fontSize: 32, marginBottom: 12 }}>🔍</div>
                <div style={{ fontSize: 15, fontWeight: 500, marginBottom: 6 }}>
                  {window.T?.resultsNoVideos || "No videos match your filters"}
                </div>
                <div style={{ fontSize: 13, color: "var(--fg-faint)" }}>
                  {window.T?.resultsNoVideosHint ||
                    "Try adjusting the search query or filters above."}
                </div>
              </div>
            ) : (
              <table className="data">
                <thead>
                  <tr>
                    <th
                      style={{ width: 40, padding: "0 8px 0 14px" }}
                      onClick={(e) => e.stopPropagation()}
                    >
                      <input
                        type="checkbox"
                        checked={allSelected}
                        onChange={() => toggleSelectAll(filteredIds)}
                        style={{ cursor: "pointer", width: 14, height: 14 }}
                      />
                    </th>
                    {columns.title && (
                      <th
                        onClick={() => toggleSort("title")}
                        style={{ minWidth: 320 }}
                      >
                        {COLUMN_LABELS.title} <SortIco col="title" />
                      </th>
                    )}
                    {columns.channel && (
                      <th onClick={() => toggleSort("channelName")}>
                        {COLUMN_LABELS.channel} <SortIco col="channelName" />
                      </th>
                    )}
                    {columns.published && (
                      <th onClick={() => toggleSort("publishedAt")}>
                        {COLUMN_LABELS.published} <SortIco col="publishedAt" />
                      </th>
                    )}
                    {columns.analyzed && (
                      <th onClick={() => toggleSort("analyzedAt")}>
                        {COLUMN_LABELS.analyzed} <SortIco col="analyzedAt" />
                      </th>
                    )}
                    {columns.duration && (
                      <th
                        className="num"
                        onClick={() => toggleSort("durationSec")}
                      >
                        {COLUMN_LABELS.duration} <SortIco col="durationSec" />
                      </th>
                    )}
                    {columns.views && (
                      <th className="num" onClick={() => toggleSort("views")}>
                        {COLUMN_LABELS.views}
                      </th>
                    )}
                    {columns.likes && (
                      <th className="num" onClick={() => toggleSort("likes")}>
                        {COLUMN_LABELS.likes} <SortIco col="likes" />
                      </th>
                    )}
                    {columns.comments && (
                      <th
                        className="num"
                        onClick={() => toggleSort("commentsCount")}
                      >
                        {COLUMN_LABELS.comments} <SortIco col="commentsCount" />
                      </th>
                    )}
                    {columns.engagement && (
                      <th onClick={() => toggleSort("engagementPct")}>
                        {COLUMN_LABELS.engagement}{" "}
                        <SortIco col="engagementPct" />
                      </th>
                    )}
                    {columns.outlier && (
                      <th onClick={() => toggleSort("outlier")}>
                        {COLUMN_LABELS.outlier} <SortIco col="outlier" />
                      </th>
                    )}
                    {columns.transcript && (
                      <th style={{ minWidth: 200 }}>
                        {COLUMN_LABELS.transcript}
                      </th>
                    )}
                    {columns.tags && <th>{COLUMN_LABELS.tags}</th>}
                  </tr>
                </thead>
                <tbody>
                  {paginatedFiltered.map((r) => (
                    <tr
                      key={r.id}
                      onClick={() => onOpen(r)}
                      style={
                        selected.has(r.id)
                          ? { background: "var(--accent-soft)" }
                          : {}
                      }
                    >
                      <td
                        style={{ padding: "0 8px 0 14px" }}
                        onClick={(e) => toggleSelect(r.id, e)}
                      >
                        <input
                          type="checkbox"
                          checked={selected.has(r.id)}
                          onChange={() => {}}
                          style={{ cursor: "pointer", width: 14, height: 14 }}
                        />
                      </td>
                      {columns.title && (
                        <td style={{ padding: "8px 14px" }}>
                          <div
                            style={{
                              display: "flex",
                              alignItems: "center",
                              gap: 10,
                            }}
                          >
                            {getThumbnail(r.url) ? (
                              <img
                                src={getThumbnail(r.url)}
                                alt=""
                                loading="lazy"
                                style={{
                                  width: 125,
                                  height: 70,
                                  borderRadius: 4,
                                  objectFit: "cover",
                                  flexShrink: 0,
                                  background: "var(--bg-sunk)",
                                }}
                              />
                            ) : (
                              <div
                                style={{
                                  width: 125,
                                  height: 70,
                                  borderRadius: 4,
                                  background: "var(--bg-sunk)",
                                  flexShrink: 0,
                                }}
                              />
                            )}
                            <span
                              style={{
                                fontSize: 12,
                                fontWeight: 500,
                                lineHeight: 1.4,
                                wordBreak: "break-word",
                              }}
                            >
                              {r.title}
                            </span>
                          </div>
                        </td>
                      )}
                      {columns.channel && (
                        <td>
                          <span
                            style={{
                              color: "var(--fg-muted)",
                              display: "block",
                              maxWidth: 120,
                              overflow: "hidden",
                              textOverflow: "ellipsis",
                              whiteSpace: "nowrap",
                            }}
                          >
                            {r.channelName}
                          </span>
                        </td>
                      )}
                      {columns.published && (
                        <td className="num" style={{ textAlign: "left" }}>
                          {window.fmtDate(r.publishedAt)}
                        </td>
                      )}
                      {columns.analyzed && (
                        <td className="num" style={{ textAlign: "left" }}>
                          {r.analyzedAt ? window.fmtDate(r.analyzedAt) : "—"}
                        </td>
                      )}
                      {columns.duration && (
                        <td
                          className="num"
                          style={{
                            fontFamily: "var(--mono)",
                            fontSize: 12,
                            color: "var(--fg-muted)",
                          }}
                        >
                          {r.durationSec
                            ? window.fmtDuration(r.durationSec)
                            : "—"}
                        </td>
                      )}
                      {columns.views && (
                        <td className="num">{window.fmtNum(r.views)}</td>
                      )}
                      {columns.likes && (
                        <td className="num">{window.fmtNum(r.likes)}</td>
                      )}
                      {columns.comments && (
                        <td className="num">
                          {window.fmtNum(r.commentsCount)}
                        </td>
                      )}
                      {columns.engagement && (
                        <td>
                          <span className="engagement-bar">
                            <span className="bar">
                              <span
                                className="fill"
                                style={{
                                  width:
                                    Math.min(100, r.engagementPct * 12) + "%",
                                }}
                              />
                            </span>
                            {r.engagementPct.toFixed(2)}%
                          </span>
                        </td>
                      )}
                      {columns.outlier && (
                        <td>
                          <OutlierBadge score={getOutlier(r, channelAvg)} />
                        </td>
                      )}
                      {columns.transcript && (
                        <td style={{ maxWidth: 240 }}>
                          {r.transcript ? (
                            <span
                              style={{
                                fontSize: 12,
                                color: "var(--fg-muted)",
                                lineHeight: 1.5,
                                display: "-webkit-box",
                                WebkitLineClamp: 3,
                                WebkitBoxOrient: "vertical",
                                overflow: "hidden",
                              }}
                            >
                              {r.transcript.slice(0, 400)}
                            </span>
                          ) : (
                            <span style={{ color: "var(--fg-faint)" }}>—</span>
                          )}
                        </td>
                      )}
                      {columns.tags && (
                        <td>
                          <span className="tag-list">
                            {r.tags.slice(0, 2).map((t) => (
                              <span key={t} className="chip">
                                {t}
                              </span>
                            ))}
                            {r.tags.length > 2 && (
                              <span className="chip">+{r.tags.length - 2}</span>
                            )}
                          </span>
                        </td>
                      )}
                    </tr>
                  ))}
                </tbody>
              </table>
            )}
          </div>

          {/* Пагинация */}
          {totalPages > 1 && (
            <div
              style={{
                display: "flex",
                alignItems: "center",
                justifyContent: "space-between",
                padding: "12px 16px",
                borderTop: "1px solid var(--border)",
                fontSize: 13,
              }}
            >
              <span style={{ color: "var(--fg-muted)" }}>
                {page * pageSize + 1}–
                {Math.min((page + 1) * pageSize, totalFiltered)}{" "}
                {window.PRODUCT_MODE === "ru" ? "из" : "of"} {totalFiltered}
              </span>
              <div style={{ display: "flex", gap: 6 }}>
                <button
                  className="btn sm"
                  disabled={page === 0}
                  onClick={() => setPage((p) => p - 1)}
                >
                  <Icon name="chevron-left" size={13} />
                </button>
                {Array.from({ length: Math.min(totalPages, 7) }, (_, i) => {
                  const p =
                    totalPages <= 7
                      ? i
                      : page < 4
                        ? i
                        : page > totalPages - 4
                          ? totalPages - 7 + i
                          : page - 3 + i;
                  return (
                    <button
                      key={p}
                      className={"btn sm" + (p === page ? " primary" : "")}
                      onClick={() => setPage(p)}
                    >
                      {p + 1}
                    </button>
                  );
                })}
                <button
                  className="btn sm"
                  disabled={page >= totalPages - 1}
                  onClick={() => setPage((p) => p + 1)}
                >
                  <Icon name="chevron-right" size={13} />
                </button>
              </div>
            </div>
          )}
        </div>
      </div>

      {confirm && (
        <ConfirmPopup
          title={(() => {
            const n = selected.size;
            const videos =
              window.PRODUCT_MODE === "ru"
                ? `${n} ${n === 1 ? "видео" : "видео"}`
                : `${n} video${n > 1 ? "s" : ""}`;
            if (confirm.type === "delete")
              return `${window.T?.resultsDelete || "Delete"} ${videos}?`;
            if (confirm.type === "hide")
              return `${window.T?.resultsHide || "Hide"} ${videos}?`;
            return `${window.T?.resultsRestore || "Restore"} ${videos}?`;
          })()}
          message={
            confirm.type === "delete"
              ? window.PRODUCT_MODE === "ru"
                ? "Выбранные видео будут удалены из базы данных. Это действие нельзя отменить."
                : "This will permanently remove the selected videos from the database. This action cannot be undone."
              : confirm.type === "hide"
                ? window.PRODUCT_MODE === "ru"
                  ? "Выбранные видео будут скрыты. Вы можете восстановить их в любой момент."
                  : "Selected videos will be hidden from Results. You can restore them anytime from the Hidden view."
                : window.PRODUCT_MODE === "ru"
                  ? "Выбранные видео будут возвращены в активный список результатов."
                  : "Selected videos will be moved back to the active Results list."
          }
          confirmLabel={
            actionLoading
              ? window.PRODUCT_MODE === "ru"
                ? "Обрабатываем…"
                : "Processing…"
              : confirm.type === "delete"
                ? window.T?.resultsDelete || "Delete"
                : confirm.type === "hide"
                  ? window.T?.resultsHide || "Hide"
                  : window.T?.resultsRestore || "Restore"
          }
          confirmDanger={confirm.type === "delete"}
          onConfirm={() => executeAction(confirm.type)}
          onCancel={() => setConfirm(null)}
        />
      )}
    </>
  );
};

// ── Detail overlay ─────────────────────────────────────────────────────────
const DetailOverlay = ({
  video,
  allResults = [],
  onClose,
  onPrev,
  onNext,
  userId,
}) => {
  const [comments, setComments] = React.useState([]);
  const [commentsLoading, setCommentsLoading] = React.useState(true);
  const [commentPrefs, setCommentPrefs] = React.useState({});
  const [aiAnalysis, setAiAnalysis] = React.useState({
    summary: "",
    categories: [],
    openQuestions: [],
  });

  const channelAvg = React.useMemo(
    () => computeOutliers(allResults),
    [allResults],
  );
  const outlierScore = getOutlier(video, channelAvg);

  React.useEffect(() => {
    const onKey = (e) => {
      if (e.key === "Escape") onClose();
      if (e.key === "ArrowLeft") onPrev();
      if (e.key === "ArrowRight") onNext();
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [onClose, onPrev, onNext]);

  React.useEffect(() => {
    if (!video?.id) return;
    setComments([]);
    setCommentsLoading(true);
    setCommentPrefs({});
    fetch(`${API_URL}/api/results/${video.id}/comments`)
      .then((r) => r.json())
      .then((json) => {
        const sorted = (json.comments || []).sort(
          (a, b) => (b.likes || 0) - (a.likes || 0),
        );
        setComments(sorted);
        setCommentsLoading(false);
        // Читаем AI-анализ из первого комментария (хранится на каждом)
        const first = json.comments?.[0];
        if (first?.summary || first?.categories) {
          setAiAnalysis({
            summary: first.summary || "",
            categories: first.categories
              ? first.categories
                  .split(",")
                  .map((s) => s.trim())
                  .filter(Boolean)
              : [],
            openQuestions:
              first.open_questions &&
              first.open_questions !== "нет" &&
              first.open_questions !== "—"
                ? first.open_questions
                    .split(";")
                    .map((s) => s.trim())
                    .filter(Boolean)
                : [],
          });
        }
        if (userId && sorted.length > 0) {
          fetch(`${API_URL}/api/comments?user_id=${userId}&limit=500&offset=0`)
            .then((r) => r.json())
            .then((d) => {
              const map = {};
              (d.comments || []).forEach((c) => {
                map[c.id] = {
                  is_favorite: c.is_favorite,
                  is_hidden: c.is_hidden,
                };
              });
              setCommentPrefs(map);
            })
            .catch(() => {});
        }
      })
      .catch(() => setCommentsLoading(false));
  }, [video?.id]);

  const setPreference = async (commentId, update) => {
    if (!userId) return;
    await fetch(`${API_URL}/api/comments/preferences`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        user_id: userId,
        comment_id: commentId,
        ...update,
      }),
    });
    setCommentPrefs((prev) => ({
      ...prev,
      [commentId]: { ...(prev[commentId] || {}), ...update },
    }));
  };

  return (
    <div className="detail-overlay">
      <div className="detail-topbar">
        <button className="btn ghost sm" onClick={onClose}>
          <Icon name="arrow-left" size={13} />{" "}
          {window.T?.detailBack || "← Back to results"}
        </button>
        <div style={{ flex: 1 }} />
        <span className="chip">{video.channelName}</span>
        <span className="help">{window.fmtDate(video.publishedAt)}</span>
        <div style={{ display: "flex", gap: 4 }}>
          <button
            className="btn ghost sm"
            onClick={onPrev}
            title="Previous (←)"
          >
            <Icon name="chevron-left" size={14} />
          </button>
          <button className="btn ghost sm" onClick={onNext} title="Next (→)">
            <Icon name="chevron-right" size={14} />
          </button>
        </div>
        <button className="btn ghost sm" onClick={onClose}>
          <Icon name="x" size={13} />
        </button>
      </div>
      <div className="detail-body">
        <div className="detail-grid">
          <div style={{ position: "sticky", top: 24, alignSelf: "flex-start" }}>
            <div
              style={{
                position: "relative",
                aspectRatio: "16/9",
                borderRadius: "var(--radius-lg)",
                overflow: "hidden",
                marginBottom: 18,
                background: "#000",
              }}
            >
              {video.url ? (
                <iframe
                  src={`https://www.youtube.com/embed/${new URLSearchParams(new URL(video.url).search).get("v")}?rel=0&modestbranding=1`}
                  title={video.title}
                  allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
                  allowFullScreen
                  style={{
                    position: "absolute",
                    inset: 0,
                    width: "100%",
                    height: "100%",
                    border: "none",
                  }}
                />
              ) : (
                <div
                  className="video-thumb"
                  style={{ position: "absolute", inset: 0 }}
                >
                  <div className="play">
                    <Icon name="play" size={22} />
                  </div>
                </div>
              )}
            </div>
            <h1
              style={{
                margin: "0 0 6px",
                fontSize: 22,
                fontWeight: 600,
                letterSpacing: "-0.02em",
              }}
            >
              {video.title}
            </h1>
            <div
              style={{
                display: "flex",
                gap: 10,
                alignItems: "center",
                color: "var(--fg-muted)",
                fontSize: 13,
                marginBottom: 18,
              }}
            >
              <Icon name="youtube" size={16} style={{ color: "#ff0033" }} />
              <span>{video.channelName}</span>
              <span>·</span>
              <span>
                {window.fmtNum(video.subscribers)}{" "}
                {window.T?.detailSubs || "subs"}
              </span>
              <a
                href={video.url}
                target="_blank"
                style={{ marginLeft: "auto" }}
              >
                {window.T?.detailOpenYT || "Open on YouTube ↗"}
              </a>
            </div>
            <div
              className="kpi-grid"
              style={{ gridTemplateColumns: "repeat(5,1fr)", marginBottom: 24 }}
            >
              <div className="kpi">
                <div className="label">{window.T?.colViews || "Views"}</div>
                <div className="value">{window.fmtNum(video.views)}</div>
              </div>
              <div className="kpi">
                <div className="label">{window.T?.colLikes || "Likes"}</div>
                <div className="value">{window.fmtNum(video.likes)}</div>
              </div>
              <div className="kpi">
                <div className="label">
                  {window.T?.colComments || "Comments"}
                </div>
                <div className="value">
                  {window.fmtNum(video.commentsCount)}
                </div>
              </div>
              <div className="kpi">
                <div className="label">
                  {window.T?.colEngagement || "Engagement"}
                </div>
                <div className="value">{video.engagementPct.toFixed(2)}%</div>
              </div>
              <div className="kpi">
                <div className="label">{window.T?.colOutlier || "Outlier"}</div>
                <div className="value" style={{ fontSize: 16 }}>
                  <OutlierBadge score={outlierScore} />
                </div>
              </div>
            </div>
            <h4 className="section-title">{window.T?.detailTags || "Tags"}</h4>
            <div
              style={{
                display: "flex",
                gap: 4,
                flexWrap: "wrap",
                marginBottom: 24,
              }}
            >
              {video.tags.map((t) => (
                <span key={t} className="chip">
                  #{t}
                </span>
              ))}
            </div>
            <h4 className="section-title">
              {window.T?.detailTranscript || "Transcript"}
            </h4>
            <TranscriptBlock transcript={video.transcript} />
          </div>

          <div>
            <div className="summary-card" style={{ marginBottom: 20 }}>
              <div className="head">
                <span className="ai-mark">✦</span>{" "}
                {window.T?.detailSummary || "Claude summary"}
              </div>
              <div className="body">
                {aiAnalysis.summary ||
                  window.T?.detailNoSummary ||
                  "AI анализ не запускался для этого видео."}
              </div>
              {aiAnalysis.categories.length > 0 && (
                <div
                  style={{
                    display: "flex",
                    flexWrap: "wrap",
                    gap: 6,
                    marginTop: 10,
                  }}
                >
                  {aiAnalysis.categories.map((cat, i) => (
                    <span
                      key={i}
                      style={{
                        padding: "2px 10px",
                        borderRadius: 100,
                        background: "var(--accent-soft)",
                        border: "1px solid rgba(79,124,255,0.2)",
                        fontSize: 12,
                        color: "var(--accent)",
                      }}
                    >
                      {cat}
                    </span>
                  ))}
                </div>
              )}
            </div>
            <h4 className="section-title">
              {window.T?.detailOpenQuestions || "Open questions from comments"}
            </h4>
            <div style={{ marginBottom: 24 }}>
              {(aiAnalysis.openQuestions || []).map((q, i) => (
                <div
                  key={i}
                  style={{
                    display: "flex",
                    gap: 8,
                    padding: "8px 0",
                    borderBottom: "1px solid var(--border)",
                    fontSize: 13.5,
                  }}
                >
                  <span
                    style={{
                      color: "var(--fg-faint)",
                      fontFamily: "var(--mono)",
                      fontSize: 12,
                      minWidth: 18,
                    }}
                  >
                    0{i + 1}
                  </span>
                  <span>{q}</span>
                </div>
              ))}
            </div>
            <h4 className="section-title">
              {window.T?.detailTopComments || "Top comments"} ·{" "}
              {commentsLoading ? "…" : comments.length}{" "}
              {window.T?.detailOf || "of"} {window.fmtNum(video.commentsCount)}
            </h4>
            <div>
              {commentsLoading ? (
                <div
                  style={{
                    padding: "24px 0",
                    textAlign: "center",
                    color: "var(--fg-faint)",
                    fontSize: 13,
                  }}
                >
                  {window.T?.detailLoadingComments || "Loading comments…"}
                </div>
              ) : comments.length === 0 ? (
                <div
                  style={{
                    padding: "24px 0",
                    textAlign: "center",
                    color: "var(--fg-faint)",
                    fontSize: 13,
                  }}
                >
                  {window.T?.detailNoComments || "No comments available"}
                </div>
              ) : (
                comments.map((c, i) => {
                  const pref = commentPrefs[c.id] || {};
                  if (pref.is_hidden) return null;
                  return (
                    <div className="comment" key={i}>
                      <div className="head">
                        <span className="author">{c.author}</span>
                        <span className="likes">
                          <Icon name="thumbs-up" size={11} /> {c.likes}
                        </span>
                        {userId && (
                          <div
                            style={{
                              marginLeft: "auto",
                              display: "flex",
                              gap: 4,
                            }}
                          >
                            <button
                              className="btn ghost sm"
                              title={
                                pref.is_favorite
                                  ? window.T?.detailRemoveFavorite ||
                                    "Remove from favorites"
                                  : window.T?.detailAddFavorite ||
                                    "Add to favorites"
                              }
                              style={{
                                color: pref.is_favorite
                                  ? "var(--warn)"
                                  : "var(--fg-faint)",
                                fontSize: 13,
                                padding: "0 4px",
                              }}
                              onClick={() =>
                                setPreference(c.id, {
                                  is_favorite: !pref.is_favorite,
                                })
                              }
                            >
                              {pref.is_favorite ? "★" : "☆"}
                            </button>
                            <button
                              className="btn ghost sm"
                              title={
                                window.T?.detailHideComment || "Hide comment"
                              }
                              style={{
                                color: "var(--fg-faint)",
                                padding: "0 4px",
                              }}
                              onClick={() =>
                                setPreference(c.id, { is_hidden: true })
                              }
                            >
                              <Icon name="eye" size={12} />
                            </button>
                          </div>
                        )}
                      </div>
                      <div className="text" style={{ whiteSpace: "pre-wrap" }}>
                        {decodeHtml(c.text)}
                      </div>
                    </div>
                  );
                })
              )}
            </div>
          </div>
        </div>
      </div>
    </div>
  );
};

// ── Settings screen ────────────────────────────────────────────────────────
const SettingsScreen = ({ tweaks, setTweak, userId, userProfile }) => {
  const [tab, setTab] = React.useState("account");
  const [profileName, setProfileName] = React.useState("");
  const [profileEmail, setProfileEmail] = React.useState("");
  const [saving, setSaving] = React.useState(false);
  const [saved, setSaved] = React.useState(false);
  const [saveError, setSaveError] = React.useState("");
  const [resetLoading, setResetLoading] = React.useState(false);
  const [resetSent, setResetSent] = React.useState(false);
  const [signOutLoading, setSignOutLoading] = React.useState(false);

  React.useEffect(() => {
    if (userProfile) setProfileName(userProfile.full_name || "");
    window.supabaseClient.auth.getUser().then(({ data: { user } }) => {
      if (user) setProfileEmail(user.email || "");
    });
  }, [userProfile]);

  const saveProfile = async () => {
    if (!userId) return;
    setSaving(true);
    setSaveError("");
    try {
      const resp = await fetch(`${API_URL}/api/profile`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ user_id: userId, full_name: profileName }),
      });
      if (!resp.ok) throw new Error(`${resp.status}`);
      setSaved(true);
      setTimeout(() => setSaved(false), 2500);
    } catch (e) {
      setSaveError(
        window.T?.settingsSaveError ||
          "Не удалось сохранить. Попробуйте ещё раз.",
      );
    } finally {
      setSaving(false);
    }
  };

  const changePassword = async () => {
    setResetLoading(true);
    try {
      await window.supabaseClient.auth.resetPasswordForEmail(profileEmail, {
        redirectTo: window.location.origin + "?reset=1",
      });
      setResetSent(true);
    } catch (e) {
      console.error(e);
    } finally {
      setResetLoading(false);
    }
  };

  const handleSignOut = async () => {
    setSignOutLoading(true);
    await window.supabaseClient.auth.signOut();
  };

  const tabs = [
    { id: "account", label: window.T?.settingsTabAccount || "Account" },
    {
      id: "preferences",
      label: window.T?.settingsTabPreferences || "Preferences",
    },
    { id: "channels", label: window.T?.settingsTabChannels || "Channels" },
    { id: "team", label: window.T?.settingsTabTeam || "Team" },
    { id: "billing", label: window.T?.settingsTabBilling || "Billing" },
    { id: "quotas", label: window.T?.settingsTabQuotas || "Quotas" },
    { id: "api", label: window.T?.settingsTabApi || "API Keys" },
  ];

  const tier = userProfile?.subscription_tier || "free";
  const tierLabel =
    {
      free: "Free",
      start: "Start",
      pro: "Pro",
      agency: "Agency",
      superadmin: "Superadmin",
    }[tier] || tier;
  const initial = (profileName || profileEmail || "?")[0].toUpperCase();

  return (
    <div className="page" style={{ maxWidth: 880 }}>
      <div
        style={{ display: "grid", gridTemplateColumns: "180px 1fr", gap: 32 }}
      >
        <nav style={{ display: "flex", flexDirection: "column", gap: 2 }}>
          {tabs.map((t) => (
            <button
              key={t.id}
              className={"nav-item" + (tab === t.id ? " active" : "")}
              onClick={() => setTab(t.id)}
            >
              {t.label}
            </button>
          ))}
        </nav>
        <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>
          {tab === "account" && (
            <>
              <div className="form-card">
                <h3>{window.T?.settingsProfile || "Profile"}</h3>
                <p className="hint">
                  {window.T?.settingsProfileHint ||
                    "Your display name shown in the sidebar and across the app."}
                </p>
                <div
                  style={{
                    display: "flex",
                    alignItems: "center",
                    gap: 14,
                    marginBottom: 20,
                  }}
                >
                  <span
                    style={{
                      width: 48,
                      height: 48,
                      borderRadius: "50%",
                      flexShrink: 0,
                      background:
                        "linear-gradient(135deg, var(--accent), color-mix(in oklch, var(--accent), white 40%))",
                      color: "white",
                      fontWeight: 700,
                      fontSize: 20,
                      display: "inline-flex",
                      alignItems: "center",
                      justifyContent: "center",
                    }}
                  >
                    {initial}
                  </span>
                  <div>
                    <div style={{ fontWeight: 600, fontSize: 14 }}>
                      {profileName || profileEmail?.split("@")[0] || "—"}
                    </div>
                    <div
                      style={{
                        fontSize: 12,
                        color: "var(--fg-faint)",
                        marginBottom: 4,
                      }}
                    >
                      {profileEmail}
                    </div>
                    <span className="chip accent">{tierLabel}</span>
                  </div>
                </div>

                <div className="field" style={{ marginBottom: 12 }}>
                  <label>
                    {window.T?.settingsDisplayName || "Display name"}
                  </label>
                  <input
                    className="input"
                    value={profileName}
                    onChange={(e) => setProfileName(e.target.value)}
                    placeholder={
                      window.T?.settingsDisplayNamePlaceholder || "Your name"
                    }
                    onKeyDown={(e) => {
                      if (e.key === "Enter") saveProfile();
                    }}
                    style={{ maxWidth: 320 }}
                  />
                </div>
                <div className="field" style={{ marginBottom: 20 }}>
                  <label>{window.T?.settingsEmail || "Email"}</label>
                  <input
                    className="input"
                    value={profileEmail}
                    disabled
                    style={{
                      maxWidth: 320,
                      opacity: 0.6,
                      cursor: "not-allowed",
                    }}
                  />
                  <span className="help" style={{ marginTop: 4 }}>
                    {window.T?.settingsEmailHint ||
                      "Для смены email обратитесь в поддержку"}
                  </span>
                </div>

                {saveError && (
                  <div
                    style={{
                      fontSize: 13,
                      color: "var(--bad)",
                      marginBottom: 12,
                      padding: "8px 12px",
                      background: "rgba(220,38,38,0.08)",
                      borderRadius: 6,
                    }}
                  >
                    {saveError}
                  </div>
                )}
                <button
                  className="btn primary"
                  onClick={saveProfile}
                  disabled={saving}
                >
                  {saving ? (
                    <>
                      <Icon name="spinner" size={13} />{" "}
                      {window.T?.settingsSaving || "Saving…"}
                    </>
                  ) : saved ? (
                    <>
                      <Icon name="check" size={13} />{" "}
                      {window.T?.settingsSaved || "Saved"}
                    </>
                  ) : (
                    window.T?.settingsSaveChanges || "Save changes"
                  )}
                </button>
              </div>

              <div className="form-card">
                <h3>{window.T?.settingsPassword || "Password"}</h3>
                <p className="hint">
                  {window.T?.settingsPasswordHint ||
                    "Send a password reset link to your email address."}
                </p>
                {resetSent ? (
                  <div
                    style={{
                      padding: "12px 16px",
                      borderRadius: "var(--radius)",
                      background: "rgba(22,163,74,0.08)",
                      color: "var(--good)",
                      fontSize: 13,
                    }}
                  >
                    ✓ {window.T?.settingsResetSent || "Reset link sent to"}{" "}
                    {profileEmail}
                  </div>
                ) : (
                  <button
                    className="btn"
                    onClick={changePassword}
                    disabled={resetLoading}
                  >
                    {resetLoading ? (
                      <>
                        <Icon name="spinner" size={13} />{" "}
                        {window.T?.settingsSending || "Sending…"}
                      </>
                    ) : (
                      window.T?.settingsSendReset || "Send reset link"
                    )}
                  </button>
                )}
              </div>

              <div className="form-card">
                <h3>{window.T?.settingsSignOut || "Sign out"}</h3>
                <p className="hint">
                  {window.T?.settingsSignOutHint ||
                    "Sign out from this device."}
                </p>
                <button
                  className="btn danger"
                  onClick={handleSignOut}
                  disabled={signOutLoading}
                >
                  {signOutLoading ? (
                    <>
                      <Icon name="spinner" size={13} />{" "}
                      {window.T?.settingsSigningOut || "Signing out…"}
                    </>
                  ) : (
                    <>
                      <Icon name="logout" size={13} />{" "}
                      {window.T?.settingsSignOut || "Sign out"}
                    </>
                  )}
                </button>
              </div>
            </>
          )}

          {tab === "preferences" && (
            <div className="form-card">
              <h3>{window.T?.settingsAppearance || "Appearance"}</h3>
              <p className="hint">
                {window.T?.settingsAppearanceHint ||
                  "Customize the interface to your liking."}
              </p>
              <div className="checkbox-row">
                <span>{window.T?.settingsTheme || "Theme"}</span>
                <div className="segmented">
                  {[
                    { id: "light", label: window.T?.themeLight || "Светлая" },
                    { id: "dark", label: window.T?.themeDark || "Тёмная" },
                  ].map((m) => (
                    <button
                      key={m.id}
                      className={tweaks.theme === m.id ? "active" : ""}
                      onClick={() => setTweak("theme", m.id)}
                    >
                      {m.label}
                    </button>
                  ))}
                </div>
              </div>
              <div className="checkbox-row">
                <span>{window.T?.settingsDensity || "Table density"}</span>
                <div className="segmented">
                  {[
                    {
                      id: "compact",
                      label: window.T?.densityCompact || "Компактная",
                    },
                    {
                      id: "normal",
                      label: window.T?.densityNormal || "Обычная",
                    },
                    {
                      id: "comfortable",
                      label: window.T?.densityComfortable || "Просторная",
                    },
                  ].map((d) => (
                    <button
                      key={d.id}
                      className={tweaks.density === d.id ? "active" : ""}
                      onClick={() => setTweak("density", d.id)}
                    >
                      {d.label}
                    </button>
                  ))}
                </div>
              </div>
            </div>
          )}

          {tab === "channels" && <ChannelsTab userId={userId} />}

          {tab === "team" && (
            <TeamTab
              userId={userId}
              userProfile={userProfile}
              onGoBilling={() => setTab("billing")}
            />
          )}

          {tab === "billing" && (
            <BillingTab userId={userId} userProfile={userProfile} />
          )}

          {tab === "quotas" && <QuotasTab userId={userId} />}

          {tab === "api" && (
            <div className="form-card">
              <h3>{window.T?.settingsApiKeys || "API Keys"}</h3>
              <p className="hint">
                {window.T?.settingsApiKeysHint ||
                  "Stored as Cloud Run environment variables. Rotate via GCP Console."}
              </p>
              {[
                {
                  l: "YOUTUBE_API_KEY",
                  hint: "Google Cloud Console → Credentials",
                },
                {
                  l: "ANTHROPIC_API_KEY",
                  hint: "console.anthropic.com → API Keys",
                },
                {
                  l: "SUPABASE_URL",
                  hint: "Supabase Dashboard → Project Settings",
                },
                {
                  l: "SUPABASE_KEY",
                  hint: "Supabase Dashboard → Project Settings",
                },
                {
                  l: "SCRAPECREATORS_API_KEY",
                  hint: "app.scrapecreators.com → API Keys",
                },
              ].map((k) => (
                <div
                  key={k.l}
                  style={{
                    display: "flex",
                    alignItems: "center",
                    gap: 12,
                    padding: "12px 0",
                    borderBottom: "1px solid var(--border)",
                  }}
                >
                  <div style={{ flex: 1 }}>
                    <div
                      style={{
                        fontSize: 12,
                        color: "var(--fg-muted)",
                        fontFamily: "var(--mono)",
                        marginBottom: 2,
                      }}
                    >
                      {k.l}
                    </div>
                    <div style={{ fontSize: 11, color: "var(--fg-faint)" }}>
                      {k.hint}
                    </div>
                  </div>
                  <span className="status ok">
                    {window.T?.settingsConnected || "connected"}
                  </span>
                  <a
                    href="https://console.cloud.google.com/run/detail/europe-west1/younalyse-api/revisions"
                    target="_blank"
                    className="btn sm"
                  >
                    {window.T?.settingsRotate || "Rotate"} ↗
                  </a>
                </div>
              ))}
            </div>
          )}
        </div>
      </div>
    </div>
  );
};

Object.assign(window, {
  ResultsScreen,
  DetailOverlay,
  SettingsScreen,
  OutlierBadge,
  computeOutliers,
  getOutlier,
  TeamTab,
  TeamMemberBanner,
});
