// Модалка "Сигналы / Telegram" — подключение Telegram-аккаунта + торговые
// настройки + сигнальные каналы.

const TelegramSettingsModal = ({ open, onClose }) => {
  if (!open) return null;
  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal" onClick={e => e.stopPropagation()}
           style={{ width: "min(700px, 95vw)", maxHeight: "90vh", display: "flex", flexDirection: "column" }}>
        <div className="modal-head">
          <h2><Icon name="activity" size={14}/> Сигналы и торговля</h2>
          <button className="icon-btn" onClick={onClose}><Icon name="x" size={14}/></button>
        </div>
        <div className="modal-body" style={{ overflowY: "auto" }}>
          <TelegramAccountSection/>
          <div style={{ height: 18 }}/>
          <TradingPrefsSection/>
          <div style={{ height: 18 }}/>
          <ChannelsSection/>
          <ForwardsAdminSection/>
        </div>
        <div className="modal-foot">
          <button className="btn ghost" onClick={onClose}>Закрыть</button>
        </div>
      </div>
    </div>
  );
};

// =====================================================================
// Telegram account: send-code → verify-code → (2FA password)
// =====================================================================

const TelegramAccountSection = () => {
  const [status, setStatus] = useState(null);
  const [step, setStep] = useState("idle");   // idle | sending | code | password | working | qr | qr_password
  const [loginMode, setLoginMode] = useState("qr"); // "qr" | "code" | "import"
  const [form, setForm] = useState({ api_id: "", api_hash: "", phone: "" });
  const [code, setCode] = useState("");
  const [sessionString, setSessionString] = useState("");
  const [password, setPassword] = useState("");
  const [err, setErr] = useState("");
  const [info, setInfo] = useState("");
  const [qrUrl, setQrUrl] = useState("");
  const qrCanvasRef = React.useRef(null);
  const qrPollTimerRef = React.useRef(null);

  const reload = async () => {
    try { setStatus(await window.AUTH.tgStatus()); }
    catch (e) { setErr(e.message); }
  };
  useEffect(() => { reload(); }, []);

  const upd = (k, v) => setForm(prev => ({ ...prev, [k]: v }));

  const sendCode = async (forceSms = false) => {
    setErr(""); setInfo("");
    const api_id = parseInt(form.api_id, 10);
    const api_hash = (form.api_hash || "").trim();
    const phone = (form.phone || "").trim();
    if (!api_id || !api_hash || !phone) {
      setErr("Заполните api_id, api_hash и phone.");
      return;
    }
    setStep("sending");
    try {
      const res = await window.AUTH.tgSendCode({
        api_id, api_hash, phone, force_sms: !!forceSms,
      });
      setStep("code");
      const via = res?.via;
      if (forceSms || via === "sms") {
        setInfo("📨 Запрошена отправка через SMS. Проверьте сообщения.");
      } else {
        setInfo("Код отправлен в приложение Telegram (на другом устройстве с этим номером). Если не приходит — нажмите «Прислать SMS».");
      }
    } catch (e) {
      setErr(e.message); setStep("idle");
    }
  };

  // === QR-login ===

  const renderQrToCanvas = (url) => {
    if (!qrCanvasRef.current || !window.qrcode) return;
    try {
      const qr = window.qrcode(0, "L"); // type=0 auto, ECC level L (low for compact)
      qr.addData(url);
      qr.make();
      const canvas = qrCanvasRef.current;
      const ctx = canvas.getContext("2d");
      const size = 240;
      const moduleCount = qr.getModuleCount();
      const cell = Math.floor(size / moduleCount);
      canvas.width = canvas.height = cell * moduleCount;
      ctx.fillStyle = "#ffffff";
      ctx.fillRect(0, 0, canvas.width, canvas.height);
      ctx.fillStyle = "#000000";
      for (let r = 0; r < moduleCount; r++) {
        for (let c = 0; c < moduleCount; c++) {
          if (qr.isDark(r, c)) {
            ctx.fillRect(c * cell, r * cell, cell, cell);
          }
        }
      }
    } catch (e) {
      console.error("QR render error", e);
    }
  };

  const qrStart = async () => {
    setErr(""); setInfo("");
    const api_id = parseInt(form.api_id, 10);
    const api_hash = (form.api_hash || "").trim();
    if (!api_id || !api_hash) {
      setErr("Заполните api_id и api_hash.");
      return;
    }
    setStep("sending");
    try {
      const r = await window.AUTH.tgQrStart({ api_id, api_hash });
      setQrUrl(r.url || "");
      setStep("qr");
      setInfo("Откройте Telegram на телефоне → Настройки → Устройства → Подключить устройство — отсканируйте QR ниже.");
      // Запуск poll'a
      if (qrPollTimerRef.current) clearInterval(qrPollTimerRef.current);
      qrPollTimerRef.current = setInterval(qrPoll, 2500);
    } catch (e) {
      setErr(e.message); setStep("idle");
    }
  };

  const qrPoll = async () => {
    try {
      const r = await window.AUTH.tgQrPoll();
      if (r.status === "waiting") {
        if (r.url && r.url !== qrUrl) {
          setQrUrl(r.url);
          if (r.recreated) setInfo("QR-код обновлён — отсканируйте новый.");
        }
        return;
      }
      // любой не-waiting — останавливаем poll
      if (qrPollTimerRef.current) {
        clearInterval(qrPollTimerRef.current);
        qrPollTimerRef.current = null;
      }
      if (r.status === "needs_password") {
        setStep("qr_password");
        setInfo("✅ QR подтверждён. Введите 2FA пароль Telegram.");
        return;
      }
      if (r.status === "connected") {
        setInfo(`✅ Подключено! ${r.tg_username ? "@" + r.tg_username : ""}`);
        setStep("idle");
        setForm({ api_id: "", api_hash: "", phone: "" });
        setQrUrl(""); setPassword(""); setCode("");
        await reload();
        return;
      }
      if (r.status === "expired") {
        setErr("Сессия истекла, нажмите «Получить QR» ещё раз.");
        setStep("idle");
        return;
      }
      if (r.status === "error") {
        setErr(r.error || "Ошибка QR-login");
        setStep("idle");
      }
    } catch (e) {
      // poll-ошибки игнорируем — просто продолжим следующим тиком
    }
  };

  const qrSubmitPassword = async () => {
    setErr("");
    if (!password) { setErr("Введите 2FA пароль."); return; }
    setStep("working");
    try {
      const r = await window.AUTH.tgQrPassword({ password });
      if (r.status === "connected") {
        setInfo(`✅ Подключено! ${r.tg_username ? "@" + r.tg_username : ""}`);
        setStep("idle");
        setForm({ api_id: "", api_hash: "", phone: "" });
        setQrUrl(""); setPassword(""); setCode("");
        await reload();
      }
    } catch (e) {
      setErr(e.message); setStep("qr_password");
    }
  };

  const qrCancel = async () => {
    if (qrPollTimerRef.current) {
      clearInterval(qrPollTimerRef.current);
      qrPollTimerRef.current = null;
    }
    try { await window.AUTH.tgQrCancel(); } catch {}
    setStep("idle"); setQrUrl(""); setPassword("");
    setErr(""); setInfo("");
  };

  // Cleanup timer на unmount
  useEffect(() => {
    return () => {
      if (qrPollTimerRef.current) clearInterval(qrPollTimerRef.current);
    };
  }, []);

  // Перерисовать QR когда URL меняется
  useEffect(() => {
    if (step === "qr" && qrUrl) {
      const tick = () => renderQrToCanvas(qrUrl);
      if (window.qrcode) tick();
      else setTimeout(tick, 200);  // ждём загрузки CDN
    }
  }, [qrUrl, step]);

  const importSession = async () => {
    setErr(""); setInfo("");
    const api_id = parseInt(form.api_id, 10);
    const api_hash = (form.api_hash || "").trim();
    const phone = (form.phone || "").trim();
    const ss = (sessionString || "").trim();
    if (!api_id || !api_hash || !phone) {
      setErr("Заполните api_id, api_hash и phone (те же что использовались при экспорте).");
      return;
    }
    if (!ss || ss.length < 50) {
      setErr("Вставьте session string (запустите tools/export_session.py локально).");
      return;
    }
    setStep("working");
    try {
      const r = await window.AUTH.tgImportSession({
        api_id, api_hash, phone, session_string: ss,
      });
      if (r.connected) {
        setInfo(`✅ Сессия импортирована! (${r.tg_username ? "@" + r.tg_username : "tg_user_id=" + r.tg_user_id})`);
        setStep("idle");
        setForm({ api_id: "", api_hash: "", phone: "" });
        setSessionString(""); setCode(""); setPassword("");
        setLoginMode("code");
        await reload();
      }
    } catch (e) {
      setErr(e.message); setStep("idle");
    }
  };

  const resendSms = async () => {
    setErr(""); setInfo("");
    const api_id = parseInt(form.api_id, 10);
    const api_hash = (form.api_hash || "").trim();
    const phone = (form.phone || "").trim();
    if (!api_id || !api_hash || !phone) {
      setErr("Данные формы потеряны. Отмените и заполните заново.");
      return;
    }
    setStep("sending");
    try {
      const res = await window.AUTH.tgSendCode({
        api_id, api_hash, phone, force_sms: true,
      });
      setStep("code");
      setInfo(res?.via === "sms"
        ? "📨 SMS отправлено. Проверьте сообщения на телефоне."
        : "Telegram попробовал прислать SMS — проверьте телефон через 30-60 сек.");
    } catch (e) {
      setErr(e.message); setStep("code");
    }
  };

  const verifyCode = async () => {
    setErr(""); setInfo("");
    const c = (code || "").trim();
    if (!c) { setErr("Введите код."); return; }
    setStep("working");
    try {
      const r = await window.AUTH.tgVerifyCode({ code: c });
      if (r.needs_password) {
        setStep("password");
        setInfo("Введите ваш 2FA-пароль от Telegram.");
      } else if (r.connected) {
        setInfo("✅ Подключено!");
        setStep("idle");
        setForm({ api_id: "", api_hash: "", phone: "" });
        setCode(""); setPassword("");
        await reload();
      }
    } catch (e) {
      setErr(e.message); setStep("code");
    }
  };

  const verifyPassword = async () => {
    setErr(""); setInfo("");
    if (!password) { setErr("Введите пароль."); return; }
    setStep("working");
    try {
      const r = await window.AUTH.tgVerifyPass({ password });
      if (r.connected) {
        setInfo("✅ Подключено!");
        setStep("idle");
        setForm({ api_id: "", api_hash: "", phone: "" });
        setCode(""); setPassword("");
        await reload();
      }
    } catch (e) {
      setErr(e.message); setStep("password");
    }
  };

  const cancelConnect = async () => {
    setErr(""); setInfo("");
    try { await window.AUTH.tgCancelConnect(); } catch {}
    setStep("idle"); setCode(""); setPassword("");
    await reload();
  };

  const disconnect = async () => {
    if (!confirm("Отвязать Telegram-аккаунт? Listener будет остановлен.")) return;
    setErr(""); setInfo("");
    try {
      await window.AUTH.tgDisconnect();
      setInfo("Отключено.");
      await reload();
    } catch (e) { setErr(e.message); }
  };

  if (!status) {
    return <div style={{ padding: 12, textAlign: "center", color: "var(--text-3)" }}>
      <span className="skel-bar" style={{ width: 16, height: 16, borderRadius: "50%" }}/>
    </div>;
  }

  const busy = step === "sending" || step === "working";

  return (
    <div>
      <div className="section-title" style={{ marginBottom: 10 }}>
        <Icon name="link" size={11}/> Подключение Telegram-аккаунта
      </div>

      {status.connected ? (
        <div style={{ padding: "10px 12px",
                      background: status.listener_running ? "var(--long-dim)" : "var(--warn-dim)",
                      border: "1px solid " + (status.listener_running ? "var(--long)" : "var(--warn)"),
                      borderRadius: "var(--r-2)",
                      display: "flex", alignItems: "center", justifyContent: "space-between" }}>
          <div>
            <div style={{ fontSize: 13, fontWeight: 500,
                          color: status.listener_running ? "var(--long)" : "var(--warn)" }}>
              {status.listener_running
                ? "✅ Подключено, listener активен"
                : "⚠️ Подключено, но listener не запущен"}
            </div>
            <div style={{ fontSize: 11, color: "var(--text-3)", marginTop: 2, lineHeight: 1.5 }}>
              {status.phone_masked && <>Телефон: <span className="mono">{status.phone_masked}</span></>}
              {status.tg_username && <> · @{status.tg_username}</>}
              {!status.listener_running && <><br/>Проверьте, что в .env заданы TELEGRAM_API_ID/HASH/BOT_TOKEN для запуска confirm-бота.</>}
            </div>
          </div>
          <button className="btn" onClick={disconnect}
                  style={{ color: "var(--short)", borderColor: "var(--short-dim)" }}>
            <Icon name="x" size={11}/> Отвязать
          </button>
        </div>
      ) : step === "idle" ? (
        <div>
          {/* Tabs: QR (рекомендуется) / код / импорт сессии */}
          <div style={{ display: "flex", gap: 4, marginBottom: 12,
                        padding: 3, background: "var(--bg-2)",
                        border: "1px solid var(--border)", borderRadius: "var(--r-2)" }}>
            <button className="btn"
                    onClick={() => { setLoginMode("qr"); setErr(""); setInfo(""); }}
                    style={{ flex: 1,
                             background: loginMode === "qr" ? "var(--bg)" : "transparent",
                             borderColor: loginMode === "qr" ? "var(--border-2)" : "transparent",
                             color: loginMode === "qr" ? "var(--text)" : "var(--text-3)" }}>
              📷 QR-код ★
            </button>
            <button className="btn"
                    onClick={() => { setLoginMode("code"); setErr(""); setInfo(""); }}
                    style={{ flex: 1,
                             background: loginMode === "code" ? "var(--bg)" : "transparent",
                             borderColor: loginMode === "code" ? "var(--border-2)" : "transparent",
                             color: loginMode === "code" ? "var(--text)" : "var(--text-3)" }}>
              📱 Код
            </button>
            <button className="btn"
                    onClick={() => { setLoginMode("import"); setErr(""); setInfo(""); }}
                    style={{ flex: 1,
                             background: loginMode === "import" ? "var(--bg)" : "transparent",
                             borderColor: loginMode === "import" ? "var(--border-2)" : "transparent",
                             color: loginMode === "import" ? "var(--text)" : "var(--text-3)" }}>
              📥 Импорт
            </button>
          </div>

          <div className="field"><label>API ID</label>
            <input className="input" type="number" placeholder="например 1234567"
                   value={form.api_id} onChange={e => upd("api_id", e.target.value)} disabled={busy}/>
          </div>
          <div className="field"><label>API Hash</label>
            <input className="input" placeholder="abc123..."
                   value={form.api_hash} onChange={e => upd("api_hash", e.target.value)} disabled={busy}/>
          </div>
          {loginMode !== "qr" && (
            <div className="field"><label>Телефон (с кодом страны)</label>
              <input className="input" placeholder="+79123456789"
                     value={form.phone} onChange={e => upd("phone", e.target.value)} disabled={busy}/>
            </div>
          )}

          {loginMode === "qr" ? (
            <>
              <div className="empty-hint" style={{ textAlign: "left", lineHeight: 1.6, marginBottom: 10, fontSize: 11 }}>
                <b>★ Рекомендуется.</b> Telegram с 2024 года ограничил SMS-доставку для third-party приложений — твой api_id может не получать коды. QR-вход работает всегда.
                <br/><br/>
                <b>Как:</b>
                <ol style={{ margin: "6px 0 0 16px", paddingLeft: 0 }}>
                  <li>Жми «Получить QR» ниже</li>
                  <li>Открой Telegram <b>на телефоне</b> → Настройки → <b>Устройства</b> → <b>«Подключить устройство»</b></li>
                  <li>Сканируй QR на экране</li>
                  <li>Если 2FA — введи пароль здесь</li>
                </ol>
              </div>
              <div style={{ display: "flex", justifyContent: "flex-end" }}>
                <button className="btn primary" onClick={qrStart} disabled={busy}>
                  {busy ? "..." : "📷 Получить QR"}
                </button>
              </div>
            </>
          ) : loginMode === "code" ? (
            <>
              <div className="empty-hint" style={{ textAlign: "left", lineHeight: 1.5, marginBottom: 10 }}>
                Получить api_id и api_hash: <a href="https://my.telegram.org/auth" target="_blank" rel="noopener noreferrer">my.telegram.org</a> → API development tools.
                Ваши credentials шифруются и хранятся локально в БД.
                <br/><br/>
                <b style={{ color: "var(--warn)" }}>⚠️ Если код не приходит</b> — используй вкладку <b>QR-код</b> (надёжнее).
              </div>
              <div style={{ display: "flex", justifyContent: "flex-end" }}>
                <button className="btn primary" onClick={() => sendCode(false)} disabled={busy}>
                  {busy ? "..." : "Получить код"}
                </button>
              </div>
            </>
          ) : (
            <>
              <div className="field">
                <label>Session string</label>
                <textarea className="input" rows={5}
                          placeholder="1ApWapzMBu_xxxxxxxxxxxxxxxxxxxxxxxxxxx..."
                          value={sessionString}
                          onChange={e => setSessionString(e.target.value)}
                          disabled={busy}
                          style={{ fontFamily: "var(--font-mono)", fontSize: 11,
                                   resize: "vertical", minHeight: 80 }}/>
              </div>
              <div className="empty-hint" style={{ textAlign: "left", lineHeight: 1.6, marginBottom: 10, fontSize: 11 }}>
                <b>Когда использовать:</b> если Telegram не присылает код на сервер
                (anti-fraud блок на VPS-IP).
                <br/><br/>
                <b>Как получить session string:</b>
                <ol style={{ margin: "6px 0 0 16px", paddingLeft: 0 }}>
                  <li>Локально на твоей машине: <span className="mono">cd trading-bot</span></li>
                  <li>Запусти: <span className="mono">python tools/export_session.py</span></li>
                  <li>Введи api_id / api_hash / phone (те же что выше)</li>
                  <li>Получишь код в Telegram (с домашнего IP — придёт нормально)</li>
                  <li>Скрипт распечатает session string — скопируй и вставь сюда</li>
                </ol>
              </div>
              <div style={{ display: "flex", justifyContent: "flex-end" }}>
                <button className="btn primary" onClick={importSession} disabled={busy}>
                  {busy ? "..." : "📥 Импортировать"}
                </button>
              </div>
            </>
          )}
        </div>
      ) : step === "qr" ? (
        <div>
          <div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 12, marginBottom: 12 }}>
            <canvas ref={qrCanvasRef}
                    style={{ background: "#fff", padding: 12,
                             borderRadius: "var(--r-2)",
                             border: "1px solid var(--border-2)" }}/>
            <div style={{ fontSize: 11, color: "var(--text-3)", textAlign: "center", lineHeight: 1.5 }}>
              Открой Telegram <b>на телефоне</b> →<br/>
              Настройки → Устройства → <b>«Подключить устройство»</b><br/>
              → Сканируй QR
            </div>
          </div>
          <div style={{ display: "flex", justifyContent: "flex-end" }}>
            <button className="btn ghost" onClick={qrCancel} disabled={busy}>Отменить</button>
          </div>
        </div>
      ) : step === "qr_password" ? (
        <div>
          <div className="field">
            <label>2FA пароль Telegram</label>
            <input className="input" type="password" placeholder="Пароль"
                   value={password} onChange={e => setPassword(e.target.value)}
                   disabled={busy}
                   onKeyDown={e => e.key === "Enter" && qrSubmitPassword()}/>
            <div style={{ fontSize: 11, color: "var(--text-3)", marginTop: 4, lineHeight: 1.4 }}>
              QR отсканирован, но на аккаунте включена двухэтапная защита. Введи пароль от Telegram (не от SMS).
            </div>
          </div>
          <div style={{ display: "flex", gap: 6, justifyContent: "flex-end" }}>
            <button className="btn ghost" onClick={qrCancel} disabled={busy}>Отменить</button>
            <button className="btn primary" onClick={qrSubmitPassword} disabled={busy}>
              {busy ? "..." : "Подтвердить"}
            </button>
          </div>
        </div>
      ) : step === "code" || step === "working" && code ? (
        <div>
          <div className="field">
            <label>Код из Telegram</label>
            <input className="input" placeholder="12345"
                   value={code} onChange={e => setCode(e.target.value)}
                   disabled={busy}
                   onKeyDown={e => e.key === "Enter" && verifyCode()}/>
            <div style={{ fontSize: 11, color: "var(--text-3)", marginTop: 4, lineHeight: 1.4 }}>
              Код приходит в <b>чат от Telegram</b> в приложении на другом устройстве с этим номером.
              Если не получили — нажмите <b>«Прислать SMS»</b>.
            </div>
          </div>
          <div style={{ display: "flex", gap: 6, justifyContent: "space-between", alignItems: "center" }}>
            <button className="btn ghost" onClick={resendSms} disabled={busy}>
              {busy ? "..." : "📨 Прислать SMS"}
            </button>
            <div style={{ display: "flex", gap: 6 }}>
              <button className="btn ghost" onClick={cancelConnect} disabled={busy}>Отменить</button>
              <button className="btn primary" onClick={verifyCode} disabled={busy}>
                {busy ? "..." : "Подтвердить"}
              </button>
            </div>
          </div>
        </div>
      ) : step === "password" ? (
        <div>
          <div className="field">
            <label>2FA пароль Telegram (cloud-password)</label>
            <input className="input" type="password" placeholder="••••••"
                   value={password} onChange={e => setPassword(e.target.value)}
                   disabled={busy}
                   onKeyDown={e => e.key === "Enter" && verifyPassword()}/>
          </div>
          <div style={{ display: "flex", gap: 6, justifyContent: "flex-end" }}>
            <button className="btn ghost" onClick={cancelConnect} disabled={busy}>Отменить</button>
            <button className="btn primary" onClick={verifyPassword} disabled={busy}>
              {busy ? "..." : "Подтвердить 2FA"}
            </button>
          </div>
        </div>
      ) : null}

      {err && <div className="auth-error" style={{ marginTop: 8 }}>{err}</div>}
      {info && !err && (
        <div style={{ marginTop: 8, fontSize: 12, color: "var(--text-3)" }}>{info}</div>
      )}

      {/* BotFather bot — отдельная секция, видна только когда Telegram уже подключён */}
      {status.connected && (
        <div style={{ marginTop: 18, paddingTop: 14, borderTop: "1px solid var(--border)" }}>
          <BotTokenBlock status={status} onChange={reload}/>
        </div>
      )}
    </div>
  );
};

// =====================================================================
// BotFather bot привязка (для DM-карточек подтверждения)
// =====================================================================

const BotTokenBlock = ({ status, onChange }) => {
  const [token, setToken] = useState("");
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState("");
  const [info, setInfo] = useState("");

  const save = async () => {
    setErr(""); setInfo("");
    const t = (token || "").trim();
    if (!t) { setErr("Вставьте bot_token от @BotFather."); return; }
    setBusy(true);
    try {
      const r = await window.AUTH.tgSetBotToken({ bot_token: t });
      setInfo(`✅ Бот @${r.bot_username || "?"} привязан. Я отправил вам тестовое сообщение в Telegram.`);
      setToken("");
      await onChange();
    } catch (e) {
      setErr(e.message);
    } finally { setBusy(false); }
  };

  const clear = async () => {
    if (!confirm("Отвязать бота? Карточки сигналов перестанут приходить.")) return;
    setErr(""); setInfo("");
    setBusy(true);
    try {
      await window.AUTH.tgClearBotToken();
      setInfo("Бот отвязан.");
      await onChange();
    } catch (e) { setErr(e.message); }
    finally { setBusy(false); }
  };

  return (
    <div>
      <div className="section-title" style={{ marginBottom: 10 }}>
        <Icon name="bell" size={11}/> Бот для алертов
      </div>

      {status.bot_linked ? (
        <div style={{ padding: "10px 12px",
                      background: status.bot_running ? "var(--long-dim)" : "var(--warn-dim)",
                      border: "1px solid " + (status.bot_running ? "var(--long)" : "var(--warn)"),
                      borderRadius: "var(--r-2)",
                      display: "flex", alignItems: "center", justifyContent: "space-between" }}>
          <div>
            <div style={{ fontSize: 13, fontWeight: 500,
                          color: status.bot_running ? "var(--long)" : "var(--warn)" }}>
              {status.bot_running
                ? `✅ Бот @${status.bot_username || "?"} работает`
                : `⚠️ Бот @${status.bot_username || "?"} привязан, но не запущен`}
            </div>
            <div style={{ fontSize: 11, color: "var(--text-3)", marginTop: 2, lineHeight: 1.5 }}>
              Карточки сигналов будут приходить вам в DM через этого бота.
            </div>
          </div>
          <button className="btn" onClick={clear} disabled={busy}
                  style={{ color: "var(--short)", borderColor: "var(--short-dim)" }}>
            <Icon name="x" size={11}/> Отвязать
          </button>
        </div>
      ) : (
        <div>
          <div className="field">
            <label>BotFather token</label>
            <input className="input" placeholder="123456:ABCDEF..."
                   value={token} onChange={e => setToken(e.target.value)}
                   disabled={busy}
                   onKeyDown={e => e.key === "Enter" && save()}/>
          </div>
          <div className="empty-hint" style={{ textAlign: "left", lineHeight: 1.6, marginBottom: 10 }}>
            <b>Как получить:</b>
            <ol style={{ marginTop: 4, marginBottom: 0, paddingLeft: 22 }}>
              <li>В Telegram откройте <a href="https://t.me/BotFather" target="_blank" rel="noopener noreferrer">@BotFather</a></li>
              <li>Команда <span className="mono">/newbot</span> → задайте имя и username</li>
              <li>BotFather пришлёт токен — скопируйте сюда</li>
              <li><b>Важно:</b> найдите вашего нового бота в Telegram и нажмите <span className="mono">/start</span> — иначе он не сможет вам писать</li>
            </ol>
          </div>
          <div style={{ display: "flex", justifyContent: "flex-end" }}>
            <button className="btn primary" onClick={save} disabled={busy || !token.trim()}>
              {busy ? "Проверяю…" : "Привязать"}
            </button>
          </div>
        </div>
      )}

      {err && <div className="auth-error" style={{ marginTop: 8 }}>{err}</div>}
      {info && !err && (
        <div style={{ marginTop: 8, fontSize: 12, color: "var(--text-3)" }}>{info}</div>
      )}
    </div>
  );
};

// =====================================================================
// Trading prefs (size / leverage / mode / dry-run)
// Два режима:
//   - global      : одни настройки для всех бирж + per-exchange флаг "принимать сигналы"
//   - per_exchange: каждая биржа со своими настройками
// =====================================================================

const EXCHANGES = [
  { id: "weex",    label: "WEEX"    },
  { id: "binance", label: "Binance" },
  { id: "bybit",   label: "Bybit"   },
  { id: "okx",     label: "OKX"     },
];

const TradingPrefsSection = () => {
  const [s, setS] = useState(null);
  const [exSigs, setExSigs] = useState(null);
  const [picked, setPicked] = useState("weex");
  const [busy, setBusy] = useState(false);
  const [msg, setMsg] = useState({ kind: "", text: "" });

  const flash = (kind, text) => {
    setMsg({ kind, text });
    if (kind === "ok") setTimeout(() => setMsg({ kind: "", text: "" }), 1500);
  };

  useEffect(() => {
    (async () => {
      try {
        const [settings, signals] = await Promise.all([
          window.AUTH.getSettings(),
          window.AUTH.listExchangeSignals(),
        ]);
        setS(settings);
        setExSigs(signals);
      } catch (e) {
        flash("err", e.message);
      }
    })();
  }, []);

  const setMode = async (mode) => {
    setBusy(true); setMsg({ kind: "", text: "" });
    try {
      const fresh = await window.AUTH.putSettings({ signal_settings_mode: mode });
      setS(fresh);
    } catch (e) { flash("err", e.message); }
    finally { setBusy(false); }
  };

  const toggleExchangeEnabled = async (ex, enabled) => {
    setBusy(true);
    try {
      const fresh = await window.AUTH.putExchangeSignal(ex, { signal_enabled: enabled });
      setExSigs(prev => prev.map(r => r.exchange === ex ? fresh : r));
    } catch (e) { flash("err", e.message); }
    finally { setBusy(false); }
  };

  const saveGlobal = async (values) => {
    setBusy(true); setMsg({ kind: "", text: "" });
    try {
      const fresh = await window.AUTH.putSettings(values);
      setS(fresh);
      flash("ok", "💾 Сохранено");
    } catch (e) { flash("err", e.message); }
    finally { setBusy(false); }
  };

  const savePerExchange = async (ex, values) => {
    setBusy(true); setMsg({ kind: "", text: "" });
    try {
      const fresh = await window.AUTH.putExchangeSignal(ex, values);
      setExSigs(prev => prev.map(r => r.exchange === ex ? fresh : r));
      flash("ok", "💾 Сохранено");
    } catch (e) { flash("err", e.message); }
    finally { setBusy(false); }
  };

  if (!s || !exSigs) {
    return <div style={{ padding: 20, textAlign: "center", color: "var(--text-3)" }}>
      <span className="skel-bar" style={{ width: 16, height: 16, borderRadius: "50%" }}/>
    </div>;
  }

  const mode = s.signal_settings_mode || "global";
  const pickedRow = exSigs.find(r => r.exchange === picked) || exSigs[0];

  return (
    <div>
      <div className="section-title" style={{ marginBottom: 10 }}>
        <Icon name="settings" size={11}/> Торговые настройки
      </div>

      {/* === Режим === */}
      <div className="field" style={{ marginBottom: 14 }}>
        <label>Режим настроек</label>
        <div style={{ display: "flex", gap: 6 }}>
          <button onClick={() => setMode("global")}
                  className={"btn" + (mode === "global" ? " primary" : " ghost")}
                  disabled={busy} style={{ flex: 1, fontSize: 12 }}>
            🌐 Глобально (одни для всех)
          </button>
          <button onClick={() => setMode("per_exchange")}
                  className={"btn" + (mode === "per_exchange" ? " primary" : " ghost")}
                  disabled={busy} style={{ flex: 1, fontSize: 12 }}>
            🎛️ Per-exchange (каждой свои)
          </button>
        </div>
        <div className="empty-hint" style={{ textAlign: "left", marginTop: 4, lineHeight: 1.5 }}>
          {mode === "global"
            ? "Одни и те же плечо/маржа/режим для всех бирж. Ниже можно выкл/вкл биржи."
            : "У каждой биржи свой набор настроек. Выберите биржу в dropdown ниже."}
        </div>
      </div>

      {mode === "global" ? (
        <GlobalSignalPanel
          initial={s}
          exSigs={exSigs}
          busy={busy}
          onToggleEx={toggleExchangeEnabled}
          onSave={saveGlobal}
        />
      ) : (
        <PerExchangePanel
          exSigs={exSigs}
          picked={picked}
          setPicked={setPicked}
          row={pickedRow}
          busy={busy}
          onSave={(values) => savePerExchange(picked, values)}
        />
      )}

      {msg.text && (
        <div style={{ marginTop: 10, fontSize: 12, fontFamily: "var(--font-mono)",
                      color: msg.kind === "ok" ? "var(--long)" :
                             msg.kind === "err" ? "var(--short)" : "var(--text-3)" }}>
          {msg.text}
        </div>
      )}
    </div>
  );
};

// ----- Global mode: единый набор полей + per-exchange чипы вкл/выкл -----

const GlobalSignalPanel = ({ initial, exSigs, busy, onToggleEx, onSave }) => {
  return (
    <div>
      {/* Per-exchange enable chips */}
      <div className="field" style={{ marginBottom: 14 }}>
        <label>Принимать сигналы на биржах</label>
        <div style={{ display: "flex", gap: 6, flexWrap: "wrap" }}>
          {EXCHANGES.map(ex => {
            const row = exSigs.find(r => r.exchange === ex.id);
            const on = !!(row && row.signal_enabled);
            return (
              <button key={ex.id}
                      onClick={() => onToggleEx(ex.id, !on)}
                      disabled={busy}
                      className={"btn " + (on ? "primary" : "ghost")}
                      style={{ fontSize: 12, padding: "4px 10px" }}>
                {on ? "✅" : "⬜"} {ex.label}
              </button>
            );
          })}
        </div>
        <div className="empty-hint" style={{ textAlign: "left", marginTop: 4, lineHeight: 1.5 }}>
          API-ключи биржи остаются — выключение блокирует только сигнальные сделки.
        </div>
      </div>

      <SignalFormFields initial={initial} busy={busy} onSave={onSave}/>
    </div>
  );
};

// ----- Per-exchange mode: dropdown + сигнал-toggle + поля -----

const PerExchangePanel = ({ exSigs, picked, setPicked, row, busy, onSave }) => {
  const toggleEnabled = async () => {
    const fresh = { ...row, signal_enabled: !row.signal_enabled };
    await onSave({ signal_enabled: fresh.signal_enabled });
  };
  return (
    <div>
      <div className="field" style={{ marginBottom: 14 }}>
        <label>Биржа</label>
        <select className="select" value={picked}
                onChange={e => setPicked(e.target.value)} disabled={busy}>
          {EXCHANGES.map(ex => {
            const r = exSigs.find(x => x.exchange === ex.id);
            const on = r && r.signal_enabled;
            return (
              <option key={ex.id} value={ex.id}>
                {ex.label} {on ? "— сигналы вкл" : "— сигналы выкл"}
              </option>
            );
          })}
        </select>
      </div>

      <div style={{ marginBottom: 14, padding: "10px 12px",
                    background: row.signal_enabled ? "var(--long-dim)" : "var(--warn-dim)",
                    border: "1px solid " + (row.signal_enabled ? "var(--long)" : "var(--warn)"),
                    borderRadius: "var(--r-2)",
                    display: "flex", alignItems: "center", justifyContent: "space-between" }}>
        <div>
          <div style={{ fontSize: 13, fontWeight: 500,
                        color: row.signal_enabled ? "var(--long)" : "var(--warn)" }}>
            {row.signal_enabled ? "✅ Сигналы включены" : "⏸ Сигналы выключены"}
          </div>
          <div style={{ fontSize: 11, color: "var(--text-3)", marginTop: 2, lineHeight: 1.5 }}>
            {row.signal_enabled
              ? "Сделки по сигналам исполняются на этой бирже."
              : "На этой бирже сигнальных сделок не будет (API-ключи сохранены)."}
          </div>
        </div>
        <button onClick={toggleEnabled}
                className={"switch" + (row.signal_enabled ? " on" : "")}
                title={row.signal_enabled ? "Выключить" : "Включить"} disabled={busy}/>
      </div>

      <SignalFormFields key={picked} initial={row} busy={busy} onSave={onSave}/>
    </div>
  );
};

// ----- Общий набор полей (плечо / маржа / подтверждение / dry-run) -----

const SignalFormFields = ({ initial, busy, onSave }) => {
  const [s, setS] = useState(initial);
  useEffect(() => { setS(initial); }, [initial]);
  const upd = (k, v) => setS(prev => ({ ...prev, [k]: v }));

  const save = () => onSave({
    default_position_size_usdt: Number(s.default_position_size_usdt),
    default_leverage: Number(s.default_leverage),
    confirmation_mode: s.confirmation_mode,
    dry_run: !!s.dry_run,
    leverage_mode: s.leverage_mode || "fixed",
    size_mode: s.size_mode || "fixed_usdt",
    size_percent: Number(s.size_percent || 1),
  });

  return (
    <div>
      {/* === Плечо === */}
      <div className="field" style={{ marginBottom: 6 }}>
        <label>Плечо</label>
        <select className="select" value={s.leverage_mode || "fixed"}
                onChange={e => upd("leverage_mode", e.target.value)} disabled={busy}>
          <option value="fixed">Фиксированное — всегда из настроек (рекомендую)</option>
          <option value="from_signal">Из сигнала — если в сигнале указано, иначе из настроек</option>
          <option value="max">Максимум биржи — для каждой монеты максимально доступное плечо</option>
        </select>
      </div>
      <div className="field">
        <label>{s.leverage_mode === "from_signal" ? "Плечо по умолчанию (когда в сигнале нет)" : "Плечо"}</label>
        <input className="input" type="number" step="1" min="1" max="125"
               value={s.default_leverage}
               onChange={e => upd("default_leverage", e.target.value)} disabled={busy}/>
      </div>

      {/* === Маржа === */}
      <div className="field" style={{ marginBottom: 6, marginTop: 14 }}>
        <label>Маржа на сделку</label>
        <select className="select" value={s.size_mode || "fixed_usdt"}
                onChange={e => upd("size_mode", e.target.value)} disabled={busy}>
          <option value="fixed_usdt">Фиксированная сумма USDT</option>
          <option value="percent_balance">% от доступного баланса</option>
        </select>
      </div>
      {s.size_mode === "percent_balance" ? (
        <div className="field">
          <label>% от available USDT (фьючерсный кошелёк)</label>
          <input className="input" type="number" step="0.01" min="0.01" max="100"
                 value={s.size_percent || 1}
                 onChange={e => upd("size_percent", e.target.value)} disabled={busy}/>
          <div className="empty-hint" style={{ textAlign: "left", marginTop: 4, lineHeight: 1.5 }}>
            Пример: <b>1%</b> при балансе <b>$500</b> = маржа <b>$5</b>.
            При плече <b>{s.default_leverage || "—"}x</b> объём позиции = <b>${(5 * (s.default_leverage || 1)).toFixed(0)}</b>.
          </div>
        </div>
      ) : (
        <div className="field">
          <label>Сумма USDT</label>
          <input className="input" type="number" step="0.01" min="0.1" max="100000"
                 value={s.default_position_size_usdt}
                 onChange={e => upd("default_position_size_usdt", e.target.value)} disabled={busy}/>
          <div className="empty-hint" style={{ textAlign: "left", marginTop: 4, lineHeight: 1.5 }}>
            При плече <b>{s.default_leverage || "—"}x</b> объём позиции = <b>${(Number(s.default_position_size_usdt || 0) * (s.default_leverage || 1)).toFixed(0)}</b>.
          </div>
        </div>
      )}

      {/* === Подтверждение === */}
      <div className="field" style={{ marginTop: 14 }}>
        <label>Режим подтверждения сигналов</label>
        <select className="select" value={s.confirmation_mode}
                onChange={e => upd("confirmation_mode", e.target.value)} disabled={busy}>
          <option value="manual">Manual — каждый сигнал вручную через кнопку</option>
          <option value="auto">Auto — высокая уверенность → авто-исполнение</option>
        </select>
      </div>

      <div style={{ marginTop: 12, padding: "10px 12px",
                    background: s.dry_run ? "var(--warn-dim)" : "var(--short-dim)",
                    border: "1px solid " + (s.dry_run ? "var(--warn)" : "var(--short)"),
                    borderRadius: "var(--r-2)",
                    display: "flex", alignItems: "center", justifyContent: "space-between" }}>
        <div>
          <div style={{ fontSize: 13, fontWeight: 500,
                        color: s.dry_run ? "var(--warn)" : "var(--short)" }}>
            {s.dry_run ? "🟡 DRY-RUN (тренировка)" : "🔴 РЕАЛЬНАЯ ТОРГОВЛЯ"}
          </div>
          <div style={{ fontSize: 11, color: "var(--text-3)", marginTop: 2, lineHeight: 1.5 }}>
            {s.dry_run
              ? "Ордера логируются, на биржу НЕ уходят. Безопасно для тестов."
              : "Ордера реально исполняются на бирже. Реальные деньги."}
          </div>
        </div>
        <button onClick={() => upd("dry_run", !s.dry_run)}
                className={"switch" + (s.dry_run ? "" : " on")}
                title={s.dry_run ? "Включить реальную торговлю" : "Выключить (вернуть dry-run)"} disabled={busy}/>
      </div>

      <div style={{ marginTop: 12, display: "flex", justifyContent: "flex-end" }}>
        <button className="btn primary" onClick={save} disabled={busy}>
          {busy ? "..." : "Сохранить настройки"}
        </button>
      </div>
    </div>
  );
};

// =====================================================================
// Signal channels
// =====================================================================

const ChannelsSection = () => {
  const [channels, setChannels] = useState([]);
  const [loading, setLoading] = useState(true);
  const [busy, setBusy] = useState(false);
  const [newRef, setNewRef] = useState("");
  const [newLabel, setNewLabel] = useState("");
  const [err, setErr] = useState("");

  const reload = async () => {
    setLoading(true);
    try { setChannels(await window.AUTH.listChannels()); }
    catch (e) { setErr(e.message); }
    finally { setLoading(false); }
  };
  useEffect(() => { reload(); }, []);

  const add = async () => {
    setErr("");
    const ref = newRef.trim();
    if (!ref) return;
    setBusy(true);
    try {
      await window.AUTH.addChannel({ channel_ref: ref, label: newLabel.trim() });
      setNewRef(""); setNewLabel("");
      await reload();
    } catch (e) {
      setErr(e.message);
    } finally { setBusy(false); }
  };

  const toggle = async (ch) => {
    try {
      await window.AUTH.updateChannel(ch.id, { is_active: !ch.is_active });
      await reload();
    } catch (e) { setErr(e.message); }
  };

  const remove = async (ch) => {
    if (!confirm(`Удалить ${ch.channel_ref}?`)) return;
    try {
      await window.AUTH.deleteChannel(ch.id);
      await reload();
    } catch (e) { setErr(e.message); }
  };

  return (
    <div style={{ borderTop: "1px solid var(--border)", paddingTop: 18 }}>
      <div className="section-title" style={{ marginBottom: 10 }}>
        <Icon name="list" size={11}/> Сигнальные каналы
        <span className="count">{channels.length}</span>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "1.5fr 1fr auto", gap: 6, marginBottom: 6 }}>
        <input className="input" placeholder="@username или -100..." value={newRef}
               onChange={e => setNewRef(e.target.value)} disabled={busy}
               onKeyDown={e => e.key === "Enter" && add()}/>
        <input className="input" placeholder="метка (опц.)" value={newLabel}
               onChange={e => setNewLabel(e.target.value)} disabled={busy} maxLength={64}/>
        <button className="btn primary" onClick={add} disabled={busy || !newRef.trim()}>
          <Icon name="check" size={12}/> Добавить
        </button>
      </div>
      <div className="empty-hint" style={{ textAlign: "left", lineHeight: 1.5, marginBottom: 10 }}>
        Формат: <span className="mono">@channelname</span> для публичных или{" "}
        <span className="mono">-1001234567890</span> для приватных.
        Ваш Telegram-аккаунт должен быть подписан на канал.
      </div>

      {err && <div className="auth-error" style={{ marginBottom: 10 }}>{err}</div>}

      {loading ? (
        <SkeletonRows rows={3} cols={4}/>
      ) : channels.length === 0 ? (
        <EmptyCard title="Каналов нет"
                   msg="Добавьте первый канал — его сообщения будут парситься и приходить на подтверждение."
                   icon="activity"/>
      ) : (
        <div className="card" style={{ overflow: "auto" }}>
          <table className="tbl">
            <thead>
              <tr>
                <th>Канал</th>
                <th>Метка</th>
                <th>Статус</th>
                <th>Добавлен</th>
                <th></th>
              </tr>
            </thead>
            <tbody>
              {channels.map(ch => (
                <tr key={ch.id}>
                  <td className="mono" style={{ fontSize: 12 }}>{ch.channel_ref}</td>
                  <td style={{ fontSize: 12, color: "var(--text-3)" }}>{ch.label || "—"}</td>
                  <td>
                    <button onClick={() => toggle(ch)}
                            className={"switch" + (ch.is_active ? " on" : "")}
                            title={ch.is_active ? "Активен" : "Выключен"}/>
                  </td>
                  <td className="mono muted" style={{ fontSize: 11 }}>{fmtTime(ch.added_at)}</td>
                  <td style={{ textAlign: "right" }}>
                    <button className="btn" onClick={() => remove(ch)}
                            style={{ fontSize: 11, padding: "3px 8px",
                                     color: "var(--short)", borderColor: "var(--short-dim)" }}>
                      <Icon name="x" size={10}/>
                    </button>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
    </div>
  );
};

// =====================================================================
// Admin-only: forwards (Channel A → формат → Channel B + PnL reply)
// =====================================================================

const ForwardsAdminSection = () => {
  const [me, setMe] = useState(null);
  const [channels, setChannels] = useState([]);
  const [forwards, setForwards] = useState([]);
  const [loading, setLoading] = useState(true);
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState("");
  const [srcId, setSrcId] = useState("");      // "" = catch-all
  const [destRef, setDestRef] = useState("");

  const reload = async () => {
    setLoading(true); setErr("");
    try {
      const [u, ch, fw] = await Promise.all([
        window.AUTH.me(),
        window.AUTH.listChannels(),
        window.AUTH.listForwards().catch(() => []), // 403 если не admin
      ]);
      setMe(u);
      setChannels(ch || []);
      setForwards(fw || []);
    } catch (e) {
      setErr(e.message);
    } finally { setLoading(false); }
  };
  useEffect(() => { reload(); }, []);

  // Non-admin → ничего не показываем
  if (!me || me.role !== "admin") {
    if (loading) return null;
    return null;
  }

  const add = async () => {
    setErr("");
    const ref = (destRef || "").trim();
    if (!ref) { setErr("Введите dest канал."); return; }
    setBusy(true);
    try {
      await window.AUTH.addForward({
        source_channel_id: srcId ? Number(srcId) : null,
        dest_channel_ref: ref,
      });
      setDestRef(""); setSrcId("");
      await reload();
    } catch (e) { setErr(e.message); }
    finally { setBusy(false); }
  };

  const toggle = async (f) => {
    setErr("");
    try {
      await window.AUTH.updateForward(f.id, { enabled: !f.enabled });
      await reload();
    } catch (e) { setErr(e.message); }
  };

  const remove = async (f) => {
    if (!confirm(`Удалить форвард → ${f.dest_channel_ref}?`)) return;
    setErr("");
    try {
      await window.AUTH.deleteForward(f.id);
      await reload();
    } catch (e) { setErr(e.message); }
  };

  const srcLabel = (fid) => {
    if (!fid) return "Любой канал (catch-all)";
    const c = channels.find(x => x.id === fid);
    return c ? `${c.channel_ref}${c.label ? " (" + c.label + ")" : ""}` : `#${fid}`;
  };

  return (
    <div style={{ marginTop: 18, paddingTop: 18, borderTop: "1px solid var(--border)" }}>
      <div className="section-title" style={{ marginBottom: 10 }}>
        <Icon name="repeat" size={11}/> Форварды сигналов (admin)
        <span className="count">{forwards.length}</span>
      </div>

      <div className="empty-hint" style={{ textAlign: "left", lineHeight: 1.5, marginBottom: 10 }}>
        Форвард: парсим сигнал из source-канала, форматируем и постим в dest.
        Когда сделка закроется (TP/SL) → reply с PnL-карточкой.
        Source = "catch-all" → применяется ко всем вашим source-каналам.
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "1.4fr 1.4fr auto", gap: 6, marginBottom: 6 }}>
        <select className="select" value={srcId} onChange={e => setSrcId(e.target.value)} disabled={busy}>
          <option value="">— Catch-all (любой канал) —</option>
          {channels.map(c => (
            <option key={c.id} value={c.id}>
              {c.channel_ref}{c.label ? " · " + c.label : ""}
            </option>
          ))}
        </select>
        <input className="input" placeholder="dest @channel или -100..."
               value={destRef} onChange={e => setDestRef(e.target.value)}
               disabled={busy}
               onKeyDown={e => e.key === "Enter" && add()}/>
        <button className="btn primary" onClick={add} disabled={busy || !destRef.trim()}>
          <Icon name="check" size={12}/> Добавить
        </button>
      </div>

      {err && <div className="auth-error" style={{ marginBottom: 8 }}>{err}</div>}

      {forwards.length === 0 ? (
        <div className="empty-hint" style={{ textAlign: "left", marginTop: 6 }}>
          Форвардов нет. Добавьте первый — сигналы начнут репоститься.
        </div>
      ) : (
        <div className="card" style={{ overflow: "auto" }}>
          <table className="tbl">
            <thead>
              <tr>
                <th>Source</th>
                <th>Dest</th>
                <th>Статус</th>
                <th></th>
              </tr>
            </thead>
            <tbody>
              {forwards.map(f => (
                <tr key={f.id}>
                  <td style={{ fontSize: 12 }}>{srcLabel(f.source_channel_id)}</td>
                  <td className="mono" style={{ fontSize: 12 }}>{f.dest_channel_ref}</td>
                  <td>
                    <button onClick={() => toggle(f)}
                            className={"switch" + (f.enabled ? " on" : "")}
                            title={f.enabled ? "Активен" : "Выключен"}/>
                  </td>
                  <td style={{ textAlign: "right" }}>
                    <button className="btn" onClick={() => remove(f)}
                            style={{ fontSize: 11, padding: "3px 8px",
                                     color: "var(--short)", borderColor: "var(--short-dim)" }}>
                      <Icon name="x" size={10}/>
                    </button>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
    </div>
  );
};

Object.assign(window, { TelegramSettingsModal });
