// M1–M5 + mini-modal. Rendered as overlays from app.jsx (no backdrop wrapper here).
// Each dialog reads state and dispatches actions via window.actions.

// ── Shared dialog frame ──────────────────────────────────────────────────
function Dialog({ width = 480, children, onClose }) {
  return (
    <div
      style={{
        position: "absolute", inset: 0,
        background: "rgba(13,17,26,.78)", backdropFilter: "blur(8px)",
        display: "grid", placeItems: "center", zIndex: 60, padding: 16, overflowY: "auto",
      }}
      onClick={(e) => { if (e.target === e.currentTarget) onClose && onClose(); }}
    >
      <div style={{
        width: "100%", maxWidth: width,
        background: "var(--bg-2)", border: "1px solid var(--border-strong)",
        borderRadius: 20, padding: 28, position: "relative",
        boxShadow: "0 30px 80px -20px rgba(0,0,0,.6)",
      }}>
        <button onClick={onClose} aria-label="Закрыть" style={{
          position: "absolute", top: 14, right: 14, width: 32, height: 32, borderRadius: 8,
          background: "transparent", border: "1px solid var(--border)", color: "var(--muted)",
          display: "grid", placeItems: "center", cursor: "pointer",
        }}>
          <Icons.x />
        </button>
        {children}
      </div>
    </div>
  );
}

// ── M1: Save URL + QR (one-time visible) ────────────────────────────────
function Modal_SaveLink() {
  const s = useAppState();
  const close = () => window.actions.closeModal();
  const data = s.lastUrl || {};
  const url = data.url || "";
  const mirrors = Array.isArray(data.mirrors) ? data.mirrors.filter((item) => item && (item.short_url || item.url)) : [];
  const label = data.label || "Устройство";
  const isPending = data.status === "pending_apply";
  const expires = s.entitlement?.expires_at ? window.fmtDate(s.entitlement.expires_at) : "";
  const [acknowledged, setAck] = React.useState(false);
  const hasUrl = !!url;

  React.useEffect(() => { setAck(false); }, [data.slotId]);

  const copyUrl = () => {
    if (!hasUrl) {
      window.actions.toast("Ссылка пока недоступна");
      return;
    }
    window.actions.copyToClipboard(url, "Ссылка скопирована");
  };

  // P1-5: download fallback — AWS/GitHub-style. Юзер может скачать как файл,
  // если боится потерять буфер обмена.
  const downloadAsFile = () => {
    const content = [
      "Fortune VPN — ссылка для подключения",
      "================================",
      `Устройство: ${label}`,
      `Ссылка: ${url}`,
      expires ? `Действует до: ${expires}` : "",
      `Создано: ${new Date().toLocaleString("ru-RU")}`,
      "",
      "Как подключить:",
      "  1. Установите V2Ray или Incy.",
      "  2. Откройте клиент → добавить подписку по URL.",
      "  3. Вставьте ссылку выше → подключитесь.",
      "",
      "Поддержка:",
      "  Telegram: @FortuneVPNsupportbot (https://t.me/FortuneVPNsupportbot)",
      "  Email:    support@fortunetavern.com",
    ].filter(Boolean).join("\n");
    const blob = new Blob([content], { type: "text/plain;charset=utf-8" });
    const a = document.createElement("a");
    a.href = URL.createObjectURL(blob);
    a.download = `fortune-vpn-${label.toLowerCase().replace(/[^a-z0-9]+/gi, "-") || "key"}.txt`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    setTimeout(() => URL.revokeObjectURL(a.href), 1000);
    window.actions.toast("Файл скачан");
  };

  return (
    <Dialog width={520} onClose={acknowledged ? close : null}>
      <h3 style={{ margin: "0 0 16px", fontSize: 22, fontWeight: 700, letterSpacing: "-0.02em", color: "#FFF", paddingRight: 36 }}>
        Сохраните ссылку
      </h3>

      <div style={{
        display: "flex", gap: 10, alignItems: "flex-start",
        padding: "12px 14px", borderRadius: 10, marginBottom: 18,
        background: "rgba(245,166,35,.10)", borderLeft: "3px solid var(--warning)",
        fontSize: 13.5, color: "var(--ink)", lineHeight: 1.5,
      }}>
        <span style={{ color: "var(--warning)", flexShrink: 0, marginTop: 1 }}><Icons.alert size={16} /></span>
        <span>Покажем эту ссылку только один раз — сохраните её сейчас. Если потеряете, придётся создать новую.</span>
      </div>

      <div style={{
        display: "flex", gap: 10, alignItems: "flex-start",
        padding: "12px 14px", borderRadius: 10, marginBottom: 18,
        background: "rgba(46,168,255,.08)", border: "1px solid rgba(46,168,255,.22)",
        fontSize: 13.5, color: "var(--ink)", lineHeight: 1.5,
      }}>
        <span style={{ color: "var(--accent-soft)", flexShrink: 0, marginTop: 1 }}><Icons.info size={16} /></span>
        <span>
          Это subscription URL, а не одиночный VLESS-ключ.
          В V2Ray/v2rayNG/v2rayN добавляйте его через раздел подписок или групп подписок, затем нажмите обновление подписки.
          {isPending ? " Если слот ещё в статусе «Готовится», клиент может показать ошибку до применения конфигурации на сервере." : ""}
        </span>
      </div>

      <div style={{
        display: "flex", alignItems: "center", gap: 8,
        padding: "10px 12px", borderRadius: 10, marginBottom: 14,
        background: "var(--panel)", border: "1px solid var(--border)",
      }}>
        <span className="mono" style={{ flex: 1, fontSize: 13, color: "var(--ink)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{url}</span>
        <button className="btn btn-ghost btn-sm" onClick={copyUrl} style={{ padding: "6px 10px" }}><Icons.copy size={14} /></button>
      </div>

      {mirrors.length ? (
        <div style={{
          padding: "10px 12px", borderRadius: 10, margin: "-4px 0 14px",
          background: "rgba(255,255,255,.03)", border: "1px solid var(--border)",
          fontSize: 12.5, color: "var(--muted)", lineHeight: 1.45,
        }}>
          <div style={{ color: "var(--ink)", fontWeight: 700, marginBottom: 6 }}>Резервные ссылки подписки</div>
          <div style={{ marginBottom: 8 }}>
            Используйте их только если основная ссылка не открывается у провайдера или в приложении.
          </div>
          <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
            {mirrors.map((mirror, index) => (
              <button
                key={`${mirror.base_url || "mirror"}-${index}`}
                className="btn btn-ghost btn-sm"
                onClick={() => window.actions.copyToClipboard(mirror.short_url || mirror.url, "Резервная ссылка скопирована")}
                style={{ justifyContent: "space-between", width: "100%", minWidth: 0 }}
              >
                <span className="mono" style={{ overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", minWidth: 0 }}>
                  {mirror.short_url || mirror.url}
                </span>
                <Icons.copy size={13} />
              </button>
            ))}
          </div>
        </div>
      ) : null}

      <div style={{ display: "flex", flexDirection: "column", gap: 8, marginBottom: 18 }}>
        <button className="btn btn-primary btn-block" onClick={copyUrl}><Icons.copy size={14} /> Скопировать ссылку</button>
        <div style={{ display: "flex", gap: 8 }}>
          <button className="btn btn-ghost" style={{ flex: 1 }} onClick={downloadAsFile}><Icons.download size={14} /> Файл (.txt)</button>
        </div>
        <div style={{ display: "flex", gap: 8 }}>
          <button className="btn btn-ghost" style={{ flex: 1 }} onClick={() => window.navigate("setup-v2ray")}>Инструкция V2Ray</button>
          <button className="btn btn-ghost" style={{ flex: 1 }} onClick={() => window.navigate("setup-incy")}>Инструкция Incy</button>
        </div>
      </div>

      <label style={{ display: "flex", alignItems: "center", gap: 10, padding: "10px 0", fontSize: 13.5, color: "var(--ink)", cursor: "pointer" }}>
        <input type="checkbox" checked={acknowledged} onChange={(e) => setAck(e.target.checked)} style={{ width: 18, height: 18, accentColor: "var(--accent)" }} />
        Я сохранил ссылку
      </label>

      <button
        className="btn btn-primary btn-block"
        disabled={!acknowledged}
        onClick={close}
        style={{ marginTop: 10, opacity: acknowledged ? 1 : 0.45, cursor: acknowledged ? "pointer" : "not-allowed" }}
      >
        Готово
      </button>
    </Dialog>
  );
}

// ── M2: Regenerate ──────────────────────────────────────────────────────
function Modal_Regenerate() {
  const s = useAppState();
  const busy = s.api?.pendingAction === "regenerate_slot";
  const close = () => window.actions.closeModal();
  return (
    <Dialog onClose={close}>
      <h3 style={{ margin: "0 0 12px", fontSize: 22, fontWeight: 700, letterSpacing: "-0.02em", color: "#FFF", paddingRight: 36 }}>
        Создать новую ссылку?
      </h3>
      <div style={{ fontSize: 14.5, color: "var(--muted)", lineHeight: 1.55 }}>
        Старая ссылка перестанет работать — на устройстве нужно будет вставить новую в V2Ray или Incy.
        Новую ссылку мы покажем <b style={{ color: "var(--ink)" }}>один раз</b>, сохраните её сразу.
      </div>
      <div style={{ display: "flex", justifyContent: "flex-end", gap: 10, marginTop: 22 }}>
        <button className="btn btn-ghost" onClick={close}>Отмена</button>
        <button className="btn btn-danger" disabled={busy} style={busy ? { opacity: 0.65, cursor: "wait" } : null} onClick={() => window.actions.confirmRegenerate()}>
          {busy ? "Создаем..." : "Создать новую"}
        </button>
      </div>
    </Dialog>
  );
}

// ── M3: Revoke slot ─────────────────────────────────────────────────────
function Modal_Revoke() {
  const s = useAppState();
  const busy = s.api?.pendingAction === "revoke_slot";
  const close = () => window.actions.closeModal();
  return (
    <Dialog onClose={close}>
      <h3 style={{ margin: "0 0 12px", fontSize: 22, fontWeight: 700, letterSpacing: "-0.02em", color: "#FFF", paddingRight: 36 }}>
        Отозвать ссылку?
      </h3>
      <div style={{ fontSize: 14.5, color: "var(--muted)", lineHeight: 1.55 }}>
        Эта ссылка перестанет работать. Если у вас есть вторая — она продолжит работать.
        Восстановить отозванную ссылку нельзя — можно только создать новую.
      </div>
      <div style={{ display: "flex", justifyContent: "flex-end", gap: 10, marginTop: 22 }}>
        <button className="btn btn-ghost" onClick={close}>Отмена</button>
        <button className="btn btn-danger" disabled={busy} style={busy ? { opacity: 0.65, cursor: "wait" } : null} onClick={() => window.actions.confirmRevoke()}>
          {busy ? "Отзываем..." : "Отозвать"}
        </button>
      </div>
    </Dialog>
  );
}

// ── M4: 2/2 limit ──────────────────────────────────────────────────────
function Modal_Limit() {
  const close = () => window.actions.closeModal();
  const lim = window.appState?.limits || {};
  const max = lim.max_external_slots ?? 2;
  return (
    <Dialog onClose={close}>
      <h3 style={{ margin: "0 0 12px", fontSize: 22, fontWeight: 700, letterSpacing: "-0.02em", color: "#FFF", paddingRight: 36 }}>
        Достигнут лимит ссылок
      </h3>
      <div style={{ fontSize: 14.5, color: "var(--muted)", lineHeight: 1.55 }}>
        В подписке доступно {max} {max === 1 ? "ссылка" : "ссылки"} V2Ray / Incy — все заняты. Чтобы создать новую, отзовите одну из текущих.
      </div>
      <div style={{ display: "flex", justifyContent: "flex-end", gap: 10, marginTop: 22 }}>
        <button className="btn btn-primary" onClick={close}>Понятно</button>
      </div>
    </Dialog>
  );
}

// ── M5: Delete account ──────────────────────────────────────────────────
function Modal_DeleteAccount() {
  const s = useAppState();
  const userEmail = s.user.email || "";
  const close = () => window.actions.closeModal();
  const [confirm, setConfirm] = React.useState("");
  const ok = userEmail && confirm.trim().toLowerCase() === userEmail.toLowerCase();
  return (
    <Dialog onClose={close}>
      <h3 style={{ margin: "0 0 12px", fontSize: 22, fontWeight: 700, letterSpacing: "-0.02em", color: "#FFF", paddingRight: 36 }}>
        Удалить аккаунт навсегда?
      </h3>
      <div style={{ fontSize: 14.5, color: "var(--muted)", lineHeight: 1.55, marginBottom: 12 }}>
        Восстановить аккаунт не получится. Произойдёт:
      </div>
      <ul style={{ margin: "0 0 16px", padding: "0 0 0 18px", fontSize: 13.5, color: "var(--muted)", display: "flex", flexDirection: "column", gap: 6 }}>
        <li>вы потеряете подписку до конца оплаченного срока — деньги не вернём</li>
        <li>реферальный баланс обнулится</li>
        <li>история платежей удалится</li>
      </ul>
      <div className="field" style={{ marginBottom: 18 }}>
        <label className="field-label">Введите ваш email для подтверждения</label>
        <input
          className="field-input"
          value={confirm}
          onChange={(e) => setConfirm(e.target.value)}
          placeholder={userEmail || "name@example.com"}
          style={{ width: "100%", background: "transparent", border: "none", outline: "none", color: "var(--ink)", fontSize: 14 }}
        />
      </div>
      <div style={{ display: "flex", justifyContent: "flex-end", gap: 10 }}>
        <button className="btn btn-ghost" onClick={close}>Отмена</button>
        <button className="btn btn-danger" disabled={!ok} style={!ok ? { opacity: 0.5, cursor: "not-allowed" } : null} onClick={() => { close(); window.actions.logout(); window.actions.toast("Аккаунт удалён"); }}>
          Удалить навсегда
        </button>
      </div>
    </Dialog>
  );
}

// ── Mini: Create new slot (asks for label) ─────────────────────────────
function Modal_NewSlot() {
  const s = useAppState();
  const busy = s.api?.pendingAction === "create_slot";
  const error = s.api?.lastError?.action === "create_slot" ? s.api.lastError.message : "";
  const close = () => window.actions.closeModal();
  return (
    <Dialog width={440} onClose={close}>
      <h3 style={{ margin: "0 0 16px", fontSize: 22, fontWeight: 700, letterSpacing: "-0.02em", color: "#FFF", paddingRight: 36 }}>
        Новая ссылка
      </h3>
      <div className="field" style={{ marginBottom: 18 }}>
        <label className="field-label">Название устройства (необязательно)</label>
        <input
          className="field-input"
          value={s.draft.newSlotLabel}
          onChange={(e) => window.actions.setNewSlotLabel(e.target.value)}
          placeholder="например, Ноутбук"
          autoFocus
          style={{ width: "100%", background: "transparent", border: "none", outline: "none", color: "var(--ink)", fontSize: 14 }}
        />
      </div>
      {error ? (
        <div style={{
          margin: "-6px 0 16px",
          padding: "10px 12px",
          borderRadius: 10,
          border: "1px solid rgba(255,107,107,.28)",
          background: "rgba(255,107,107,.08)",
          color: "var(--danger)",
          fontSize: 13,
          lineHeight: 1.45,
        }}>
          {error}
        </div>
      ) : null}
      <div style={{ display: "flex", justifyContent: "flex-end", gap: 10 }}>
        <button className="btn btn-ghost" onClick={close}>Отмена</button>
        <button className="btn btn-primary" disabled={busy} style={busy ? { opacity: 0.65, cursor: "wait" } : null} onClick={() => window.actions.createSlot()}>
          {busy ? "Создаем..." : "Создать ссылку"}
        </button>
      </div>
    </Dialog>
  );
}

Object.assign(window, {
  Modal_SaveLink, Modal_Regenerate, Modal_Revoke, Modal_Limit, Modal_DeleteAccount, Modal_NewSlot,
  Dialog,
});
