/* eslint-disable */
const { useState, useEffect, useRef, useMemo, useCallback } = React;

// ============== HOOKS ==============

function useScrollProgress() {
  const [p, setP] = useState(0);
  useEffect(() => {
    const onScroll = () => {
      const max = document.documentElement.scrollHeight - window.innerHeight;
      setP(max > 0 ? window.scrollY / max : 0);
    };
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  return p;
}

// ============== SUB-COMPONENTS ==============

function Chrome({ lang, setLang, t }) {
  const langs = ["ru", "lt", "en"];
  return (
    <header className="chrome">
      <div className="brand">
        <span className="seal">V</span>
        <span>Visagino istorija · XIX a.</span>
      </div>
      <nav>
        <a href="#timeline">{t.nav.timeline}</a>
        <a href="#map">{t.nav.map}</a>
        <a href="#estates">{t.nav.estates}</a>
        <a href="#parish">{t.nav.parish}</a>
        <a href="#gallery">{t.nav.gallery}</a>
        <a href="#method">{t.nav.method}</a>
      </nav>
      <div className="lang-switch">
        {langs.map((l) => (
          <button key={l} className={lang === l ? "active" : ""} onClick={() => setLang(l)}>
            {window.I18N[l].code}
          </button>
        ))}
      </div>
    </header>
  );
}

function Compass() {
  return (
    <svg viewBox="0 0 200 200" className="compass" style={{ position: "absolute", top: "50%", right: "6vw", transform: "translateY(-50%)", width: 380, height: 380, opacity: 0.45, pointerEvents: "none" }}>
      <circle cx="100" cy="100" r="98" fill="none" stroke="var(--rule-2)" />
      <circle cx="100" cy="100" r="80" fill="none" stroke="var(--rule-2)" strokeDasharray="2 4" />
      <circle cx="100" cy="100" r="60" fill="none" stroke="var(--rule-2)" />
      {Array.from({ length: 32 }).map((_, i) => {
        const a = (i / 32) * Math.PI * 2;
        const x1 = 100 + Math.cos(a) * 80;
        const y1 = 100 + Math.sin(a) * 80;
        const x2 = 100 + Math.cos(a) * (i % 8 === 0 ? 92 : 86);
        const y2 = 100 + Math.sin(a) * (i % 8 === 0 ? 92 : 86);
        return <line key={i} x1={x1} y1={y1} x2={x2} y2={y2} stroke="var(--ink-3)" strokeWidth={i % 8 === 0 ? 1 : 0.5} />;
      })}
      <path d="M100,30 L108,100 L100,170 L92,100 Z" fill="var(--accent)" opacity="0.7" />
      <path d="M100,30 L108,100 L100,100 Z" fill="var(--accent)" />
      <text x="100" y="22" textAnchor="middle" fontSize="10" fontFamily="JetBrains Mono, monospace" fill="var(--ink-2)" letterSpacing="2">N</text>
      <text x="100" y="186" textAnchor="middle" fontSize="10" fontFamily="JetBrains Mono, monospace" fill="var(--ink-3)" letterSpacing="2">S</text>
      <text x="14" y="103" fontSize="10" fontFamily="JetBrains Mono, monospace" fill="var(--ink-3)" letterSpacing="2">W</text>
      <text x="180" y="103" fontSize="10" fontFamily="JetBrains Mono, monospace" fill="var(--ink-3)" letterSpacing="2">E</text>
      <circle cx="100" cy="100" r="3" fill="var(--accent)" />
    </svg>
  );
}

function Hero({ t, year }) {
  return (
    <section className="hero">
      <div className="grid-bg" />
      <Compass />
      <div className="odometer">
        <div className="ticks">
          <div>1795</div>
          <div>·</div>
          <div>1914</div>
        </div>
        <div className="year">{year}</div>
        <div className="label">{t.hero.year_label}</div>
      </div>

      <div style={{ position: "relative", zIndex: 2 }}>
        <div className="kicker-line">
          <span className="bar" />
          <span className="mono kicker">{t.hero.kicker}</span>
        </div>
        <h1>
          {t.hero.title.split("\n").map((line, i) => (
            <div key={i}>{i === 1 ? <em>{line}</em> : line}</div>
          ))}
        </h1>
        <p className="lede">{t.hero.subtitle}</p>
      </div>

      <div className="scroll-hint">
        <div className="line" />
        <span className="mono">{t.hero.scroll}</span>
      </div>
    </section>
  );
}

function SectionHead({ kicker, num, title, body }) {
  return (
    <div className="section-head">
      <div className="kicker-block">
        <div className="num">{kicker}</div>
      </div>
      <div>
        <h2>{title}</h2>
        <p className="body">{body}</p>
      </div>
    </div>
  );
}

function Intro({ t }) {
  return (
    <section className="deck" id="intro">
      <SectionHead kicker={t.sections.intro.kicker} title={t.sections.intro.title} body={t.sections.intro.body} />
    </section>
  );
}

function Timeline({ t, onYearChange }) {
  const events = t.timeline;
  const [active, setActive] = useState(0);
  const refs = useRef([]);

  useEffect(() => {
    const obs = new IntersectionObserver(
      (entries) => {
        const visible = entries
          .filter((e) => e.isIntersecting)
          .sort((a, b) => a.target.getBoundingClientRect().top - b.target.getBoundingClientRect().top);
        if (visible.length) {
          const idx = Number(visible[0].target.dataset.idx);
          setActive(idx);
          onYearChange?.(events[idx].year);
        }
      },
      { rootMargin: "-30% 0px -50% 0px", threshold: 0 }
    );
    refs.current.forEach((r) => r && obs.observe(r));
    return () => obs.disconnect();
  }, [events, onYearChange]);

  return (
    <section className="deck" id="timeline">
      <SectionHead kicker={t.sections.timeline.kicker} title={t.sections.timeline.title} body={t.sections.timeline.body} />
      <div className="timeline-wrap">
        <div className="timeline-axis">
          <div className="now-year">{events[active].year}</div>
          <div className="now-label">— {events[active].title}</div>
          <div className="scale">
            {events.map((e, i) => (
              <div
                key={i}
                className={`tick ${i === active ? "active" : ""}`}
                onClick={() => refs.current[i]?.scrollIntoView({ behavior: "smooth", block: "start" })}
              >
                <span style={{ width: 36 }}>{e.year}</span>
                <span className="bar" />
              </div>
            ))}
          </div>
        </div>
        <div className="timeline-list">
          {events.map((e, i) => (
            <article
              key={i}
              data-idx={i}
              ref={(el) => (refs.current[i] = el)}
              className={`timeline-event ${i === active ? "active" : ""}`}
            >
              <div className="yr">{e.year}</div>
              <h3>{e.title}</h3>
              <p>{e.text}</p>
            </article>
          ))}
        </div>
      </div>
    </section>
  );
}

function MapPanel({ t }) {
  const points = t.map_points;
  const [sel, setSel] = useState(points[0].id);
  const cur = points.find((p) => p.id === sel);

  return (
    <section className="deck" id="map">
      <SectionHead kicker={t.sections.map.kicker} title={t.sections.map.title} body={t.sections.map.body} />
      <div className="map-wrap">
        <div className="map-canvas">
          <svg viewBox="0 0 1600 1000" preserveAspectRatio="none">
            <defs>
              <pattern id="hatch" patternUnits="userSpaceOnUse" width="6" height="6" patternTransform="rotate(45)">
                <line x1="0" y1="0" x2="0" y2="6" stroke="var(--rule-2)" strokeWidth="0.6" />
              </pattern>
            </defs>
            {/* Subtle topographic contour lines */}
            {Array.from({ length: 6 }).map((_, i) => (
              <ellipse key={i} cx={500 + i * 30} cy={400 + i * 20} rx={300 - i * 30} ry={180 - i * 18}
                fill="none" stroke="rgba(201,138,60,0.05)" strokeWidth="1" />
            ))}
            {/* Lakes */}
            <ellipse cx="730" cy="500" rx="160" ry="90" fill="rgba(80,130,160,0.22)" stroke="rgba(140,180,200,0.35)" strokeWidth="1.2" />
            <ellipse cx="960" cy="700" rx="200" ry="120" fill="rgba(80,130,160,0.18)" stroke="rgba(140,180,200,0.3)" strokeWidth="1.2" />
            <ellipse cx="500" cy="600" rx="80" ry="45" fill="rgba(80,130,160,0.16)" stroke="rgba(140,180,200,0.28)" strokeWidth="1" />
            {/* Forest hatch */}
            <rect x="100" y="100" width="500" height="220" fill="url(#hatch)" opacity="0.5" />
            <rect x="1100" y="120" width="380" height="280" fill="url(#hatch)" opacity="0.4" />
            <rect x="1200" y="500" width="350" height="320" fill="url(#hatch)" opacity="0.45" />
            {/* Roads */}
            <path d="M 100,200 Q 600,260 1100,180 T 1550,160" fill="none" stroke="var(--accent)" strokeWidth="1.2" strokeDasharray="6 4" opacity="0.7" />
            <path d="M 60,400 Q 400,520 800,520 T 1500,540" fill="none" stroke="var(--ink-3)" strokeWidth="1" strokeDasharray="3 5" opacity="0.5" />
            {/* Railway */}
            <path d="M 60,300 L 1550,300" fill="none" stroke="var(--ink-2)" strokeWidth="0.8" />
            {Array.from({ length: 80 }).map((_, i) => (
              <line key={i} x1={60 + i * 19} y1="296" x2={60 + i * 19} y2="304" stroke="var(--ink-3)" strokeWidth="0.6" />
            ))}
            {/* Labels */}
            <text x="120" y="175" fontSize="11" fontFamily="JetBrains Mono, monospace" fill="var(--accent)" letterSpacing="2">SPB — WARSAW TURNPIKE</text>
            <text x="120" y="290" fontSize="10" fontFamily="JetBrains Mono, monospace" fill="var(--ink-3)" letterSpacing="2">RAILWAY · 1860s</text>
            <text x="640" y="510" fontSize="11" fontFamily="Source Serif 4, serif" fontStyle="italic" fill="var(--ink-2)">Lake Visaginas</text>
            <text x="870" y="700" fontSize="11" fontFamily="Source Serif 4, serif" fontStyle="italic" fill="var(--ink-2)">Lake Drūkšiai</text>
            <text x="430" y="600" fontSize="10" fontFamily="Source Serif 4, serif" fontStyle="italic" fill="var(--ink-3)">Skėteris</text>
          </svg>

          {points.map((p, i) => (
            <div
              key={p.id}
              className={`pt ${sel === p.id ? "active" : ""}`}
              style={{ left: `${p.x}%`, top: `${p.y}%` }}
              onClick={() => setSel(p.id)}
            >
              <span className="pulse" />
              <span className="dot" />
              <span className="pt-label">{String(i + 1).padStart(2, "0")} · {p.title}</span>
            </div>
          ))}

          <div className="map-legend">
            <div className="ttl">Schubert · 1:126 000</div>
            <ul>
              <li><span className="sym" /> kaimas / khutor</li>
              <li><span className="sym fol" /> palivarkas / folwark</li>
              <li><span className="sym parish" /> parapija / parish</li>
            </ul>
          </div>

          {cur && (
            <div className="map-detail">
              <div className="yr">{cur.year} · {cur.id.toUpperCase()}</div>
              <h4>{cur.title}</h4>
              <p>{cur.text}</p>
            </div>
          )}
        </div>

        <div className="map-meta">
          {t.stats.map((s, i) => (
            <div key={i}>
              <div className="v">{s.stat}</div>
              <div className="k">{s.label}</div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

function Estates({ t }) {
  return (
    <section className="deck" id="estates">
      <SectionHead kicker={t.sections.estates.kicker} title={t.sections.estates.title} body={t.sections.estates.body} />
      <div className="estates-grid">
        {t.estates.map((e, i) => (
          <article className="estate" key={i}>
            <div className="name">{e.name}</div>
            <div className="row"><span className="k">владельцы</span><span className="v">{e.owner}</span></div>
            <div className="row"><span className="k">фокус</span><span className="v">{e.focus}</span></div>
            <p className="text">{e.text}</p>
          </article>
        ))}
      </div>
    </section>
  );
}

function Parish({ t }) {
  return (
    <section className="deck" id="parish">
      <SectionHead kicker={t.sections.parish.kicker} title={t.sections.parish.title} body={t.sections.parish.body} />
      <div className="parish-grid">
        {t.parish.map((p, i) => (
          <article className="parish" key={i}>
            <div className="lat">{p.lat}</div>
            <div className="nm">{p.name}</div>
            <p className="text">{p.text}</p>
          </article>
        ))}
      </div>
    </section>
  );
}

function Gallery({ t }) {
  return (
    <section className="deck" id="gallery">
      <SectionHead kicker={t.sections.gallery.kicker} title={t.sections.gallery.title} body={t.sections.gallery.body} />
      <div className="gallery-grid">
        {t.gallery.map((g, i) => (
          <figure className={`plate ${g.tone}`} key={i}>
            <div className="ph">No. {String(i + 1).padStart(2, "0")} · archival placeholder</div>
            <figcaption className="cap">{g.caption}</figcaption>
          </figure>
        ))}
      </div>
    </section>
  );
}

function Method({ t }) {
  return (
    <section className="deck" id="method">
      <SectionHead kicker={t.sections.method.kicker} title={t.sections.method.title} body={t.sections.method.body} />
      <div className="method-list">
        {t.method_steps.map((s, i) => (
          <div className="method-item" key={i}>
            <div className="n">{s.n}</div>
            <div>
              <h4>{s.title}</h4>
              <p>{s.text}</p>
            </div>
          </div>
        ))}
      </div>
      <div className="units-row">
        {t.units.map((u, i) => (
          <div className="unit-cell" key={i}>
            <div className="u">{u.unit}</div>
            <div className="v">{u.value}</div>
            <div className="t">{u.text}</div>
          </div>
        ))}
      </div>
    </section>
  );
}

function Foot({ t }) {
  return (
    <footer className="foot">
      <div>
        <div className="seal">Visagino <em>istorija</em></div>
        <div style={{ marginTop: 12 }}>{t.footer.line1}</div>
      </div>
      <div>{t.footer.line2}</div>
      <div>{t.footer.line3}</div>
    </footer>
  );
}

// ============== APP ==============

function App() {
  const [T, setT] = useState(window.TWEAK_DEFAULTS);
  const setTweak = (key, val) => {
    setT((p) => ({ ...p, [key]: val }));
    try { window.parent.postMessage({ type: "__edit_mode_set_keys", edits: { [key]: val } }, "*"); } catch(e) {}
  };

  const [lang, setLang] = useState("ru");
  const [year, setYear] = useState(window.I18N.ru.timeline[0].year);

  const t = window.I18N[lang];

  // accent color from tweaks
  useEffect(() => {
    document.documentElement.style.setProperty("--accent", T.accent);
    // derive accent-2 (lighter)
    const m = T.accent.match(/^#([0-9a-f]{6})$/i);
    if (m) {
      const r = Math.min(255, parseInt(m[1].slice(0, 2), 16) + 30);
      const g = Math.min(255, parseInt(m[1].slice(2, 4), 16) + 30);
      const b = Math.min(255, parseInt(m[1].slice(4, 6), 16) + 30);
      document.documentElement.style.setProperty("--accent-2", `rgb(${r},${g},${b})`);
    }
  }, [T.accent]);

  // Hero year animates from first to last across the hero scroll
  const [heroYear, setHeroYear] = useState(t.timeline[0].year);
  useEffect(() => {
    const onScroll = () => {
      const h = window.innerHeight;
      const sy = Math.min(1, Math.max(0, window.scrollY / h));
      const yrs = t.timeline.map((e) => e.year);
      const idx = Math.min(yrs.length - 1, Math.floor(sy * yrs.length));
      setHeroYear(yrs[idx]);
    };
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, [t]);

  return (
    <>
      <Chrome lang={lang} setLang={setLang} t={t} />
      <Hero t={t} year={heroYear} />
      <Intro t={t} />
      <Timeline t={t} onYearChange={setYear} />
      <MapPanel t={t} />
      <Estates t={t} />
      <Parish t={t} />
      <Gallery t={t} />
      <Method t={t} />
      <Foot t={t} />

      {window.TweaksPanel && (
        <window.TweaksPanel title="Tweaks">
          <window.TweakSection label="Color" />
          <window.TweakColor label="Accent" value={T.accent} onChange={(v) => setTweak("accent", v)} />
          <div style={{ display: "flex", gap: 6, marginTop: 4, flexWrap: "wrap" }}>
            {[
              ["Amber", "#c98a3c"],
              ["Brick", "#b04a3a"],
              ["Moss", "#7a8a3c"],
              ["Slate", "#6e8aa3"],
              ["Plum", "#8a5a8a"],
              ["Bone", "#d6c79a"],
            ].map(([n, c]) => (
              <button key={c} onClick={() => setTweak("accent", c)}
                style={{
                  background: c, width: 24, height: 24, borderRadius: 999,
                  border: T.accent === c ? "2px solid #29261b" : "1px solid rgba(0,0,0,.2)",
                  cursor: "pointer", padding: 0,
                }}
                title={n}
              />
            ))}
          </div>
          <window.TweakSection label="Language" />
          <window.TweakRadio
            label="Interface"
            value={lang}
            onChange={setLang}
            options={["ru", "lt", "en"]}
          />
        </window.TweaksPanel>
      )}
    </>
  );
}

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