/* ============ PRO MODE — auth, subskrypcja, gating ============ */
/* global React, PrzelomAudio */

const { useState, useEffect, useRef } = React;

// ============================================================
// Sub helpers — localStorage-based mock weryfikacji.
// W produkcji: webhook Stripe → Supabase → JWT, sprawdzany serwerowo.
// ============================================================
const PRO_USER_KEY = "proUser";
const PRO_PLAN_KEY = "proPlan";
const PRO_SESSION_KEY = "proSession";

function loadProUser() {
  try {
    return JSON.parse(localStorage.getItem(PRO_USER_KEY) || "null");
  } catch {
    return null;
  }
}
function saveProUser(u) {
  localStorage.setItem(PRO_USER_KEY, JSON.stringify(u));
}
function loadProPlan() {
  try {
    return JSON.parse(localStorage.getItem(PRO_PLAN_KEY) || "null");
  } catch {
    return null;
  }
}
function saveProPlan(p) {
  localStorage.setItem(PRO_PLAN_KEY, JSON.stringify(p));
}
function isProActive(plan) {
  if (!plan || !plan.paid) return false;
  if (plan.lifetime) return true;
  return plan.expiresAt && plan.expiresAt > Date.now();
}
window.PRO = {
  loadUser: loadProUser,
  loadPlan: loadProPlan,
  isActive: () => isProActive(loadProPlan()),
  hash: (str) => {
    let h = 5381;
    for (let i = 0; i < str.length; i++) h = ((h << 5) + h) ^ str.charCodeAt(i);
    return (h >>> 0).toString(36);
  },
  // Persisted prefs per user — preferujemy backend (window.AUTH.prefs),
  // fallback na localStorage (legacy / offline).
  loadUserPrefs: () => {
    if (window.AUTH?.user && window.AUTH.prefs) return window.AUTH.prefs;
    const u = loadProUser();
    if (!u) return null;
    try {
      return JSON.parse(localStorage.getItem("proPrefs:" + u.email) || "null");
    } catch {
      return null;
    }
  },
  saveUserPrefs: (partial) => {
    if (window.AUTH?.user && window.AUTH.savePrefs) {
      window.AUTH.savePrefs(partial);
      return;
    }
    const u = loadProUser();
    if (!u) return;
    let cur = {};
    try {
      cur = JSON.parse(localStorage.getItem("proPrefs:" + u.email) || "{}");
    } catch {}
    const merged = { ...cur, ...partial };
    localStorage.setItem("proPrefs:" + u.email, JSON.stringify(merged));
  },
  // Desktop layout per user
  defaultDesktopPrefs: () => ({
    iconPositions: {},
    hiddenIcons: [],
    widgets: { quickLaunch: true, syslog: true, agentMesh: true },
    quickLaunchApps: [
      "prostudio",
      "ai",
      "portfolio",
      "stats",
      "doom",
      "contact",
    ],
    autostart: ["ai"],
  }),
  loadDesktopPrefs: () => {
    const prefs = window.PRO.loadUserPrefs() || {};
    return { ...window.PRO.defaultDesktopPrefs(), ...(prefs.desktop || {}) };
  },
  saveDesktopPrefs: (desktop) => {
    window.PRO.saveUserPrefs({ desktop });
    // Powiadom inne komponenty żeby odświeżyły stan natychmiast
    try {
      window.dispatchEvent(
        new CustomEvent("desk-prefs-changed", { detail: desktop }),
      );
    } catch {}
  },
};

// ============================================================
// PRO LOGIN MODAL — email + password (mock) + phone OTP (mock)
// Step 0: tabbed login/register
// Step 1: phone OTP confirmation (mock — kod 000000 zawsze OK lub dowolny 6-cyfrowy)
// Step 2: success → onLogin
// ============================================================
function ProLoginModal({ onLogin, onClose }) {
  const [step, setStep] = useState(0); // 0=auth, 1=otp, 2=done
  const [mode, setMode] = useState("login"); // login | register
  const [form, setForm] = useState({
    email: "",
    password: "",
    name: "",
    phone: "+48",
  });
  const [otp, setOtp] = useState("");
  const [err, setErr] = useState("");
  const [sentOtpAt, setSentOtpAt] = useState(0);

  const submit = () => {
    setErr("");
    if (!form.email || !form.email.includes("@")) {
      setErr("Wpisz prawidłowy email.");
      return;
    }
    if (form.password.length < 4) {
      setErr("Hasło min. 4 znaki.");
      return;
    }
    if (
      mode === "register" &&
      (!form.name || form.phone.replace(/\D/g, "").length < 9)
    ) {
      setErr("Wpisz imię i numer telefonu (min. 9 cyfr).");
      return;
    }
    PrzelomAudio.sounds.click();
    setSentOtpAt(Date.now());
    setStep(1);
  };

  const verifyOtp = () => {
    setErr("");
    if (otp.length !== 6 || !/^\d{6}$/.test(otp)) {
      setErr("Wpisz 6-cyfrowy kod.");
      return;
    }
    // Mock: każdy 6-cyfrowy kod jest OK (w prod: webhook → server-side weryfikacja)
    PrzelomAudio.sounds.levelup();
    const user = {
      email: form.email,
      name: form.name || form.email.split("@")[0],
      phone: form.phone,
      verifiedAt: Date.now(),
    };
    saveProUser(user);
    setStep(2);
    setTimeout(() => onLogin(user), 700);
  };

  const fakeGoogle = () => {
    PrzelomAudio.sounds.click();
    setForm((f) => ({
      ...f,
      email: "demo@gmail.com",
      name: "Demo Pro",
      password: "google",
    }));
    setSentOtpAt(Date.now());
    setStep(1);
  };

  return (
    <div className="pro-modal-overlay" onClick={onClose}>
      <div className="pro-modal" onClick={(e) => e.stopPropagation()}>
        <div className="pro-modal-head">
          <span className="pro-badge">★ PRO</span>
          <span className="pro-modal-title">
            {step === 0
              ? mode === "login"
                ? "Zaloguj się"
                : "Załóż konto"
              : step === 1
                ? "Potwierdź numer telefonu"
                : "Zalogowano"}
          </span>
          <button className="pro-modal-x" onClick={onClose}>
            ×
          </button>
        </div>

        {step === 0 && (
          <div className="pro-modal-body">
            <div className="pro-tabs">
              <button
                className={`pro-tab ${mode === "login" ? "active" : ""}`}
                onClick={() => setMode("login")}
              >
                LOGOWANIE
              </button>
              <button
                className={`pro-tab ${mode === "register" ? "active" : ""}`}
                onClick={() => setMode("register")}
              >
                REJESTRACJA
              </button>
            </div>
            <button className="pro-google" onClick={fakeGoogle}>
              <span className="pro-g-icon">G</span>
              Kontynuuj z Google
            </button>
            <div className="pro-or">— lub email —</div>
            {mode === "register" && (
              <input
                className="pro-input"
                placeholder="Imię"
                value={form.name}
                onChange={(e) => setForm({ ...form, name: e.target.value })}
              />
            )}
            <input
              className="pro-input"
              placeholder="Email"
              type="email"
              value={form.email}
              onChange={(e) => setForm({ ...form, email: e.target.value })}
            />
            <input
              className="pro-input"
              placeholder="Hasło"
              type="password"
              value={form.password}
              onChange={(e) => setForm({ ...form, password: e.target.value })}
            />
            {mode === "register" && (
              <input
                className="pro-input"
                placeholder="Numer telefonu (np. +48 ...)"
                value={form.phone}
                onChange={(e) => setForm({ ...form, phone: e.target.value })}
              />
            )}
            {err && <div className="pro-err">{err}</div>}
            <button className="pro-cta" onClick={submit}>
              {mode === "login" ? "ZALOGUJ" : "ZAREJESTRUJ"} →
            </button>
            <div className="pro-fineprint">
              Logowanie wymaga konta PRO z aktywną subskrypcją.
              <br />
              Nie masz konta? Otwórz aplikację{" "}
              <strong style={{ color: "#ffd24a" }}>"Przejdź na PRO"</strong> z
              pulpitu Klienta.
            </div>
          </div>
        )}

        {step === 1 && (
          <div className="pro-modal-body">
            <div className="pro-otp-info">
              Wysłaliśmy kod na <strong>{form.phone}</strong>.<br />
              <span style={{ opacity: 0.6, fontSize: 10 }}>
                Demo: dowolny 6-cyfrowy kod zadziała (np. 000000).
              </span>
            </div>
            <input
              className="pro-input pro-otp"
              placeholder="——————"
              maxLength={6}
              value={otp}
              onChange={(e) =>
                setOtp(e.target.value.replace(/\D/g, "").slice(0, 6))
              }
            />
            {err && <div className="pro-err">{err}</div>}
            <button className="pro-cta" onClick={verifyOtp}>
              POTWIERDŹ →
            </button>
            <button className="pro-back" onClick={() => setStep(0)}>
              ← wstecz
            </button>
          </div>
        )}

        {step === 2 && (
          <div className="pro-modal-body pro-success">
            <div className="pro-success-glyph">✓</div>
            <div className="pro-success-msg">Witaj w strefie PRO</div>
            <div className="pro-success-sub">
              Inicjalizacja środowiska premium…
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

// ============================================================
// "Twój Plan" — 3 tiery (FREE / PRO / EPIC) × 3 billing
// ============================================================
const TIERS = [
  {
    id: "free",
    name: "FREE",
    tagline: "Spróbuj jak to działa",
    color: "#9ec1c1",
    pricing: { monthly: 0, yearly: 0, lifetime: 0 },
    features: [
      "1 generacja PRO Studio / 24h",
      "5 poprawek / 24h",
      "AI LAB w trybie 'sales' — pomoc nawigacji + info o usługach",
      "Wszystkie aplikacje pulpitu",
      "Personalizacja layoutu, theme, tapeta",
    ],
    notIncluded: [
      "AI LAB nie pisze kodu, nie projektuje architektur",
      "Brak mentoringu 1:1 i konkretnych deliverables",
      "Brak prywatnych projektów ZAZA",
    ],
  },
  {
    id: "pro",
    name: "PRO",
    tagline: "Codzienny workhorse",
    color: "#caff33",
    pricing: { monthly: 49, yearly: 449, lifetime: 1499 },
    badge: "POPULARNY",
    features: [
      "20 generacji PRO Studio / tydzień",
      "100 poprawek / tydzień",
      "AI LAB w trybie 'mentor 1:1' — uczy step-by-step, pisze kod, projektuje architektury",
      "Pełna personalizacja: drag, widgety, autostart, custom Quick Launch",
      "Backup ustawień na koncie (cross-device)",
      "Prywatne projekty ZAZA (kod, configi, pipelines)",
      "Early access do nowych aplikacji i features",
    ],
    notIncluded: [
      "Limit 20/100 zamiast nieograniczonego",
      "Bez Direct Line do Jakuba",
      "Bez multi-agent orchestration i custom fine-tuningu",
    ],
  },
  {
    id: "epic",
    name: "EPIC",
    tagline: "Beyond limits — out of this world",
    color: "#ff66cc",
    pricing: { monthly: 199, yearly: 1999, lifetime: 4999 },
    badge: "EARLY ADOPTER",
    features: [
      "♾  Bez limitu PRO Studio (gen + ref)",
      "♾  Bez limitu AI LAB",
      "🛸 Multi-agent orchestration — 14 wyspecjalizowanych agentów",
      "🧬 Custom AI fine-tuning na twoich danych (RAG + reranking)",
      "🎯 Reverse-engineering konkurencji + auto counter-strategy",
      "📡 Direct Line do Jakuba — Telegram/Slack 24/7",
      "⚡ Concierge migration — wdrożenie ZAZA/OS u ciebie",
      "💎 Source code access — pełen kod każdego deliverable",
      "🚀 Q1 2036 features — eksperymenty zanim zobaczy je rynek",
      "🔮 Voice clone agent — twój głos w AI LAB",
      "🌐 White-label deployment — własna domena, własny branding",
    ],
  },
];

const BILLING_OPTIONS = [
  {
    id: "monthly",
    name: "Miesięcznie",
    short: "/mc",
    durationDays: 30,
    suffix: "co miesiąc, anuluj kiedy chcesz",
  },
  {
    id: "yearly",
    name: "Rocznie",
    short: "/rok",
    durationDays: 365,
    suffix: "oszczędzasz ~25% vs miesięczny",
  },
  {
    id: "lifetime",
    name: "Lifetime",
    short: "raz",
    durationDays: null,
    lifetime: true,
    suffix: "płacisz raz, masz na zawsze",
  },
];

function ProUpgradeApp({ onShutdown }) {
  const [view, setView] = useState("plans"); // plans | checkout | done
  const [billing, setBilling] = useState("yearly");
  const [selectedTier, setSelectedTier] = useState(null);
  const [selectedBilling, setSelectedBilling] = useState(null);
  const [processing, setProcessing] = useState(false);
  const currentPlan = window.PRO?.loadPlan?.() || null;
  const currentTier = currentPlan?.paid
    ? (currentPlan.tier || "pro").toLowerCase()
    : "free";

  const startCheckout = (tier, billingId) => {
    if (tier.id === "free") {
      // FREE = brak płatności, ewentualnie downgrade do free w prefs
      return;
    }
    const billOpt = BILLING_OPTIONS.find((b) => b.id === billingId);
    setSelectedTier(tier);
    setSelectedBilling(billOpt);
    setView("checkout");
  };

  const realPay = async () => {
    if (!window.AUTH?.user || !window.AUTH?.token) {
      alert("Zaloguj się żeby przejść do płatności.");
      return;
    }
    setProcessing(true);
    PrzelomAudio.sounds.boot();
    // Najpierw zweryfikuj sesję — odśwież AUTH.user i AUTH.token z backendu.
    // Jeśli token wygasł / niepoprawny, refresh() wyczyści sesję i wymusi re-login.
    try {
      const refreshed = await window.AUTH.refresh?.();
      if (!refreshed || !window.AUTH?.token) {
        alert("Sesja wygasła. Zaloguj się ponownie i spróbuj jeszcze raz.");
        setProcessing(false);
        // Zamknij wszystkie okienka i otwórz auth wall przez emit
        if (window.PrzelomBus) window.PrzelomBus.emit("shutdown");
        return;
      }
    } catch {
      // network blip — kontynuuj, backend zwróci 401 jeśli problem
    }
    try {
      const res = await fetch("/api/stripe-checkout", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "X-Auth-Token": window.AUTH.token,
        },
        body: JSON.stringify({
          tier: selectedTier.id,
          billing: selectedBilling.id,
        }),
      });
      const data = await res.json();
      if (!res.ok || !data.url) {
        // 401 = niepoprawna sesja — zaloguj ponownie
        if (res.status === 401) {
          alert(
            "Sesja wygasła. Wyloguj się i zaloguj ponownie, potem spróbuj jeszcze raz.",
          );
        } else {
          alert(
            "Błąd Stripe: " +
              (data.message || data.error || res.statusText) +
              "\n\nKod: " +
              data.error,
          );
        }
        setProcessing(false);
        return;
      }
      // Redirect na hosted Stripe Checkout
      window.location.href = data.url;
    } catch (e) {
      alert("Błąd sieci: " + e.message);
      setProcessing(false);
    }
  };

  return (
    <div className="app-pro-upgrade">
      {view === "plans" && (
        <>
          <div className="pup-hero">
            <span className="pup-badge">▣ TWÓJ PLAN</span>
            <h1 className="pup-h1">
              Wybierz poziom <em>mocy</em>.
            </h1>
            <p className="pup-lead">
              Trzy plany. Trzy modele rozliczania. Wybierz to, co pasuje do
              skali twojego ruchu.
            </p>
          </div>

          <div className="pup-billing-toggle">
            {BILLING_OPTIONS.map((b) => (
              <button
                key={b.id}
                className={`pup-billing-btn ${billing === b.id ? "active" : ""}`}
                onClick={() => setBilling(b.id)}
              >
                {b.name}
              </button>
            ))}
          </div>

          <div className="pup-tiers">
            {TIERS.map((t) => {
              const price = t.pricing[billing];
              const isCurrent = currentTier === t.id;
              const billOpt = BILLING_OPTIONS.find((b) => b.id === billing);
              return (
                <div
                  key={t.id}
                  className={`pup-tier pup-tier-${t.id} ${t.badge ? "highlight" : ""}`}
                  style={{ "--tier-color": t.color }}
                >
                  {t.badge && <div className="pup-tier-badge">{t.badge}</div>}
                  <div className="pup-tier-name" style={{ color: t.color }}>
                    {t.name}
                  </div>
                  <div className="pup-tier-tagline">{t.tagline}</div>
                  <div className="pup-tier-price">
                    {price === 0 ? (
                      <span className="pup-tier-amt">0</span>
                    ) : (
                      <span className="pup-tier-amt">{price}</span>
                    )}
                    <span className="pup-tier-cur">PLN</span>
                    <span className="pup-tier-per">{billOpt.short}</span>
                  </div>
                  <div className="pup-tier-sub">{billOpt.suffix}</div>
                  <ul className="pup-tier-features">
                    {t.features.map((f, i) => (
                      <li key={i}>{f}</li>
                    ))}
                  </ul>
                  {t.notIncluded && (
                    <ul className="pup-tier-features-out">
                      {t.notIncluded.map((f, i) => (
                        <li key={i}>{f}</li>
                      ))}
                    </ul>
                  )}
                  {isCurrent ? (
                    <button className="pup-tier-cta current" disabled>
                      AKTUALNY PLAN
                    </button>
                  ) : t.id === "free" ? (
                    <button className="pup-tier-cta free" disabled>
                      Domyślny start
                    </button>
                  ) : (
                    <button
                      className="pup-tier-cta"
                      onClick={() => startCheckout(t, billing)}
                    >
                      WYBIERZ {t.name} →
                    </button>
                  )}
                </div>
              );
            })}
          </div>
        </>
      )}

      {view === "checkout" && selectedTier && selectedBilling && (
        <div className="pup-checkout">
          <div className="pup-hero">
            <span className="pup-badge">
              ▣ {selectedTier.name} · {selectedBilling.name.toUpperCase()}
            </span>
            <h1 className="pup-h1">
              {selectedTier.pricing[selectedBilling.id]} PLN{" "}
              {selectedBilling.short}
            </h1>
            <p className="pup-lead">{selectedBilling.suffix}</p>
          </div>
          <div className="pup-stripe-mock">
            <div className="pup-stripe-info">
              🔒 Płatność obsługiwana przez <strong>Stripe</strong>. Po
              kliknięciu przekierujemy cię na bezpieczną stronę Stripe — karta,
              BLIK lub Przelewy24.
              <br />
              <span
                style={{
                  opacity: 0.6,
                  fontSize: 10,
                  marginTop: 8,
                  display: "block",
                }}
              >
                <strong>TEST MODE:</strong> użyj karty{" "}
                <code style={{ color: "var(--accent)" }}>
                  4242 4242 4242 4242
                </code>
                , dowolne MM/YY w przyszłości, dowolne CVC. Żadna prawdziwa
                karta nie zostanie obciążona.
              </span>
            </div>
            <button
              className="pup-cta pup-pay"
              onClick={realPay}
              disabled={processing}
            >
              {processing
                ? "ŁĄCZĘ ZE STRIPE…"
                : `PRZEJDŹ DO PŁATNOŚCI · ${selectedTier.pricing[selectedBilling.id]} PLN`}
            </button>
          </div>
          <button className="pup-back" onClick={() => setView("plans")}>
            ← wróć do planów
          </button>
        </div>
      )}

      {view === "done" && selectedTier && (
        <div className="pup-success">
          <div className="pup-success-glyph">✓</div>
          <h1 className="pup-h1">Plan {selectedTier.name} aktywny.</h1>
          <p className="pup-lead">
            Twoje konto zostało zaktualizowane do planu{" "}
            <strong style={{ color: selectedTier.color }}>
              {selectedTier.name}
            </strong>{" "}
            ·{" "}
            <strong style={{ color: selectedTier.color }}>
              {selectedBilling.name}
            </strong>
            .
          </p>
          <div className="pup-next-steps">
            <div className="pup-step">
              1. Limity od razu zwiększone na koncie
            </div>
            <div className="pup-step">
              2. Otwórz PRO Studio i kontynuuj z większą quotą
              {selectedTier.id === "epic" ? " — bez limitów ♾" : ""}
            </div>
            {selectedTier.id === "epic" && (
              <div className="pup-step">
                3. Zaproszenie do prywatnego Telegrama trafi na maila w 5 min
              </div>
            )}
          </div>
          <button className="pup-cta" onClick={() => setView("plans")}>
            WRÓĆ DO PLANÓW
          </button>
        </div>
      )}
    </div>
  );
}

// ============================================================
// PRO STATUS PANEL — pokazywany w zalogowanym pro mode
// (mała aplikacja gdzie user widzi status konta + persistowane prefs)
// ============================================================
function ProAccountApp() {
  const user = loadProUser();
  const plan = loadProPlan();
  const active = isProActive(plan);
  const expires = plan?.expiresAt
    ? new Date(plan.expiresAt).toLocaleDateString("pl-PL")
    : "—";

  const logout = () => {
    if (
      confirm("Wylogować z konta PRO? Trzeba będzie zalogować się ponownie.")
    ) {
      localStorage.removeItem(PRO_USER_KEY);
      // plan zostaje (subskrypcja nie znika z wylogowaniem)
      window.location.reload();
    }
  };

  return (
    <div className="app-pro-account">
      <div className="pup-hero">
        <span className="pup-badge">★ KONTO PRO</span>
        <h1 className="pup-h1">{user?.name || user?.email || "Brak danych"}</h1>
      </div>
      <div className="pa-grid">
        <div className="pa-row">
          <span className="pa-l">Email</span>
          <span className="pa-r">{user?.email || "—"}</span>
        </div>
        <div className="pa-row">
          <span className="pa-l">Telefon</span>
          <span className="pa-r">{user?.phone || "—"}</span>
        </div>
        <div className="pa-row">
          <span className="pa-l">Plan</span>
          <span className="pa-r">{plan?.plan || "—"}</span>
        </div>
        <div className="pa-row">
          <span className="pa-l">Status</span>
          <span
            className="pa-r"
            style={{ color: active ? "#5aff5a" : "#ff5577" }}
          >
            {active ? "AKTYWNY" : "NIEAKTYWNY"}
          </span>
        </div>
        <div className="pa-row">
          <span className="pa-l">{plan?.lifetime ? "Lifetime" : "Wygasa"}</span>
          <span className="pa-r">
            {plan?.lifetime ? "✓ na zawsze" : expires}
          </span>
        </div>
        <div className="pa-row">
          <span className="pa-l">Zalogowany od</span>
          <span className="pa-r">
            {user?.verifiedAt
              ? new Date(user.verifiedAt).toLocaleDateString("pl-PL")
              : "—"}
          </span>
        </div>
      </div>
      {!active && (
        <div className="pa-warn">
          ⚠ Twoja subskrypcja wygasła. Funkcje PRO są ograniczone do read-only.
          <br />
          Otwórz "Przejdź na PRO" żeby odnowić.
        </div>
      )}
      <AgentZazaSection />
      <button className="pup-back" onClick={logout}>
        WYLOGUJ Z KONTA PRO
      </button>
    </div>
  );
}

// ============================================================
// AGENT ZAZA — section visible to EPIC plan only.
// Lets the user pair a CLI session by entering the user_code.
// ============================================================
function AgentZazaSection() {
  const tier =
    (window.AUTH?.getActiveTier && window.AUTH.getActiveTier().tier) || "free";
  const isEpic = tier === "epic";
  const [code, setCode] = useState("");
  const [busy, setBusy] = useState(false);
  const [info, setInfo] = useState("");
  const [err, setErr] = useState("");
  const [paired, setPaired] = useState(false);
  const autoTriedRef = useRef(false);

  // Pull the user_code from either ?agent=... (direct landing) or the
  // localStorage stash that main.jsx set when the OS booted. Whichever fires
  // first wins. Both sources are cleared after consumption so a refresh does
  // not retry a stale code.
  useEffect(() => {
    let q = null;
    try {
      const u = new URL(window.location.href);
      q = u.searchParams.get("agent");
      if (q) {
        u.searchParams.delete("agent");
        window.history.replaceState({}, "", u.toString());
      }
    } catch {}
    if (!q) {
      try {
        q = localStorage.getItem("__pz_agent_pending");
      } catch {}
    }
    if (q) setCode(q.toUpperCase().trim());
  }, []);

  const submit = async (codeOverride) => {
    if (!isEpic) return;
    const c = (codeOverride || code).trim().toUpperCase();
    if (!c) return;
    setBusy(true);
    setErr("");
    setInfo("");
    try {
      const res = await fetch("/api/agent", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "X-Auth-Token": window.AUTH?.token || "",
        },
        body: JSON.stringify({ action: "auth-confirm", user_code: c }),
      });
      const d = await res.json();
      if (d.ok) {
        setInfo("Sparowano. CLI dokończy login automatycznie.");
        setCode("");
        setPaired(true);
        try {
          localStorage.removeItem("__pz_agent_pending");
        } catch {}
      } else {
        const ERR_MAP = {
          epic_required: "Wymagany plan EPIC dla Agent ZAZA.",
          code_expired_or_unknown:
            "Kod wygasł lub nieznany. Uruchom: agent-zaza login (nowy kod).",
          not_pending: "Ten kod został już użyty.",
          missing_user_code: "Brak kodu — wpisz lub odśwież stronę.",
          invalid_session: "Sesja wygasła — zaloguj się ponownie.",
        };
        setErr(ERR_MAP[d.error] || "Błąd: " + (d.error || "confirm_failed"));
      }
    } catch (e) {
      setErr("Błąd sieci: " + e.message);
    } finally {
      setBusy(false);
    }
  };

  // Auto-submit the moment we have both: a code in state AND an EPIC tier.
  // Run once per mount so a failed submit lets the user inspect the error and
  // retry manually.
  useEffect(() => {
    if (autoTriedRef.current) return;
    if (!code) return;
    if (!isEpic) return;
    autoTriedRef.current = true;
    const t = setTimeout(() => submit(code), 700);
    return () => clearTimeout(t);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [code, isEpic]);

  if (!isEpic) {
    return (
      <div
        style={{
          marginTop: 24,
          padding: 14,
          border: "1px dashed rgba(var(--accent-rgb)/0.4)",
          borderRadius: 3,
          background: "rgba(0,0,0,0.3)",
        }}
      >
        <div
          style={{
            fontSize: 9,
            letterSpacing: "0.2em",
            color: "var(--fg-dim)",
            marginBottom: 6,
          }}
        >
          ⚡ AGENT ZAZA · WYMAGA EPIC
        </div>
        <div style={{ fontSize: 11, color: "var(--fg-dim)" }}>
          CLI agent (terminal) jest dostępny tylko dla planu EPIC. Twój plan:{" "}
          <b>{tier.toUpperCase()}</b>.
        </div>
      </div>
    );
  }

  return (
    <div
      style={{
        marginTop: 24,
        padding: 16,
        border: "1px solid var(--accent)",
        borderRadius: 3,
        background: "rgba(var(--accent-rgb)/0.06)",
      }}
    >
      <div
        style={{
          fontSize: 9,
          letterSpacing: "0.2em",
          color: "var(--accent)",
          marginBottom: 6,
        }}
      >
        ⚡ AGENT ZAZA · CLI W TERMINALU
      </div>
      <div style={{ fontSize: 11, lineHeight: 1.6, marginBottom: 10 }}>
        Pełnowymiarowy agent AI w Twoim terminalu — edycja kodu, eksploracja
        repo, integracja z przeglądarką, pamięć między sesjami. Rate limit 60
        req/min. Token zapisany w{" "}
        <code style={{ color: "var(--accent)" }}>
          ~/.config/agent-zaza/credentials.json
        </code>
        .
      </div>
      <pre
        style={{
          background: "#000",
          padding: 10,
          fontSize: 11,
          fontFamily: "var(--mono)",
          color: "var(--accent)",
          borderRadius: 2,
          overflowX: "auto",
        }}
      >
        {
          '# Instalacja (one-liner — Linux/macOS)\ncurl -fsSL https://raw.githubusercontent.com/sotius1/agent-zaza/main/install.sh | bash\n\n# Login — te same email + hasło co tutaj\nagent-zaza login\n\n# Uruchomienie agenta (REPL)\nagent-zaza\n\n# Jednorazowe pytanie\nagent-zaza -q "napisz funkcję sortującą tablicę"\n\n# Repo: https://github.com/sotius1/agent-zaza'
        }
      </pre>
      <div
        style={{
          marginTop: 14,
          paddingTop: 14,
          borderTop: "1px solid rgba(var(--accent-rgb)/0.2)",
        }}
      >
        {paired ? (
          <div
            style={{
              padding: 14,
              border: "1px solid var(--accent)",
              background: "rgba(var(--accent-rgb)/0.12)",
              borderRadius: 3,
              textAlign: "center",
            }}
          >
            <div
              style={{ fontSize: 28, color: "var(--accent)", marginBottom: 6 }}
            >
              ✓
            </div>
            <div
              style={{
                fontSize: 12,
                fontWeight: 700,
                letterSpacing: "0.18em",
                color: "var(--accent)",
              }}
            >
              ZAUTORYZOWANO
            </div>
            <div
              style={{
                fontSize: 10,
                color: "var(--fg-dim)",
                marginTop: 6,
                lineHeight: 1.5,
              }}
            >
              Wróć do terminala — <code>agent-zaza</code> kończy login.
            </div>
          </div>
        ) : (
          <>
            <div
              style={{ fontSize: 10, marginBottom: 6, color: "var(--fg-dim)" }}
            >
              Wpisz kod wyświetlony przez CLI (po <code>agent-zaza login</code>
              ):
            </div>
            <div style={{ display: "flex", gap: 8 }}>
              <input
                value={code}
                onChange={(e) => setCode(e.target.value.toUpperCase())}
                placeholder="XXXX-XXXX"
                className="auth-input"
                style={{
                  fontFamily: "var(--mono)",
                  letterSpacing: "0.2em",
                  flex: 1,
                }}
              />
              <button
                className="auth-btn"
                onClick={() => submit()}
                disabled={busy || !code.trim()}
              >
                {busy ? "..." : "POTWIERDŹ"}
              </button>
            </div>
            {err && <div className="auth-error">{err}</div>}
            {info && <div className="auth-info">{info}</div>}
          </>
        )}
      </div>
    </div>
  );
}

// ============================================================
// DESKTOP PREFS PANEL — Settings → ★ PULPIT (PRO only)
// Edycja: widgets visibility, Quick Launch list, autostart, reset positions
// ============================================================
function DesktopPrefsPanel() {
  const [prefs, setPrefs] = useState(() => window.PRO.loadDesktopPrefs());
  const apps = window.APP_REGISTRY || [];
  const launchableApps = apps.filter(
    (a) => !["notepad", "upgrade"].includes(a.id) && !a.hidden,
  );

  const update = (partial) => {
    setPrefs((prev) => {
      const next = { ...prev, ...partial };
      window.PRO.saveDesktopPrefs(next);
      return next;
    });
  };
  // Synchronizacja gdy prefs zmieniają się gdzie indziej (np. drag na pulpicie)
  useEffect(() => {
    const handler = (e) => {
      if (e.detail) setPrefs(e.detail);
    };
    window.addEventListener("desk-prefs-changed", handler);
    return () => window.removeEventListener("desk-prefs-changed", handler);
  }, []);

  const toggleWidget = (key) => {
    update({ widgets: { ...prefs.widgets, [key]: !prefs.widgets[key] } });
  };
  const toggleQuickLaunch = (appId) => {
    const list = prefs.quickLaunchApps.includes(appId)
      ? prefs.quickLaunchApps.filter((a) => a !== appId)
      : [...prefs.quickLaunchApps, appId];
    update({ quickLaunchApps: list });
  };
  const toggleAutostart = (appId) => {
    const list = prefs.autostart.includes(appId)
      ? prefs.autostart.filter((a) => a !== appId)
      : [...prefs.autostart, appId];
    update({ autostart: list });
  };
  const toggleIconVisible = (appId) => {
    const hidden = prefs.hiddenIcons || [];
    const list = hidden.includes(appId)
      ? hidden.filter((a) => a !== appId)
      : [...hidden, appId];
    update({ hiddenIcons: list });
  };
  const resetPositions = () => {
    if (confirm("Zresetować pozycje ikon na pulpicie?")) {
      update({ iconPositions: {} });
    }
  };

  return (
    <>
      <div className="settings-section-h" style={{ color: "#ffd24a" }}>
        ★ Personalizacja pulpitu
      </div>
      <div
        style={{
          fontSize: 10,
          color: "var(--fg-dim)",
          marginBottom: 14,
          lineHeight: 1.5,
        }}
      >
        Twoje ustawienia zapisują się automatycznie na koncie. Po wylogowaniu i
        powrocie wszystko wraca jak zostawiłeś.
      </div>

      <div className="settings-section-h" style={{ marginTop: 18 }}>
        Widgety pulpitu
      </div>
      <div className="settings-row">
        <div className="settings-row-l">
          <div className="settings-row-name">Quick Launch (lewy górny)</div>
          <div className="settings-row-desc">Lista najczęstszych aplikacji</div>
        </div>
        <button
          className={`toggle-btn ${prefs.widgets.quickLaunch ? "on" : ""}`}
          onClick={() => toggleWidget("quickLaunch")}
        >
          {prefs.widgets.quickLaunch ? "ON" : "OFF"}
        </button>
      </div>
      <div className="settings-row">
        <div className="settings-row-l">
          <div className="settings-row-name">System log (prawy górny)</div>
          <div className="settings-row-desc">Live feed eventów systemowych</div>
        </div>
        <button
          className={`toggle-btn ${prefs.widgets.syslog ? "on" : ""}`}
          onClick={() => toggleWidget("syslog")}
        >
          {prefs.widgets.syslog ? "ON" : "OFF"}
        </button>
      </div>
      <div className="settings-row">
        <div className="settings-row-l">
          <div className="settings-row-name">Agent Mesh (lewy dolny)</div>
          <div className="settings-row-desc">Status agentów i statystyki</div>
        </div>
        <button
          className={`toggle-btn ${prefs.widgets.agentMesh ? "on" : ""}`}
          onClick={() => toggleWidget("agentMesh")}
        >
          {prefs.widgets.agentMesh ? "ON" : "OFF"}
        </button>
      </div>

      <div className="settings-section-h" style={{ marginTop: 22 }}>
        Ikony na pulpicie
      </div>
      <div style={{ fontSize: 10, color: "var(--fg-dim)", marginBottom: 8 }}>
        Domyślnie pokazane są wszystkie aplikacje. Odznacz te, których nie
        chcesz widzieć na pulpicie — zmiana jest natychmiastowa.
      </div>
      <div className="dpp-grid">
        {launchableApps.map((a) => {
          const visible = !(prefs.hiddenIcons || []).includes(a.id);
          return (
            <button
              key={a.id}
              className={`dpp-chip ${visible ? "on" : ""}`}
              onClick={() => toggleIconVisible(a.id)}
            >
              {visible ? "✓" : "✗"} {a.title}
            </button>
          );
        })}
      </div>

      <div className="settings-section-h" style={{ marginTop: 22 }}>
        Quick Launch — pinned apps
      </div>
      <div className="dpp-grid">
        {launchableApps.map((a) => {
          const on = prefs.quickLaunchApps.includes(a.id);
          return (
            <button
              key={a.id}
              className={`dpp-chip ${on ? "on" : ""}`}
              onClick={() => toggleQuickLaunch(a.id)}
            >
              {on ? "✓" : "+"} {a.title}
            </button>
          );
        })}
      </div>

      <div className="settings-section-h" style={{ marginTop: 22 }}>
        Autostart aplikacji
      </div>
      <div style={{ fontSize: 10, color: "var(--fg-dim)", marginBottom: 8 }}>
        Te aplikacje uruchomią się automatycznie po booting w trybie PRO.
      </div>
      <div className="dpp-grid">
        {launchableApps.map((a) => {
          const on = prefs.autostart.includes(a.id);
          return (
            <button
              key={a.id}
              className={`dpp-chip ${on ? "on" : ""}`}
              onClick={() => toggleAutostart(a.id)}
            >
              {on ? "✓" : "+"} {a.title}
            </button>
          );
        })}
      </div>

      <div className="settings-section-h" style={{ marginTop: 22 }}>
        Reset
      </div>
      <div className="settings-row">
        <div className="settings-row-l">
          <div className="settings-row-name">Pozycje ikon na pulpicie</div>
          <div className="settings-row-desc">
            Wraca do default grid (lewy górny)
          </div>
        </div>
        <button
          className="toggle-btn"
          onClick={resetPositions}
          style={{ borderColor: "var(--red)", color: "var(--red)" }}
        >
          ZRESETUJ
        </button>
      </div>
    </>
  );
}

// ============================================================
// EXPORTS
// ============================================================
Object.assign(window, {
  ProLoginModal,
  ProUpgradeApp,
  ProAccountApp,
  DesktopPrefsPanel,
});
