// Main React app — historical globe interface
const { useState, useEffect, useRef, useMemo, useCallback } = React;

const DATA = window.HISTORY_DATA;

// ── Palette presets ─────────────────────────────────────────────
const PALETTES = {
  heritage: {
    name: '헤리티지',
    en: 'Heritage',
    oceanDeep: '#0a1f1a',
    oceanShallow: '#163d32',
    land: '#2a5c4c',
    accent: '#c9a94d',
    bg: 'radial-gradient(ellipse at center, #0f2e25 0%, #07140f 75%)',
  },
  midnight: {
    name: '미드나잇',
    en: 'Midnight',
    oceanDeep: '#040915',
    oceanShallow: '#0a1430',
    land: '#1a2e55',
    accent: '#e8c97a',
    bg: 'radial-gradient(ellipse at center, #050a1a 0%, #020309 75%)',
  },
  ember: {
    name: '엠버',
    en: 'Ember',
    oceanDeep: '#120707',
    oceanShallow: '#261410',
    land: '#3d1e14',
    accent: '#e8a15a',
    bg: 'radial-gradient(ellipse at center, #1a0a08 0%, #080403 75%)',
  },
  copper: {
    name: '코퍼',
    en: 'Copper',
    oceanDeep: '#1a0f0a',
    oceanShallow: '#2a1d13',
    land: '#6b3a1e',
    accent: '#d9a066',
    bg: 'radial-gradient(ellipse at center, #1a0f0a 0%, #0a0604 75%)',
  },
  aurora: {
    name: '오로라',
    en: 'Aurora',
    oceanDeep: '#071820',
    oceanShallow: '#0d2a38',
    land: '#164456',
    accent: '#8cd4c2',
    bg: 'radial-gradient(ellipse at center, #081820 0%, #020608 75%)',
  },
};

function formatYear(y) {
  if (y < 0) return `기원전 ${Math.abs(Math.round(y)).toLocaleString()}년`;
  return `서기 ${Math.round(y).toLocaleString()}년`;
}

function formatYearShort(y) {
  if (y < 0) return `B.C. ${Math.abs(Math.round(y)).toLocaleString()}`;
  return `A.D. ${Math.round(y).toLocaleString()}`;
}

// ── Climate description ─────────────────────────────────────────
function climateAt(year) {
  return DATA.climate.find((c) => year >= c.start && year <= c.end) || DATA.climate[0];
}

// Count active empires
function activeEmpires(year) {
  return DATA.empires.filter((e) => year >= e.start && year <= e.end);
}
function activeCities(year) {
  return DATA.cities.filter((c) => year >= c.founded);
}
function currentEvent(year) {
  return DATA.events.filter((e) => Math.abs(e.year - year) < 15).sort((a, b) => Math.abs(a.year - year) - Math.abs(b.year - year))[0];
}

// ── Timeline / slider ───────────────────────────────────────────
function Timeline({ year, setYear, playing }) {
  const [a, b] = DATA.timeRange;
  const ref = useRef(null);
  const dragging = useRef(false);

  const t = (year - a) / (b - a);

  const onPointer = (e) => {
    const r = ref.current.getBoundingClientRect();
    const x = Math.max(0, Math.min(1, (e.clientX - r.left) / r.width));
    setYear(a + x * (b - a));
  };
  const onDown = (e) => { dragging.current = true; onPointer(e); e.target.setPointerCapture?.(e.pointerId); };
  const onMove = (e) => { if (dragging.current) onPointer(e); };
  const onUp   = () => { dragging.current = false; };

  // Ticks at every millennium + named chapters
  const chapterTicks = DATA.chapters;

  return (
    <div className="timeline">
      <div className="timeline-track"
           ref={ref}
           onPointerDown={onDown}
           onPointerMove={onMove}
           onPointerUp={onUp}
           onPointerCancel={onUp}>
        {/* era shading — climate bands */}
        {DATA.climate.map((c, i) => {
          const x1 = (c.start - a) / (b - a);
          const x2 = (c.end - a) / (b - a);
          const isAccelerating = c.intensity > 0.6;
          return (
            <div key={i} className="climate-band"
                 style={{
                   left: `${x1 * 100}%`,
                   width: `${(x2 - x1) * 100}%`,
                   background: `linear-gradient(180deg, rgba(232, 201, 122, ${c.intensity * 0.12}) 0%, transparent 100%)`,
                   borderBottom: isAccelerating ? '1px solid rgba(232,107,58,0.35)' : '1px solid transparent',
                 }}/>
          );
        })}
        {/* millennium ticks */}
        {[-4000,-3000,-2000,-1000,0,1000,2000].map((m) => {
          const x = (m - a) / (b - a);
          if (x < 0 || x > 1) return null;
          return (
            <div key={m} className="tick" style={{ left: `${x * 100}%` }}>
              <span>{m === 0 ? '0' : (m < 0 ? `${-m/1000}K BC` : `${m}`)}</span>
            </div>
          );
        })}
        {/* chapter flags */}
        {chapterTicks.map((ch) => {
          const x = (ch.year - a) / (b - a);
          return (
            <div key={ch.name} className="chapter-flag"
                 style={{ left: `${x * 100}%` }}
                 title={`${ch.name} (${ch.en})`}
                 onPointerDown={(e) => { e.stopPropagation(); setYear(ch.year); }}>
              <div className="chapter-dot"/>
              <div className="chapter-label">{ch.name}</div>
            </div>
          );
        })}
        {/* filled portion */}
        <div className="timeline-fill" style={{ width: `${t * 100}%` }}/>
        {/* head */}
        <div className="timeline-head" style={{ left: `${t * 100}%` }}>
          <div className="timeline-year">{formatYearShort(year)}</div>
          <div className="timeline-stem"/>
          <div className={`timeline-knob ${playing ? 'pulsing' : ''}`}/>
        </div>
      </div>
    </div>
  );
}

// ── Controls ────────────────────────────────────────────────────
function PlayControls({ playing, setPlaying, speed, setSpeed, year, setYear, onReset }) {
  return (
    <div className="play-controls">
      <button className="play-btn" onClick={() => setPlaying(!playing)} aria-label={playing ? 'Pause' : 'Play'}>
        {playing ? (
          <svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor"><rect x="6" y="5" width="4" height="14" rx="1"/><rect x="14" y="5" width="4" height="14" rx="1"/></svg>
        ) : (
          <svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor"><path d="M7 5v14l12-7z"/></svg>
        )}
      </button>
      <button className="mini-btn" onClick={() => setYear(Math.max(DATA.timeRange[0], year - 50))} aria-label="Back 50 years">
        <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="1.8"><path d="M11 17l-5-5 5-5M18 17l-5-5 5-5"/></svg>
      </button>
      <button className="mini-btn" onClick={() => setYear(Math.min(DATA.timeRange[1], year + 50))} aria-label="Forward 50 years">
        <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="1.8"><path d="M13 17l5-5-5-5M6 17l5-5-5-5"/></svg>
      </button>
      <div className="sep"/>
      <div className="speed-group">
        <span className="eyebrow-xs">속도</span>
        {[10, 25, 60, 150].map((s) => (
          <button key={s} className={`speed-chip ${speed === s ? 'on' : ''}`} onClick={() => setSpeed(s)}>
            {s}<span className="dim">년/초</span>
          </button>
        ))}
      </div>
      <div className="sep"/>
      <button className="mini-btn" onClick={onReset} title="기원전 3000년으로 돌아가기">
        <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="1.8"><path d="M3 12a9 9 0 1 0 3-6.7"/><path d="M3 3v6h6"/></svg>
      </button>
    </div>
  );
}

// ── Era info cards ──────────────────────────────────────────────
function EraPanel({ year, hoverEmpire, activeHint }) {
  const c = climateAt(year);
  const empires = activeEmpires(year);
  const cities = activeCities(year);
  const ev = currentEvent(year);
  const chapter = [...DATA.chapters].reverse().find((ch) => year >= ch.year) || DATA.chapters[0];

  return (
    <div className="era-panel">
      <div className="era-head">
        <div className="eyebrow gold">CHAPTER · 시대</div>
        <div className="era-title">{chapter.name}</div>
        <div className="era-en">{chapter.en}</div>
      </div>

      <div className="premium-divider" style={{ margin: '14px 0' }}/>

      <div className="era-year">
        <div className="era-year-big gold-shimmer">{formatYearShort(year)}</div>
        <div className="era-year-ko">{formatYear(year)}</div>
      </div>

      <div className="stat-grid">
        <div className="stat">
          <div className="stat-num">{empires.length}</div>
          <div className="stat-lab">활동 중인 국가 / 제국</div>
        </div>
        <div className="stat">
          <div className="stat-num">{cities.length}</div>
          <div className="stat-lab">존재하는 주요 도시</div>
        </div>
      </div>

      <div className="climate-card">
        <div className="eyebrow-xs">기후 환경 · CLIMATE</div>
        <div className="climate-name">{c.name}</div>
        <div className="climate-en">{c.en}</div>
        <div className="climate-bar">
          <div className="climate-fill" style={{ width: `${c.intensity * 100}%` }}/>
        </div>
        <div className="climate-hint">
          {c.intensity > 0.8 ? '지구 환경에 극적인 변화 — 인류 활동의 영향이 압도적' :
           c.intensity > 0.5 ? '기후 변동 가시화 — 문명에 도전이 시작됨' :
           c.intensity > 0.3 ? '기후는 전환기 — 성장과 수축의 경계' :
           '기후는 비교적 안정 — 문명 팽창에 유리한 시대'}
        </div>
      </div>

      {ev && (
        <div className="event-card">
          <div className="eyebrow-xs">EVENT · 이 시점의 사건</div>
          <div className="event-title">{ev.name}</div>
          <div className="event-en">{ev.en}</div>
        </div>
      )}

      {(hoverEmpire || activeHint) && (
        <div className="empire-hover">
          <div className="eyebrow-xs">{hoverEmpire ? '가리킨 제국' : '시대의 주인공'}</div>
          <div className="empire-name">{(hoverEmpire || activeHint).name}</div>
          <div className="empire-en">{(hoverEmpire || activeHint).en}</div>
          <div className="empire-dates">
            {formatYearShort((hoverEmpire || activeHint).start)} — {formatYearShort((hoverEmpire || activeHint).end)}
          </div>
        </div>
      )}
    </div>
  );
}

// ── Chapter jump strip ──────────────────────────────────────────
function ChapterStrip({ year, setYear }) {
  return (
    <div className="chapter-strip">
      {DATA.chapters.map((ch) => {
        const active = Math.abs(year - ch.year) < 100;
        return (
          <button key={ch.name} className={`chapter-btn ${active ? 'on' : ''}`} onClick={() => setYear(ch.year)}>
            <span className="chapter-btn-year">{formatYearShort(ch.year)}</span>
            <span className="chapter-btn-name">{ch.name}</span>
          </button>
        );
      })}
    </div>
  );
}

// ── Tweaks panel ────────────────────────────────────────────────
function TweaksPanel({ visible, tweaks, setTweaks, onClose }) {
  if (!visible) return null;
  return (
    <div className="tweaks-panel">
      <div className="tweaks-header">
        <div className="eyebrow gold">TWEAKS</div>
        <button className="tweaks-close" onClick={onClose}>✕</button>
      </div>
      <div className="tweaks-body">
        <div className="tweak-row">
          <label>재생 속도 <span className="dim">({tweaks.speed} 년/초)</span></label>
          <input type="range" min="5" max="400" step="5" value={tweaks.speed}
                 onChange={(e) => setTweaks({ speed: +e.target.value })}/>
        </div>
        <div className="tweak-row">
          <label>자동 회전 속도 <span className="dim">({tweaks.rotationSpeed.toFixed(2)})</span></label>
          <input type="range" min="0" max="0.5" step="0.01" value={tweaks.rotationSpeed}
                 onChange={(e) => setTweaks({ rotationSpeed: +e.target.value })}/>
        </div>
        <div className="tweak-row">
          <label>글로우 강도 <span className="dim">({tweaks.glow.toFixed(2)})</span></label>
          <input type="range" min="0" max="2.2" step="0.05" value={tweaks.glow}
                 onChange={(e) => setTweaks({ glow: +e.target.value })}/>
        </div>
        <div className="tweak-row">
          <label>팔레트</label>
          <div className="palette-picker">
            {Object.entries(PALETTES).map(([key, p]) => (
              <button key={key}
                      className={`palette-swatch ${tweaks.paletteKey === key ? 'on' : ''}`}
                      onClick={() => setTweaks({ paletteKey: key })}
                      title={p.name}>
                <span className="sw" style={{ background: p.oceanDeep }}/>
                <span className="sw" style={{ background: p.land }}/>
                <span className="sw" style={{ background: p.accent }}/>
                <span className="palette-name">{p.name}</span>
              </button>
            ))}
          </div>
        </div>
        <div className="tweak-row">
          <label>시각 요소</label>
          <div className="toggle-row">
            <button className={`toggle-chip ${tweaks.showEmpires ? 'on' : ''}`}
                    onClick={() => setTweaks({ showEmpires: !tweaks.showEmpires })}>제국</button>
            <button className={`toggle-chip ${tweaks.showCities ? 'on' : ''}`}
                    onClick={() => setTweaks({ showCities: !tweaks.showCities })}>도시</button>
            <button className={`toggle-chip ${tweaks.showArcs ? 'on' : ''}`}
                    onClick={() => setTweaks({ showArcs: !tweaks.showArcs })}>교역로</button>
            <button className={`toggle-chip ${tweaks.showClimate ? 'on' : ''}`}
                    onClick={() => setTweaks({ showClimate: !tweaks.showClimate })}>기후</button>
          </div>
        </div>
      </div>
    </div>
  );
}

// ── Root app ────────────────────────────────────────────────────
const DEFAULTS = /*EDITMODE-BEGIN*/{
  "paletteKey": "heritage",
  "speed": 60,
  "rotationSpeed": 0.08,
  "glow": 1.0,
  "showEmpires": true,
  "showCities": true,
  "showArcs": true,
  "showClimate": true,
  "startYear": -3000
}/*EDITMODE-END*/;

function App() {
  const [year, setYear] = useState(() => {
    const saved = +localStorage.getItem('hg_year');
    return Number.isFinite(saved) && saved !== 0 ? saved : DEFAULTS.startYear;
  });
  const [playing, setPlaying] = useState(true);
  const [tweaks, setTweaksState] = useState(() => ({ ...DEFAULTS }));
  const [hoverEmpire, setHoverEmpire] = useState(null);
  const [activeHint, setActiveHint] = useState(null);
  const [tweaksVisible, setTweaksVisible] = useState(false);
  const [editMode, setEditMode] = useState(false);

  const mountRef = useRef(null);
  const globeRef = useRef(null);
  const stateRef = useRef({});

  // keep state fresh for the globe loop
  stateRef.current = {
    year,
    playing,
    glow: tweaks.glow,
    rotationSpeed: tweaks.rotationSpeed,
    palette: PALETTES[tweaks.paletteKey] || PALETTES.heritage,
  };

  const setTweaks = (partial) => setTweaksState((t) => ({ ...t, ...partial }));

  // ── persist year ──
  useEffect(() => { localStorage.setItem('hg_year', String(Math.round(year))); }, [year]);

  // ── playback driver ──
  useEffect(() => {
    if (!playing) return;
    let raf;
    let last = performance.now();
    const tick = (now) => {
      const dt = (now - last) / 1000;
      last = now;
      setYear((y) => {
        const next = y + dt * tweaks.speed;
        if (next >= DATA.timeRange[1]) return DATA.timeRange[1];
        return next;
      });
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [playing, tweaks.speed]);

  // pause at end
  useEffect(() => {
    if (year >= DATA.timeRange[1]) setPlaying(false);
  }, [year]);

  // ── mount globe (once) ──
  useEffect(() => {
    if (!mountRef.current) return;
    const globe = window.HistoryGlobe({
      mount: mountRef.current,
      getState: () => stateRef.current,
      onHoverEmpire: (e) => setHoverEmpire((prev) => (prev === e ? prev : e)),
      onActiveHint: (e) => setActiveHint((prev) => (prev === e ? prev : e)),
    });
    globeRef.current = globe;
    return () => globe.dispose();
  }, []);

  // ── edit mode protocol ──
  useEffect(() => {
    const onMsg = (e) => {
      if (e.data?.type === '__activate_edit_mode') { setEditMode(true); setTweaksVisible(true); }
      if (e.data?.type === '__deactivate_edit_mode') { setEditMode(false); setTweaksVisible(false); }
    };
    window.addEventListener('message', onMsg);
    window.parent.postMessage({ type: '__edit_mode_available' }, '*');
    return () => window.removeEventListener('message', onMsg);
  }, []);

  // persist tweaks to host
  useEffect(() => {
    window.parent.postMessage({ type: '__edit_mode_set_keys', edits: tweaks }, '*');
  }, [tweaks]);

  // ── page-level palette applies to bg ──
  const palette = PALETTES[tweaks.paletteKey] || PALETTES.heritage;

  return (
    <div className="stage" style={{ background: palette.bg }}>
      {/* subtle grid texture */}
      <div className="bg-texture"/>

      {/* top bar */}
      <header className="topbar">
        <div className="brand">
          <img src="assets/logo-mark.svg" alt=""/>
          <div>
            <div className="brand-name">역사 지구본</div>
            <div className="brand-sub">HISTORICAL GLOBE · READ MASTER</div>
          </div>
        </div>
        <div className="topbar-center">
          <div className="eyebrow gold">읽는 지구 · 시간을 흐르는 문명</div>
        </div>
        <div className="topbar-right">
          <button className="ghost-btn" onClick={() => setTweaksVisible((v) => !v)}>
            <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="1.6"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06A1.65 1.65 0 0 0 9 4.6a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09A1.65 1.65 0 0 0 15 4.6a1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>
            Tweaks
          </button>
        </div>
      </header>

      {/* stage */}
      <div className="stage-body">
        <aside className="left-pane">
          <EraPanel year={year} hoverEmpire={hoverEmpire} activeHint={activeHint}/>
        </aside>

        <div className="globe-wrap">
          <div className="globe-mount" ref={mountRef}/>
          {/* overlay decorations */}
          <div className="ring-ornament top"/>
          <div className="ring-ornament bottom"/>
          <div className="hint drag-hint">드래그하여 회전 · 휠로 확대</div>
        </div>

        <aside className="right-pane">
          <div className="side-card">
            <div className="eyebrow gold">EMPIRES · 제국</div>
            <div className="side-list">
              {activeEmpires(year)
                .sort((a, b) => (b.peak - year === 0 ? 1 : Math.abs(b.peak - year) - Math.abs(a.peak - year)))
                .slice(0, 8)
                .map((emp) => {
                  const life = emp.end - emp.start;
                  const lifeT = (year - emp.start) / life;
                  return (
                    <button key={emp.id} className="empire-row"
                            onClick={() => globeRef.current?.focusEmpire(emp)}
                            onMouseEnter={() => setHoverEmpire(emp)}
                            onMouseLeave={() => setHoverEmpire(null)}>
                      <div className="empire-dot" style={{ background: emp.color }}/>
                      <div className="empire-info">
                        <div className="empire-name-row">{emp.name}</div>
                        <div className="empire-life">
                          <div className="empire-life-bar" style={{ width: `${Math.min(100, Math.max(0, lifeT * 100))}%` }}/>
                        </div>
                        <div className="empire-dates-row">
                          {formatYearShort(emp.start)} → {formatYearShort(emp.end)}
                        </div>
                      </div>
                    </button>
                  );
                })}
              {activeEmpires(year).length === 0 && (
                <div className="empty-note">이 시점에 분류된 제국 없음</div>
              )}
            </div>
          </div>

          <div className="side-card sm">
            <div className="eyebrow gold">NEWLY FOUNDED</div>
            <div className="side-list">
              {DATA.cities
                .filter((c) => Math.abs(c.founded - year) < 100)
                .slice(0, 5)
                .map((c) => (
                  <div key={c.name} className="city-row">
                    <div className="city-dot"/>
                    <div>
                      <div className="city-name">{c.name} <span className="dim">· {c.en}</span></div>
                      <div className="city-founded">창건 {formatYearShort(c.founded)}</div>
                    </div>
                  </div>
                ))}
              {DATA.cities.filter((c) => Math.abs(c.founded - year) < 100).length === 0 && (
                <div className="empty-note">이 시점 근방에 창건된 주요 도시 없음</div>
              )}
            </div>
          </div>
        </aside>
      </div>

      {/* bottom */}
      <footer className="bottombar">
        <ChapterStrip year={year} setYear={setYear}/>
        <Timeline year={year} setYear={setYear} playing={playing}/>
        <PlayControls
          playing={playing} setPlaying={setPlaying}
          speed={tweaks.speed} setSpeed={(s) => setTweaks({ speed: s })}
          year={year} setYear={setYear}
          onReset={() => { setYear(DEFAULTS.startYear); setPlaying(true); }}/>
      </footer>

      <TweaksPanel visible={tweaksVisible} tweaks={tweaks} setTweaks={setTweaks} onClose={() => setTweaksVisible(false)}/>
    </div>
  );
}

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