// ─────────────────────────────────────────────────────────────────────────
// app.jsx — KreditEU shell, routing, theme, tweaks
// ─────────────────────────────────────────────────────────────────────────

const { useState: useStateApp, useEffect: useEffectApp, useMemo: useMemoApp } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "aurora",
  "mode": "dark",
  "tileLayout": "bento",
  "primaryHue": 80,
  "showTicker": true,
  "showAds": true
}/*EDITMODE-END*/;

const SUPPORTED_LANGS = ["pl", "en", "de", "fr", "cs", "hu", "nl"];
const SEO_ROUTES = new Set(["home", "mortgage", "cash", "banks", "markets", "programs", "articles", "article", "faq", "contact", "privacy", "terms", "cookies", "admin"]);

function normalizeLang(lang) {
  const l = (lang || "").toLowerCase();
  return SUPPORTED_LANGS.includes(l) ? l : null;
}

function normalizeCountry(code) {
  const c = (code || "").toLowerCase();
  if (!c) return null;
  return ({ gb: "uk" }[c] || c);
}

function parseRouteFromUrl() {
  try {
    const q = new URLSearchParams(window.location.search);
    const page = q.get("page");
    if (page === "article") {
      const id = Math.max(1, parseInt(q.get("id") || "1", 10) || 1);
      return { name: "article", id };
    }
    if (page && SEO_ROUTES.has(page)) return page;
    return null;
  } catch {
    return null;
  }
}

function parseLangFromUrl() {
  try {
    const q = new URLSearchParams(window.location.search);
    return normalizeLang(q.get("lang"));
  } catch {
    return null;
  }
}

function buildStateUrl(origin, lang, routeName, routeData = null) {
  const q = new URLSearchParams();
  if (lang) q.set("lang", lang);
  if (routeName && routeName !== "home") q.set("page", routeName);
  if (routeName === "article") q.set("id", String(routeData?.id || 1));
  const qs = q.toString();
  return `${origin}/${qs ? `?${qs}` : ""}`;
}

function setMetaTag(kind, key, value) {
  if (!value) return;
  let tag = document.head.querySelector(`meta[${kind}="${key}"]`);
  if (!tag) {
    tag = document.createElement("meta");
    tag.setAttribute(kind, key);
    document.head.appendChild(tag);
  }
  tag.setAttribute("content", value);
}

function applySeo({ routeName, routeData, lang }) {
  const t = (key, fb) => window.t(lang, key, fb);
  const pageTitleByRoute = {
    home: t("hero.title1", "Credit Calculator"),
    mortgage: t("pages.mortgage.title", "Mortgage Calculator"),
    cash: t("pages.cash.title", "Cash Loan Calculator"),
    banks: t("pages.banks.title", "Compare Bank Rates"),
    markets: t("pages.markets.title", "Reference Indicators"),
    programs: t("pages.programs.title", "Government Programs"),
    articles: t("pages.articles.title", "Credit Guides"),
    article: t("pages.article.calcCard", "Credit Guide"),
    faq: t("pages.faq.title", "FAQ"),
    contact: t("pages.contact.title", "Contact"),
    privacy: t("pages.legal.privacyTitle", "Privacy Policy"),
    terms: t("pages.legal.termsTitle", "Terms of Service"),
    cookies: t("footer.cookies", "Cookie Policy"),
  };

  const pageTitle = pageTitleByRoute[routeName] || "KreditEU";
  const title = `${pageTitle} | KreditEU`;
  const description = t(
    "footer.brand",
    "Free credit calculator for 30 countries in Europe. Compare banks, rates, and loan options with AI insights."
  );
  const isIndexable = routeName !== "admin";
  const origin = window.location.origin;
  const canonical = buildStateUrl(origin, lang, routeName, routeData);

  document.title = title;
  setMetaTag("name", "description", description);
  setMetaTag("property", "og:title", title);
  setMetaTag("property", "og:description", description);
  setMetaTag("property", "og:type", "website");
  setMetaTag("property", "og:url", canonical);
  setMetaTag("name", "twitter:card", "summary_large_image");
  setMetaTag("name", "twitter:title", title);
  setMetaTag("name", "twitter:description", description);
  setMetaTag("name", "robots", isIndexable ? "index,follow,max-image-preview:large" : "noindex,nofollow");

  let canonicalTag = document.getElementById("kr-canonical");
  if (!canonicalTag) {
    canonicalTag = document.createElement("link");
    canonicalTag.id = "kr-canonical";
    canonicalTag.rel = "canonical";
    document.head.appendChild(canonicalTag);
  }
  canonicalTag.href = canonical;

  document.head.querySelectorAll("link[data-kr-hreflang='1']").forEach(n => n.remove());
  if (isIndexable) {
    SUPPORTED_LANGS.forEach((code) => {
      const link = document.createElement("link");
      link.rel = "alternate";
      link.hreflang = code;
      link.href = buildStateUrl(origin, code, routeName, routeData);
      link.setAttribute("data-kr-hreflang", "1");
      document.head.appendChild(link);
    });
    const xDefault = document.createElement("link");
    xDefault.rel = "alternate";
    xDefault.hreflang = "x-default";
    xDefault.href = buildStateUrl(origin, "en", routeName, routeData);
    xDefault.setAttribute("data-kr-hreflang", "1");
    document.head.appendChild(xDefault);
  }

  const ldGraph = [
    {
      "@type": "Organization",
      "@id": "https://krediteu.com/#org",
      "name": "KreditEU",
      "url": "https://krediteu.com/",
      "contactPoint": [{ "@type": "ContactPoint", "contactType": "customer support", "email": "kontakt@krediteu.com" }],
    },
    {
      "@type": "WebSite",
      "@id": "https://krediteu.com/#website",
      "url": "https://krediteu.com/",
      "name": "KreditEU",
      "inLanguage": lang,
      "potentialAction": {
        "@type": "SearchAction",
        "target": "https://krediteu.com/?lang=" + lang + "&page=articles&query={search_term_string}",
        "query-input": "required name=search_term_string"
      }
    },
    {
      "@type": "WebPage",
      "@id": canonical + "#webpage",
      "url": canonical,
      "name": title,
      "description": description,
      "inLanguage": lang,
      "isPartOf": { "@id": "https://krediteu.com/#website" }
    }
  ];

  if (routeName === "article" && window.ARTICLES?.length) {
    const article = window.ARTICLES.find((x) => x.id === (routeData?.id || 1));
    if (article) {
      ldGraph.push({
        "@type": "Article",
        "@id": `${canonical}#article`,
        "headline": article.title,
        "description": article.excerpt || description,
        "author": { "@type": "Organization", "name": "KreditEU Editorial" },
        "publisher": { "@id": "https://krediteu.com/#org" },
        "mainEntityOfPage": canonical,
        "inLanguage": lang
      });
    }
  }

  const ld = {
    "@context": "https://schema.org",
    "@graph": ldGraph
  };
  let ldNode = document.getElementById("kr-jsonld");
  if (!ldNode) {
    ldNode = document.createElement("script");
    ldNode.type = "application/ld+json";
    ldNode.id = "kr-jsonld";
    document.head.appendChild(ldNode);
  }
  ldNode.textContent = JSON.stringify(ld);
}

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);

  /* ───── Persistent app state (localStorage) ───── */
  // Wstępny fallback: navigator.language jeśli pierwszy raz, potem auto-detect ulepsza
  const detectInitialLang = () => {
    const fromUrl = parseLangFromUrl();
    if (fromUrl) return fromUrl;
    const stored = normalizeLang(readLS("kr_lang", null));
    if (stored) return stored;
    const browserLang = (navigator.language || navigator.userLanguage || "pl").slice(0, 2).toLowerCase();
    return normalizeLang(browserLang) || "pl";
  };
  const detectInitialCountry = (initialLang) => {
    const stored = normalizeCountry(readLS("kr_country", null));
    if (stored) return stored;
    const langToCountry = { pl: "pl", de: "de", fr: "fr", cs: "cz", hu: "hu", nl: "nl", en: "uk" };
    return langToCountry[initialLang] || "pl";
  };

  const [route, setRoute] = useStateApp(() => parseRouteFromUrl() || readLS("kr_route", "home"));
  const [lang, setLang] = useStateApp(detectInitialLang);
  const [country, setCountry] = useStateApp(() => detectInitialCountry(detectInitialLang()));
  const [autoDetected, setAutoDetected] = useStateApp(() => {
    const hasStoredLang = !!normalizeLang(readLS("kr_lang", null));
    const hasLangInUrl = !!parseLangFromUrl();
    return !hasStoredLang && !hasLangInUrl;
  });
  const [tiles, setTiles] = useStateApp(() => readLS("kr_tiles", window.DEFAULT_TILES));
  const [search, setSearch] = useStateApp(false);
  const [loading, setLoading] = useStateApp(true);
  const [visits, setVisits] = useStateApp(() => readLS("kr_visits", 47238));

  /* ───── Auto-detect języka po IP (uzupełnienie, jeśli user jeszcze nie wybrał ręcznie) ───── */
  useEffectApp(() => {
    // Tylko jeśli user jeszcze nie ustawił preferencji świadomie (autoDetected = pierwsza wizyta)
    if (!autoDetected) return;

    fetch("/api/geo.php", { credentials: "omit" })
      .then(r => r.ok ? r.json() : null)
      .then(data => {
        if (!data) return;
        const geoLang = normalizeLang(data.language);
        if (geoLang) {
          setLang(geoLang);
        }
        if (data.country_code) {
          const normalizedCountry = normalizeCountry(data.country_code);
          if (window.COUNTRIES?.find(c => c.code === normalizedCountry)) {
            setCountry(normalizedCountry);
          }
        }
      })
      .catch(() => {});  // backend padł — zostajemy z navigator.language
  }, []);

  // Gdy user ręcznie zmieni język — wyłącz auto-detect (zapamiętaj jego wybór na zawsze)
  const setLangManual = (newLang) => {
    const normalized = normalizeLang(newLang) || "pl";
    setLang(normalized);
    setAutoDetected(false);
    writeLS("kr_auto_detected", false);
  };
  const setCountryManual = (newCountry) => {
    const normalized = normalizeCountry(newCountry) || "pl";
    setCountry(normalized);
    setAutoDetected(false);
    writeLS("kr_auto_detected", false);
  };

  // Ustaw atrybut lang na <html> dla SEO i screen readers
  useEffectApp(() => {
    if (lang) document.documentElement.setAttribute("lang", lang);
  }, [lang]);

  // Increment visit counter once per browser session
  useEffectApp(() => {
    if (!sessionStorage.getItem("kr_session_id")) {
      sessionStorage.setItem("kr_session_id", Date.now().toString());
      const v = readLS("kr_visits", 47238) + 1;
      writeLS("kr_visits", v);
      setVisits(v);
    }
    // Slow live drift — random visits coming in to feel alive
    const id = setInterval(() => {
      setVisits(v => {
        const next = v + (Math.random() < 0.4 ? 1 : 0);
        if (next !== v) writeLS("kr_visits", next);
        return next;
      });
    }, 8000);
    return () => clearInterval(id);
  }, []);

  useEffectApp(() => { writeLS("kr_route", route); }, [route]);
  useEffectApp(() => { writeLS("kr_country", country); }, [country]);
  useEffectApp(() => { writeLS("kr_lang", lang); }, [lang]);
  useEffectApp(() => { writeLS("kr_tiles", tiles); }, [tiles]);

  // Apply theme to <html>
  useEffectApp(() => {
    document.documentElement.setAttribute("data-theme", t.theme);
    document.documentElement.setAttribute("data-mode", t.mode);
  }, [t.theme, t.mode]);

  // Skeleton on first paint
  useEffectApp(() => {
    const id = setTimeout(() => setLoading(false), 350);
    return () => clearTimeout(id);
  }, []);

  // Scroll to top on route change
  useEffectApp(() => {
    window.scrollTo({ top: 0, behavior: "instant" });
  }, [JSON.stringify(route)]);

  useEffectApp(() => {
    const currentRouteName = typeof route === "string" ? route : route?.name || "home";
    const currentRouteData = typeof route === "object" ? route : null;
    const safeLang = normalizeLang(lang) || "en";
    const nextUrl = buildStateUrl(window.location.origin, safeLang, currentRouteName, currentRouteData);
    const nextRelative = nextUrl.replace(window.location.origin, "");
    const currentRelative = `${window.location.pathname}${window.location.search}`;

    if (nextRelative !== currentRelative) {
      window.history.replaceState(null, "", nextRelative);
    }

    applySeo({ routeName: currentRouteName, routeData: currentRouteData, lang: safeLang });

    if (typeof window.gtag === "function" && currentRouteName !== "admin") {
      window.gtag("event", "page_view", {
        page_title: document.title,
        page_location: window.location.href,
        page_path: `${window.location.pathname}${window.location.search}`,
        language: safeLang,
      });
    }
  }, [route, lang]);

  // Cmd/Ctrl-K opens search
  useEffectApp(() => {
    const onKey = (e) => {
      if ((e.metaKey || e.ctrlKey) && e.key === "k") {
        e.preventDefault();
        setSearch(true);
      }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, []);

  const navigate = (target) => {
    setRoute(target);
  };

  const routeName = typeof route === "string" ? route : (route?.name || "home");
  const routeData = typeof route === "object" ? route : null;

  return (
    <>
      <Header
        route={routeName}
        navigate={navigate}
        lang={lang} setLang={setLangManual}
        country={country} setCountry={setCountryManual}
        mode={t.mode} setMode={(m) => setTweak("mode", m)}
        theme={t.theme} setTheme={(th) => setTweak("theme", th)}
        openSearch={() => setSearch(true)}
      />

      {t.showTicker && <Ticker />}

      <main style={{ minHeight: "60vh", paddingBottom: 48 }}>
        {loading ? <LoadingSkeleton route={routeName} /> : (
          <>
            {routeName === "home"      && <HomePage  country={country} navigate={navigate} lang={lang} tweaks={t} tiles={tiles} visits={visits} />}
            {routeName === "mortgage"  && <CalcPage  kind="mortgage" country={country} navigate={navigate} lang={lang} />}
            {routeName === "cash"      && <CalcPage  kind="cash" country={country} navigate={navigate} lang={lang} />}
            {routeName === "banks"     && <BanksPage country={country} navigate={navigate} lang={lang} />}
            {routeName === "markets"   && <MarketsPage navigate={navigate} lang={lang} />}
            {routeName === "programs"  && <ProgramsPage navigate={navigate} lang={lang} />}
            {routeName === "articles"  && <ArticlesPage navigate={navigate} lang={lang} />}
            {routeName === "article"   && <ArticlePage id={routeData?.id || 1} navigate={navigate} lang={lang} />}
            {routeName === "faq"       && <FaqPage navigate={navigate} lang={lang} />}
            {routeName === "contact"   && <ContactPage navigate={navigate} lang={lang} />}
            {routeName === "privacy"   && <LegalPage kind="privacy" navigate={navigate} lang={lang} />}
            {routeName === "terms"     && <LegalPage kind="terms" navigate={navigate} lang={lang} />}
            {routeName === "cookies"   && <LegalPage kind="cookies" navigate={navigate} lang={lang} />}
            {routeName === "admin"     && <AdminPage navigate={navigate} tiles={tiles} setTiles={setTiles} tweaks={t} setTweak={setTweak} />}
          </>
        )}
      </main>

      <ImpactStrip visits={visits} lang={lang} />

      <Footer lang={lang} navigate={navigate} />

      <SearchModal open={search} onClose={() => setSearch(false)} navigate={navigate} lang={lang} />

      <CookieBanner lang={lang} />

      <TweaksPanel>
        <TweakSection label={window.t(lang, "common.themeVariant", "Visual Variant")} />
        <TweakRadio  label="Theme" value={t.theme}
                     options={["aurora", "daylight", "bold"]}
                     onChange={(v) => setTweak("theme", v)} />
        <TweakRadio  label={window.t(lang, "common.mode", "Mode")} value={t.mode}
                     options={["light", "dark"]}
                     onChange={(v) => setTweak("mode", v)} />
        <TweakSection label={window.t(lang, "common.layout", "Layout")} />
        <TweakRadio  label={window.t(lang, "common.tiles", "Tiles")} value={t.tileLayout}
                     options={["bento", "grid"]}
                     onChange={(v) => setTweak("tileLayout", v)} />
        <TweakSection label={window.t(lang, "common.elements", "Elements")} />
        <TweakToggle label={window.t(lang, "common.currencyTicker", "Currency Ticker")} value={t.showTicker}
                     onChange={(v) => setTweak("showTicker", v)} />
        <TweakToggle label={window.t(lang, "common.adSlots", "Ad Slots")} value={t.showAds}
                     onChange={(v) => setTweak("showAds", v)} />
        <TweakSection label={window.t(lang, "common.actions", "Actions")} />
        <TweakButton label={window.t(lang, "cta.openAdmin", "Open Admin")} onClick={() => navigate("admin")} />
        <TweakButton label={window.t(lang, "common.resetTiles", "Reset Tiles")} onClick={() => setTiles([...window.DEFAULT_TILES])} />
      </TweaksPanel>
    </>
  );
}

/* ───── Loading skeleton ───── */
function LoadingSkeleton({ route }) {
  return (
    <div className="container" style={{ padding: "32px 24px" }}>
      <div className="skeleton" style={{ width: "60%", height: 16, marginBottom: 16 }} />
      <div className="skeleton" style={{ width: "90%", height: 56, marginBottom: 12 }} />
      <div className="skeleton" style={{ width: "70%", height: 24, marginBottom: 32 }} />
      <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(220px, 1fr))", gap: 16 }}>
        {[...Array(6)].map((_, i) => (
          <div key={i} className="skeleton" style={{ height: 200 }} />
        ))}
      </div>
    </div>
  );
}

/* ───── localStorage helpers ───── */
function readLS(key, fallback) {
  try {
    const v = localStorage.getItem(key);
    if (v === null) return fallback;
    return JSON.parse(v);
  } catch { return fallback; }
}
function writeLS(key, val) {
  try { localStorage.setItem(key, JSON.stringify(val)); } catch {}
}

/* ───── Mount ───── */
ReactDOM.createRoot(document.getElementById("root")).render(<App />);
