/* pl-app.jsx — powłoka: nawigacja, hero, stopka, tweaki, montaż */
const { useState, useEffect, useRef } = React;

const LANGS = [
  { code: "PL", label: "Polski", ready: true },
  { code: "EN", label: "English", ready: false },
  { code: "DE", label: "Deutsch", ready: false },
  { code: "RU", label: "Русский", ready: false },
];
const NOTICE = {
  EN: "An English version is in preparation — content is currently shown in Polish.",
  DE: "Eine deutsche Fassung wird vorbereitet — die Inhalte werden derzeit auf Polnisch angezeigt.",
  RU: "Русская версия готовится — содержание сейчас отображается на польском языке.",
};

/* Data ostatniej aktualizacji — wstawiana automatycznie. */
const PL_MONTHS = ["stycznia","lutego","marca","kwietnia","maja","czerwca","lipca","sierpnia","września","października","listopada","grudnia"];
const NOW = new Date();
const UPDATED_DATE = `${NOW.getDate()} ${PL_MONTHS[NOW.getMonth()]} ${NOW.getFullYear()}`;
const CURRENT_YEAR = NOW.getFullYear();

/* oryginalny, neutralny znak kampanii — abstrakcyjna „działka w rejestrze" */
function BrandMark({ size = 30 }) {
  return (
    <svg className="brand-mark" width={size} height={size} viewBox="0 0 32 32" aria-hidden="true">
      <rect x="2.5" y="2.5" width="27" height="27" rx="2" fill="none" stroke="var(--on-dark-soft)" strokeWidth="1.4" />
      <rect x="9" y="9" width="14" height="14" rx="1" fill="none" stroke="var(--accent-soft)" strokeWidth="1.6" />
      <path d="M9 16h14M16 9v14" stroke="var(--on-dark-mute)" strokeWidth="1" />
    </svg>
  );
}

function Nav({ lang, setLang }) {
  const [scrolled, setScrolled] = useState(false);
  const [menuOpen, setMenuOpen] = useState(false);
  const [navOpen, setNavOpen] = useState(false);
  const [zone, setZone] = useState("#top");
  const ref = useRef(null);

  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 24);
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  useEffect(() => {
    const onDoc = (e) => { if (ref.current && !ref.current.contains(e.target)) setMenuOpen(false); };
    document.addEventListener("mousedown", onDoc);
    return () => document.removeEventListener("mousedown", onDoc);
  }, []);

  /* scroll-spy: przypisz każdą sekcję do strefy nawigacji i podświetl bieżącą */
  useEffect(() => {
    const ZONES = {
      "#top": ["top", "liczby", "historie", "kim", "co-sie-dzieje", "czesci-wspolne", "cytat"],
      "#prawo": ["prawo", "o-co-chodzi", "ostrzezenie"],
      "#media": ["media", "precedens"],
      "#pomoc": ["pomoc", "branza", "goscie", "udostepnij", "cytaty"],
      "#kontakt": ["kontakt"],
    };
    const secToZone = {};
    Object.entries(ZONES).forEach(([z, ids]) => ids.forEach((id) => (secToZone[id] = z)));
    const nodes = Object.keys(secToZone).map((id) => document.getElementById(id)).filter(Boolean);
    const io = new IntersectionObserver((entries) => {
      entries.forEach((en) => { if (en.isIntersecting) setZone(secToZone[en.target.id] || "#top"); });
    }, { rootMargin: "-45% 0px -50% 0px", threshold: 0 });
    nodes.forEach((n) => io.observe(n));
    return () => io.disconnect();
  }, []);

  const links = [
    ["#top", "Sprawa"],
    ["#prawo", "Sytuacja prawna"],
    ["#media", "Media"],
    ["#kontakt", "Kontakt"],
  ];

  /* pełna, zagnieżdżona mapa nawigacji dla menu mobilnego */
  const tree = [
    { href: "#top", label: "Sprawa", kids: [
      ["#historie", "Ludzkie historie"],
      ["#kim", "Kim jesteśmy"],
      ["#co-sie-dzieje", "Co się dzieje"],
      ["#czesci-wspolne", "Części wspólne"],
    ]},
    { href: "#prawo", label: "Sytuacja prawna", kids: [
      ["#o-co-chodzi", "O co naprawdę chodzi"],
      ["#ostrzezenie", "Mogło spotkać i Ciebie"],
    ]},
    { href: "#media", label: "Media", kids: [
      ["#precedens", "Precedens — Hotel Tarsis"],
    ]},
    { href: "#pomoc", label: "Możesz pomóc", accent: true, kids: [
      ["#branza", "Dla branży turystycznej"],
      ["#goscie", "Byłeś gościem?"],
      ["#udostepnij", "Udostępnij"],
    ]},
    { href: "#kontakt", label: "Kontakt", kids: [] },
  ];

  /* blokada przewijania tła, gdy menu mobilne otwarte */
  useEffect(() => {
    document.body.style.overflow = navOpen ? "hidden" : "";
    return () => { document.body.style.overflow = ""; };
  }, [navOpen]);

  return (
    <nav className={"nav" + (scrolled ? " is-scrolled" : "")}>
      <div className="nav-inner">
        <a className="brand" href="#top">
          <BrandMark />
          <span className="brand-text">
            <span className="brand-name">Sveti Vlas</span>
            <span className="brand-sub">Głos Właścicieli</span>
          </span>
        </a>

        <div className={"nav-links" + (navOpen ? " is-open" : "")}>
          {links.map(([h, t]) => (
            <a key={h} href={h} className={zone === h ? "is-active" : ""}
               onClick={() => setNavOpen(false)}>{t}</a>
          ))}
        </div>

        <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
          <a className={"btn btn--primary btn--sm nav-cta" + (zone === "#pomoc" ? " is-active" : "")} href="#pomoc">
            Możesz pomóc <span className="arr"><Ico name="arrow" size={13} /></span>
          </a>
          <div className="lang" ref={ref}>
            <button className="lang-btn" onClick={() => setMenuOpen((o) => !o)} aria-haspopup="true" aria-expanded={menuOpen}>
              {lang} <Ico name="arrow" size={12} />
            </button>
            {menuOpen && (
              <div className="lang-menu" role="menu">
                {LANGS.map((l) => (
                  <button key={l.code} className={l.code === lang ? "is-active" : ""}
                    onClick={() => { setLang(l.code); setMenuOpen(false); }}>
                    <span>{l.label}</span>
                    {l.ready ? <span style={{ fontSize: "0.62rem" }}>{l.code}</span> : <span className="tag">wkrótce</span>}
                  </button>
                ))}
              </div>
            )}
          </div>
          <button className="nav-toggle" onClick={() => setNavOpen((o) => !o)}
            aria-label={navOpen ? "Zamknij menu" : "Otwórz menu"} aria-expanded={navOpen}>
            <Ico name={navOpen ? "close" : "menu"} size={18} />
          </button>
        </div>
      </div>

      {/* zagnieżdżone menu mobilne */}
      <div className={"mobile-menu" + (navOpen ? " is-open" : "")} role="dialog" aria-label="Menu nawigacji" aria-modal="true">
        <nav className="mm-inner" aria-label="Nawigacja po stronie">
          {tree.map((g) => (
            <div className="mm-group" key={g.href}>
              <a className={"mm-head" + (g.accent ? " is-accent" : "") + (zone === g.href ? " is-active" : "")}
                 href={g.href} onClick={() => setNavOpen(false)}>
                {g.label}
                <span className="mm-arr"><Ico name="arrow" size={15} /></span>
              </a>
              {g.kids.length > 0 && (
                <div className="mm-kids">
                  {g.kids.map(([h, t]) => (
                    <a key={h} href={h} onClick={() => setNavOpen(false)}>{t}</a>
                  ))}
                </div>
              )}
            </div>
          ))}
        </nav>
      </div>
    </nav>
  );
}

function LangNotice({ lang }) {
  if (lang === "PL" || !NOTICE[lang]) return null;
  return <div className="lang-notice">{NOTICE[lang]}</div>;
}

/* pasek postępu czytania + przycisk „do góry" */
function ScrollProgress() {
  const [pct, setPct] = useState(0);
  useEffect(() => {
    const onScroll = () => {
      const h = document.documentElement;
      const max = h.scrollHeight - h.clientHeight;
      setPct(max > 0 ? (h.scrollTop / max) * 100 : 0);
    };
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    window.addEventListener("resize", onScroll);
    return () => { window.removeEventListener("scroll", onScroll); window.removeEventListener("resize", onScroll); };
  }, []);
  return <div className="scroll-progress" style={{ width: pct + "%" }} aria-hidden="true" />;
}

function ToTop() {
  const [shown, setShown] = useState(false);
  useEffect(() => {
    const onScroll = () => setShown(window.scrollY > window.innerHeight * 1.4);
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  const up = () => window.scrollTo({ top: 0, behavior: "smooth" });
  return (
    <button className={"to-top" + (shown ? " is-shown" : "")} onClick={up} aria-label="Wróć na górę">
      <svg viewBox="0 0 20 20" width="18" height="18" fill="none" stroke="currentColor"
        strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
        <path d="M10 16V5M5 10l5-5 5 5" />
      </svg>
    </button>
  );
}

/* przyklejony pasek CTA — pojawia się po przewinięciu hero, znika przy sekcji „Możesz pomóc” */
function StickyCTA() {
  const [shown, setShown] = useState(false);
  const [closed, setClosed] = useState(false);
  useEffect(() => {
    const onScroll = () => {
      const pomoc = document.getElementById("pomoc");
      const past = window.scrollY > window.innerHeight * 0.9;
      let beforePomoc = true;
      if (pomoc) beforePomoc = pomoc.getBoundingClientRect().top > window.innerHeight * 0.8;
      setShown(past && beforePomoc);
    };
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  if (closed) return null;
  return (
    <div className={"sticky-cta" + (shown ? " is-shown" : "")}>
      <div className="sticky-cta-inner">
        <span className="sc-text"><span className="dot">●</span>&nbsp; Możesz pomóc nagłośnić tę sprawę.</span>
        <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
          <a className="btn btn--primary btn--sm" href="#pomoc">
            Zobacz, jak <span className="arr"><Ico name="arrow" size={13} /></span>
          </a>
          <button className="sc-close" onClick={() => setClosed(true)} aria-label="Zamknij">
            <Ico name="close" size={16} />
          </button>
        </div>
      </div>
    </div>
  );
}

function Hero() {
  return (
    <header className="hero" id="top" style={{ "--hero-photo": "url('images/hero-basen-morze.jpg')" }}>
      <div className="wrap">
        <div className="hero-inner">
          <p className="eyebrow">Zapis w interesie publicznym · Grand Hotel Sveti Vlas · Sveti Vlas, Bułgaria</p>
          <h1 className="long">Płacimy za prąd, który hotel nam odcina. Jesteśmy współwłaścicielami wind, do których nie mamy kart. <span className="hl-accent">To dzieje się teraz — w kraju Unii Europejskiej.</span></h1>
          <p className="subhead">
            Wspólny głos ponad 120 prywatnych właścicieli apartamentów w Grand Hotelu Sveti Vlas w Bułgarii.
          </p>
          <div className="hero-actions">
            <a className="btn btn--primary" href="#historie">
              Poznaj fakty <span className="arr"><Ico name="arrow" size={15} /></span>
            </a>
            <a className="btn btn--ghost btn--on-dark" href="#kontakt">
              Jesteś właścicielem? Dołącz
            </a>
          </div>
          <div>
            <a className="hero-tertiary" href="#pomoc">
              Jesteś dziennikarzem lub europosłem? Zobacz, jak możesz pomóc
              <span className="arr"><Ico name="arrow" size={14} /></span>
            </a>
          </div>
          <div className="hero-meta">
            <span><b>Lokalizacja</b> &nbsp;Sveti Vlas, obwód Burgas, Bułgaria</span>
            <span><b>Właściciele</b> &nbsp;ponad 120 osób</span>
            <span><b>Aktualizacja</b> &nbsp;{UPDATED_DATE}</span>
          </div>
        </div>
      </div>
    </header>
  );
}

/* Ikony mediów społecznościowych — wyświetlane tylko, gdy URL jest realnie wstawiony.
   Aby pokazać ikonę, wpisz adres w polu url poniżej (puste "" = ikona ukryta). */
const SOCIALS = [
  { key: "youtube",   label: "YouTube",   url: "" /* np. "https://www.youtube.com/@..." */ },
  { key: "facebook",  label: "Facebook",  url: "" /* np. "https://www.facebook.com/..." */ },
  { key: "instagram", label: "Instagram", url: "" /* np. "https://www.instagram.com/..." */ },
  { key: "tiktok",    label: "TikTok",    url: "" /* np. "https://www.tiktok.com/@..." */ },
  { key: "linkedin",  label: "LinkedIn",  url: "" /* np. "https://www.linkedin.com/company/..." */ },
];
function SocialGlyph({ name }) {
  const p = {
    youtube: <path d="M21.6 7.2a2.5 2.5 0 0 0-1.76-1.77C18.27 5 12 5 12 5s-6.27 0-7.84.43A2.5 2.5 0 0 0 2.4 7.2 26 26 0 0 0 2 12a26 26 0 0 0 .4 4.8 2.5 2.5 0 0 0 1.76 1.77C5.73 19 12 19 12 19s6.27 0 7.84-.43a2.5 2.5 0 0 0 1.76-1.77A26 26 0 0 0 22 12a26 26 0 0 0-.4-4.8zM10 15V9l5.2 3z" />,
    facebook: <path d="M22 12a10 10 0 1 0-11.56 9.88v-6.99H7.9V12h2.54V9.8c0-2.5 1.49-3.89 3.78-3.89 1.09 0 2.24.2 2.24.2v2.46h-1.26c-1.24 0-1.63.77-1.63 1.56V12h2.78l-.44 2.89h-2.34v6.99A10 10 0 0 0 22 12z" />,
    instagram: <><rect x="3.5" y="3.5" width="17" height="17" rx="4.6" fill="none" stroke="currentColor" strokeWidth="1.8" /><circle cx="12" cy="12" r="3.8" fill="none" stroke="currentColor" strokeWidth="1.8" /><circle cx="17" cy="7" r="1.2" /></>,
    tiktok: <path d="M16.5 3h-2.6v12.4a2.6 2.6 0 1 1-2.6-2.6c.27 0 .53.04.78.12v-2.68a5.3 5.3 0 1 0 4.42 5.22V8.9a6.3 6.3 0 0 0 3.5 1.06V7.32A3.8 3.8 0 0 1 16.5 4.4z" />,
    linkedin: <><rect x="3.5" y="3.5" width="17" height="17" rx="2.4" fill="none" stroke="currentColor" strokeWidth="1.8" /><path d="M7 10v6.5M7 7.3v.01M11 16.5V10m0 0v6.5m0-6.5c0-1 .8-1.9 2.2-1.9 1.6 0 2.3 1 2.3 2.9v5.5" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" /></>,
  }[name];
  const filled = name === "youtube" || name === "facebook" || name === "tiktok";
  return (
    <svg viewBox="0 0 24 24" width="20" height="20" aria-hidden="true"
      fill={filled ? "currentColor" : "none"}>{p}</svg>
  );
}
function SocialLinks() {
  const active = SOCIALS.filter((s) => s.url && s.url.trim());
  if (active.length === 0) return null;
  return (
    <div className="footer-social">
      <div className="fc-k">Obserwuj</div>
      <div className="social-row">
        {active.map((s) => (
          <a key={s.key} className="social-link" href={s.url} target="_blank" rel="noopener noreferrer"
             aria-label={`${s.label} — Sveti Vlas Głos Właścicieli`}>
            <SocialGlyph name={s.key} />
          </a>
        ))}
      </div>
    </div>
  );
}

function Footer({ setLang }) {
  return (
    <footer className="footer">
      <div className="wrap">
        <div className="footer-top">
          <div>
            <a className="brand" href="#top" style={{ marginBottom: 22 }}>
              <BrandMark size={26} />
              <span className="brand-text">
                <span className="brand-name">Sveti Vlas</span>
                <span className="brand-sub">Głos Właścicieli</span>
              </span>
            </a>
            <p className="disclaimer">
              Niniejsza strona przedstawia relacje i udokumentowane doświadczenia prywatnych
              właścicieli apartamentów. Wypowiedzi przypisane personelowi hotelu lub osobom trzecim
              przedstawiamy tak, jak właściciele je usłyszeli lub zrozumieli. Publikujemy ją w dobrej
              wierze i w interesie publicznym.
            </p>
          </div>
          <div className="footer-contact">
            <div className="fc-k">Kontakt</div>
            <p style={{ marginBottom: 18 }}><a href="#kontakt">Grupa koordynująca właścicieli →</a></p>
            <div className="fc-k">Języki</div>
            <div style={{ display: "flex", gap: 14, fontFamily: "var(--font-mono)", fontSize: "0.78rem" }}>
              {LANGS.map((l) => (
                <button key={l.code} onClick={() => setLang(l.code)}
                  style={{ background: "none", border: "none", cursor: "pointer", color: "var(--on-dark-soft)",
                    fontFamily: "inherit", fontSize: "inherit", padding: 0 }}>{l.code}</button>
              ))}
            </div>
            <SocialLinks />
          </div>
        </div>
        <div className="footer-bottom">
          <span>© {CURRENT_YEAR} Sveti Vlas — Głos Właścicieli · Inicjatywa koordynacyjna właścicieli</span>
          <span>Ostatnia aktualizacja: {UPDATED_DATE}</span>
        </div>
      </div>
    </footer>
  );
}

/* ---------------- Tweaki ---------------- */
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "red",
  "serif": "Source Serif 4",
  "fontSize": 18
}/*EDITMODE-END*/;

const ACCENTS = {
  red:   { a: "#9e2b22", s: "#b8463c", t: "rgba(158,43,34,0.10)" },
  amber: { a: "#a9751a", s: "#c1902f", t: "rgba(169,117,26,0.12)" },
};

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [lang, setLang] = useState("PL");
  const rootRef = useRef(null);

  useEffect(() => {
    const els = rootRef.current.querySelectorAll(".reveal");
    if (!("IntersectionObserver" in window)) { els.forEach((e) => e.classList.add("is-in")); return; }
    const io = new IntersectionObserver((ents) => {
      ents.forEach((en) => { if (en.isIntersecting) { en.target.classList.add("is-in"); io.unobserve(en.target); } });
    }, { threshold: 0.12, rootMargin: "0px 0px -8% 0px" });
    els.forEach((e) => io.observe(e));
    return () => io.disconnect();
  }, []);

  const ac = ACCENTS[t.accent] || ACCENTS.red;
  const rootStyle = {
    "--accent": ac.a, "--accent-soft": ac.s, "--accent-tint": ac.t,
    "--font-serif": `"${t.serif}", Georgia, serif`,
    "--fs-base": `${t.fontSize}px`,
  };

  return (
    <div ref={rootRef} style={rootStyle}>
      <a className="skip-link" href="#top">Przejdź do treści</a>
      <Nav lang={lang} setLang={setLang} />
      <LangNotice lang={lang} />
      <Hero />
      <main>
        {/* ===== SPRAWA ===== */}
        <Impact />
        <Stories />
        <Kim />
        <CoSieDzieje />
        <CzesciWspolne />
        <BigQuote />

        {/* ===== DOWODY I PRAWO ===== */}
        <SytuacjaPrawna />
        <OcoChodzi />
        <Warning />
        <Media />
        <Precedens />

        {/* ===== MOŻESZ POMÓC ===== */}
        <MozeszPomoc />
        <Branza />
        <Goscie />
        <Udostepnij />
        <Cytaty />

        {/* ===== KONTAKT ===== */}
        <Contact />
      </main>
      <Footer setLang={setLang} />
      <StickyCTA />
      <ScrollProgress />
      <ToTop />

      <TweaksPanel>
        <TweakSection label="Akcent" />
        <TweakColor label="Kolor akcentu" value={t.accent === "red" ? "#9e2b22" : "#a9751a"}
          options={["#9e2b22", "#a9751a"]}
          onChange={(v) => setTweak("accent", v === "#9e2b22" ? "red" : "amber")} />
        <TweakSection label="Typografia" />
        <TweakSelect label="Krój nagłówków" value={t.serif}
          options={["Source Serif 4", "Newsreader", "Spectral"]}
          onChange={(v) => setTweak("serif", v)} />
        <TweakSlider label="Wielkość tekstu" value={t.fontSize} min={16} max={21} step={1} unit="px"
          onChange={(v) => setTweak("fontSize", v)} />
      </TweaksPanel>
    </div>
  );
}

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