/* App root — view routing (home / project), index overlay, language toggle,
 * and the Tweaks panel. State persists to localStorage so refresh keeps place.
 */

const {
  useTweaks, TweaksPanel, TweakSection,
  TweakRadio, TweakSelect, TweakColor,
} = window;
const { TextEditLayer, MediaSlot: MSlotApp } = window;
const { useState: useStateApp, useEffect: useEffectApp, useCallback, useMemo: useMemoApp } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "fontPair": "helvetica",
  "palette": "paper",
  "gridView": "list",
  "heroVariant": "wordmark"
}/*EDITMODE-END*/;

const LS_KEY = 'ke-portfolio-nav';

function loadNav() {
  try {
    const s = JSON.parse(localStorage.getItem(LS_KEY) || 'null');
    if (s && typeof s === 'object') return s;
  } catch {}
  return { view: 'home', idx: 0, lang: 'en' };
}

/* ---- Index / Base overlay ----
 * A dense thumbnail-grid index of every project (graphic design + photo).
 * Mirrors the same media slots used on project pages so any image the owner
 * has dropped also appears here — keeping the whole site in one visual system.
 * Toggle to a typographic list view for scanning; filter by section and
 * year; search by title / client / type.
 */
function IndexOverlay({ lang, open, onClose, onOpen, onOpenSeries }) {
  const { COPY, PROJECTS, PHOTO } = window.PORTFOLIO;
  const U = COPY.ui;
  const [q, setQ] = useStateApp('');
  const [mode, setMode] = useStateApp('grid');     // 'grid' | 'list'
  const [section, setSection] = useStateApp('all'); // 'all' | 'gd' | 'photo'
  const [year, setYear] = useStateApp('all');

  useEffectApp(() => { if (open) { setQ(''); } }, [open]);

  // Unified item shape: { kind, id, idx, year, title, client, kindLabel, mediaId, tone, openIdx }
  const items = useMemoApp(() => {
    const gd = PROJECTS.map((p, i) => ({
      kind: 'gd',
      id: p.id, idx: p.idx, year: p.year, tone: p.tone,
      title: p.title[lang], client: p.client[lang], kindLabel: p.typeLabel[lang],
      mediaId: `proj-${p.id}-lead`, openIdx: i,
    }));
    const ph = PHOTO.map((s, i) => ({
      kind: 'photo',
      id: s.id, idx: s.idx, year: s.year, tone: s.tone,
      title: s.title[lang], client: s.client[lang], kindLabel: s.kind[lang],
      mediaId: `ph-${s.id}-g0`, openIdx: i,
    }));
    return [...gd, ...ph];
  }, [lang]);

  const years = useMemoApp(() => {
    const set = new Set(items.map((it) => it.year));
    return [...set].sort((a, b) => b - a);
  }, [items]);

  const filtered = items.filter((it) => {
    if (section !== 'all' && it.kind !== section) return false;
    if (year !== 'all' && String(it.year) !== String(year)) return false;
    if (!q) return true;
    const hay = `${it.title} ${it.client} ${it.kindLabel} ${it.year}`.toLowerCase();
    return hay.includes(q.toLowerCase());
  });

  const sectionLabel = {
    all:   lang === 'ru' ? 'Всё' : 'All',
    gd:    lang === 'ru' ? 'Графика' : 'Graphic',
    photo: lang === 'ru' ? 'Фото' : 'Photo',
  };

  const openItem = (it) => {
    if (it.kind === 'gd') onOpen(it.openIdx);
    else if (onOpenSeries) onOpenSeries(it.openIdx);
  };

  return (
    <div className={`idxov idxov--${mode} ${open ? 'is-open' : ''}`} aria-hidden={!open}>
      <div className="idxov-bar">
        <div className="idxov-bar-l pf-mono">
          <span className="idxov-bar-mark">■</span>
          <span>{lang === 'ru' ? 'База' : 'Base'} / {U.index[lang]}</span>
          <span className="pf-em">— {filtered.length}/{items.length}</span>
        </div>
        <div className="idxov-search">
          <span className="pf-mono">⌕</span>
          <input
            className="idxov-input"
            value={q}
            onChange={(e) => setQ(e.target.value)}
            placeholder={lang === 'ru' ? 'название, клиент, формат…' : 'title, client, type…'}
          />
        </div>
        <div className="idxov-bar-r">
          <div className="idxov-viewtoggle pf-mono" role="tablist">
            <button data-on={mode === 'grid'} onClick={() => setMode('grid')} aria-label="Grid view">▦</button>
            <button data-on={mode === 'list'} onClick={() => setMode('list')} aria-label="List view">☰</button>
          </div>
          <button className="idxov-close" onClick={onClose}>{U.close[lang]} <span>×</span></button>
        </div>
      </div>

      {/* Filter sub-bar */}
      <div className="idxov-filters pf-mono">
        <div className="idxov-chips" role="tablist" aria-label="section">
          {['all', 'gd', 'photo'].map((s) => (
            <button key={s} className="idxov-chip" data-on={section === s} onClick={() => setSection(s)}>
              {sectionLabel[s]}
            </button>
          ))}
        </div>
        <div className="idxov-chips idxov-years" aria-label="year">
          <button className="idxov-chip" data-on={year === 'all'} onClick={() => setYear('all')}>
            {lang === 'ru' ? 'Все годы' : 'All years'}
          </button>
          {years.map((y) => (
            <button key={y} className="idxov-chip" data-on={String(year) === String(y)} onClick={() => setYear(y)}>
              {y}
            </button>
          ))}
        </div>
      </div>

      {/* Body */}
      {mode === 'grid' ? (
        <div className="idxov-grid">
          {filtered.map((it) => (
            <div key={`${it.kind}-${it.id}`} className="idxov-tile" role="button" tabIndex={0}
              onClick={() => openItem(it)}
              onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); openItem(it); } }}
            >
              <div className="idxov-tile-thumb" style={{ '--tone': it.tone }}>
                <MSlotApp
                  id={it.mediaId}
                  lang={lang}
                  ratio="4/5"
                  tone={it.tone}
                  className="idxov-tile-media"
                  label={it.title}
                />
                <span className="idxov-tile-tag pf-mono">{it.kind === 'photo' ? 'PH' : 'GD'} · {it.idx}</span>
              </div>
              <div className="idxov-tile-meta">
                <div className="idxov-tile-title">{it.title || <span className="pf-em">—</span>}</div>
                <div className="idxov-tile-sub pf-mono pf-em">
                  <span>{it.kindLabel}</span>
                  <span>{it.year}</span>
                </div>
              </div>
            </div>
          ))}
          {filtered.length === 0 && (
            <div className="idxov-empty pf-mono pf-em">{lang === 'ru' ? 'Ничего не найдено' : 'Nothing found'}</div>
          )}
        </div>
      ) : (
        <div className="idxov-list">
          {filtered.map((it) => (
            <button key={`${it.kind}-${it.id}`} className="idxov-row" onClick={() => openItem(it)}>
              <span className="idxov-num pf-mono">{it.idx}</span>
              <span className="idxov-title">{it.title || <span className="pf-em">—</span>}</span>
              <span className="idxov-meta pf-mono pf-em">{it.kindLabel} — {it.year}</span>
              <span className="idxov-arrow">→</span>
            </button>
          ))}
          {filtered.length === 0 && (
            <div className="idxov-empty pf-mono pf-em">{lang === 'ru' ? 'Ничего не найдено' : 'Nothing found'}</div>
          )}
        </div>
      )}
    </div>
  );
}

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const init = loadNav();
  const [view, setView] = useStateApp(init.view);
  const [idx, setIdx] = useStateApp(init.idx);
  const [origin, setOrigin] = useStateApp(init.origin || 'home');
  const [photoIdx, setPhotoIdx] = useStateApp(init.photoIdx || 0);
  const [lang, setLang] = useStateApp(init.lang);
  const [editMode, setEditMode] = useStateApp(false);

  // Persist navigation
  useEffectApp(() => {
    try { localStorage.setItem(LS_KEY, JSON.stringify({ view, idx, photoIdx, lang, origin })); } catch {}
  }, [view, idx, photoIdx, lang, origin]);

  // Track the current view so openProject can remember where it was launched
  // from (Works / Photo / Home) and Back can return there.
  const viewRef = React.useRef(view);
  useEffectApp(() => { viewRef.current = view; }, [view]);

  // Scroll to top on view / project change
  useEffectApp(() => { window.scrollTo({ top: 0, behavior: 'instant' }); }, [view, idx, photoIdx]);

  const openProject = useCallback((i) => {
    // Remember the section we came from, but keep it stable when paging
    // between projects (next/prev, teaser) so Back always returns to the list.
    const from = viewRef.current;
    if (from !== 'project') setOrigin(from === 'works' || from === 'photo' ? from : 'home');
    setIdx(i);
    setView('project');
  }, []);
  const openSeries = useCallback((i) => {
    setPhotoIdx(i);
    setView('photoseries');
  }, []);
  const goHome = useCallback(() => { setView('home'); }, []);
  const goPhoto = useCallback(() => { setView('photo'); }, []);
  const goWorks = useCallback(() => { setView('works'); }, []);
  // Back out of a project to whichever section it was opened from.
  const backFromProject = useCallback(() => {
    if (origin === 'works') goWorks();
    else if (origin === 'photo') goPhoto();
    else goHome();
  }, [origin, goWorks, goPhoto, goHome]);

  // Keyboard
  useEffectApp(() => {
    const onKey = (e) => {
      if (e.key === 'Escape') {
        if (view === 'photoseries') goPhoto();
        else if (view === 'project') backFromProject();
        else if (view === 'photo' || view === 'works') goHome();
      }
      if (view === 'project') {
        const { PROJECTS } = window.PORTFOLIO;
        if (e.key === 'ArrowRight') openProject((idx + 1) % PROJECTS.length);
        if (e.key === 'ArrowLeft') openProject((idx - 1 + PROJECTS.length) % PROJECTS.length);
      }
      if (view === 'photoseries') {
        const { PHOTO } = window.PORTFOLIO;
        if (e.key === 'ArrowRight') openSeries((photoIdx + 1) % PHOTO.length);
        if (e.key === 'ArrowLeft') openSeries((photoIdx - 1 + PHOTO.length) % PHOTO.length);
      }
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [view, idx, photoIdx, openProject, openSeries, goHome, goPhoto, backFromProject]);

  const themeClass = `theme-${t.palette} font-${t.fontPair}`;

  // palette swatch resolver
  const paletteValue =
    t.palette === 'paper' ? ['#ffffff', '#0a0a0a', '#cc3a1a'] :
    t.palette === 'bone'  ? ['#f4f1ea', '#1a1815', '#b06a3f'] :
    t.palette === 'ink'   ? ['#0c0c0b', '#f4f2ec', '#e9b84a'] :
                            ['#e7efe9', '#0e1b13', '#2f5dc7'];

  return (
    <div className={`pf-app ${themeClass}`}>
      {/* Owner edits inline without a toggle button: as owner, click any text
          to edit it; drop photos / add video on the slots. Visitors see none
          of this. */}
      <TextEditLayer lang={lang} editMode={!!window.PF_OWNER} />

      <main className="pf-main">
        {view === 'home' && (
          <div className="pf-view" key="home">
            <Home
              lang={lang}
              heroVariant={t.heroVariant}
              gridView={t.gridView}
              onOpen={openProject}
              onPhoto={goPhoto}
              onWorks={goWorks}
            />
          </div>
        )}
        {view === 'project' && (
          <div className="pf-view" key={'proj-' + idx}>
            <Project
              lang={lang}
              index={idx}
              onBack={backFromProject}
              onOpen={openProject}
              onHome={goHome}
            />
          </div>
        )}
        {view === 'photo' && (
          <div className="pf-view" key="photo">
            <Photo
              lang={lang}
              onBack={goHome}
              onOpenSeries={openSeries}
            />
          </div>
        )}
        {view === 'photoseries' && (
          <div className="pf-view" key={'phser-' + photoIdx}>
            <PhotoSeries
              lang={lang}
              index={photoIdx}
              onBack={goPhoto}
              onOpen={openSeries}
            />
          </div>
        )}
        {view === 'works' && (
          <div className="pf-view" key="works">
            <Works
              lang={lang}
              onBack={goHome}
              onOpen={openProject}
            />
          </div>
        )}
      </main>

      <TweaksPanel title="Tweaks">
        <TweakSection label="Typography" />
        <TweakSelect label="Type pair" value={t.fontPair}
          options={[
            { value: 'archivo',   label: 'Archivo Narrow + Archivo' },
            { value: 'helvetica', label: 'Helvetica' },
            { value: 'display',   label: 'Anton + Archivo' },
          ]}
          onChange={(v) => setTweak('fontPair', v)} />

        <TweakSection label="Palette" />
        <TweakColor label="Theme" value={paletteValue}
          options={[
            ['#ffffff', '#0a0a0a', '#cc3a1a'],
            ['#f4f1ea', '#1a1815', '#b06a3f'],
            ['#0c0c0b', '#f4f2ec', '#e9b84a'],
            ['#e7efe9', '#0e1b13', '#2f5dc7'],
          ]}
          onChange={(v) => {
            const map = { '#ffffff': 'paper', '#f4f1ea': 'bone', '#0c0c0b': 'ink', '#e7efe9': 'mint' };
            setTweak('palette', map[v[0]] || 'paper');
          }} />

        <TweakSection label="Home layout" />
        <TweakRadio label="Hero" value={t.heroVariant}
          options={[
            { value: 'wordmark',  label: 'Mark' },
            { value: 'editorial', label: 'Edit.' },
            { value: 'statement', label: 'Stmt.' },
          ]}
          onChange={(v) => setTweak('heroVariant', v)} />
        <TweakRadio label="Works grid" value={t.gridView}
          options={[
            { value: 'list',    label: 'List' },
            { value: 'gallery', label: 'Gallery' },
            { value: 'tiles',   label: 'Tiles' },
          ]}
          onChange={(v) => setTweak('gridView', v)} />
      </TweaksPanel>
    </div>
  );
}

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