/* app.jsx — Tweaks-Panel, Übersicht, Rendering aller Slides in <deck-stage> */

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "dark": false,
  "accent": "teal",
  "fontScale": 1,
  "footerOn": true,
  "logoOn": true,
  "animOn": true
}/*EDITMODE-END*/;

const ACCENT_MAP = {
  teal:  '#0D9488',
  gold:  '#D4A853',
  ocean: '#2D4A5E',
};

const TEMPLATES = [
  { id: 'cover',     comp: 'SlideCover',      label: 'Cover · Titel',                 type: 'Cover',           defaultDark: true  },
  { id: 'agenda',    comp: 'SlideAgenda',     label: 'Agenda',                        type: 'Inhalt',          defaultDark: false },
  { id: 'section',   comp: 'SlideSection',    label: 'Kapiteltrenner',                type: 'Section',         defaultDark: true  },
  { id: 'text',      comp: 'SlideText',       label: 'Fließtext',                     type: 'Text',            defaultDark: false },
  { id: 'bullets',   comp: 'SlideBullets',    label: 'Bullets / Aufzählung',          type: 'Text',            defaultDark: false },
  { id: 'twocol',    comp: 'SlideTwoCol',     label: 'Zwei-Spalten',                  type: 'Text',            defaultDark: false },
  { id: 'quote',     comp: 'SlideQuote',      label: 'Zitat',                         type: 'Pull-Quote',      defaultDark: true  },
  { id: 'stat',      comp: 'SlideStat',       label: 'Big Number',                    type: 'Statistik',       defaultDark: false },
  { id: 'textimg',   comp: 'SlideTextImage',  label: 'Text + Bild',                   type: 'Bild',            defaultDark: false },
  { id: 'imgfull',   comp: 'SlideImageFull',  label: 'Bild Full-Bleed',               type: 'Bild',            defaultDark: true  },
  { id: 'textvid',   comp: 'SlideTextVideo',  label: 'Text + Video',                  type: 'Video',           defaultDark: false },
  { id: 'vidfull',   comp: 'SlideVideoFull',  label: 'Video Full-Bleed',              type: 'Video',           defaultDark: true  },
  { id: 'compare',   comp: 'SlideCompare',    label: 'Vergleich Vorher/Nachher',      type: 'Compare',         defaultDark: false },
  { id: 'timeline',  comp: 'SlideTimeline',   label: 'Timeline / Prozess',            type: 'Prozess',         defaultDark: false },
  { id: 'table',     comp: 'SlideTable',      label: 'Tabelle',                       type: 'Daten',           defaultDark: false },
  { id: 'chart',     comp: 'SlideChart',      label: 'Diagramm (Bar)',                type: 'Daten',           defaultDark: false },
  { id: 'team',      comp: 'SlideTeam',       label: 'Team',                          type: 'Personen',        defaultDark: false },
  { id: 'cta',       comp: 'SlideCTA',        label: 'Call-to-Action',                type: 'Abschluss',       defaultDark: true  },
];

/* ────────────── Overview Modal ────────────── */
function OverviewModal({ open, onClose, currentIndex, onJump }) {
  React.useEffect(() => {
    if (!open) return;
    const onKey = (e) => {
      if (e.key === 'Escape') { e.preventDefault(); onClose(); }
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [open, onClose]);

  if (!open) return null;
  return (
    <div className="ov-backdrop" onClick={onClose}>
      <div className="ov-head" onClick={(e) => e.stopPropagation()}>
        <div className="ov-title">Übersicht · {TEMPLATES.length} Slides</div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
          <span className="ov-hint">Klicken zum Springen · Esc / O zum Schließen</span>
          <button onClick={onClose} style={{
            appearance: 'none', border: '1px solid rgba(248,246,242,0.18)',
            background: 'rgba(248,246,242,0.06)', color: 'inherit',
            padding: '8px 14px', borderRadius: 999, cursor: 'pointer', font: 'inherit', fontSize: 12,
          }}>Schließen</button>
        </div>
      </div>
      <div className="ov-grid" onClick={(e) => e.stopPropagation()}>
        {TEMPLATES.map((t, i) => (
          <button key={t.id} className={`ov-cell${i === currentIndex ? ' is-current' : ''}`}
                  onClick={() => { onJump(i); onClose(); }}>
            <div className="ov-cell__thumb">
              <div className="ov-cell__num">{String(i + 1).padStart(2, '0')}</div>
              <div style={{ textAlign: 'center', padding: '0 10px' }}>{t.label}</div>
            </div>
            <div className="ov-cell__meta">
              <div className="ov-cell__label">{t.label}</div>
              <div className="ov-cell__type">{t.type}</div>
            </div>
          </button>
        ))}
      </div>
    </div>
  );
}

/* ────────────── App ────────────── */
function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [overviewOpen, setOverviewOpen] = React.useState(false);
  const [currentIndex, setCurrentIndex] = React.useState(0);
  const stageRef = React.useRef(null);

  // Apply tweaks → DOM
  React.useEffect(() => {
    document.documentElement.style.setProperty('--accent', ACCENT_MAP[t.accent] || ACCENT_MAP.teal);
    document.documentElement.style.setProperty('--fs-scale', String(t.fontScale));
    document.documentElement.dataset.anim = t.animOn ? 'on' : 'off';
  }, [t.accent, t.fontScale, t.animOn]);

  // O-Key opens overview
  React.useEffect(() => {
    const onKey = (e) => {
      const tgt = e.target;
      if (tgt && (tgt.isContentEditable || /^(INPUT|TEXTAREA|SELECT)$/.test(tgt.tagName))) return;
      if (e.metaKey || e.ctrlKey || e.altKey) return;
      if (e.key === 'o' || e.key === 'O') {
        e.preventDefault();
        setOverviewOpen(o => !o);
      }
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, []);

  // Hook into deck-stage slide changes
  React.useEffect(() => {
    const stage = document.querySelector('deck-stage');
    if (!stage) return;
    stageRef.current = stage;
    const onChange = (e) => setCurrentIndex(e.detail.index);
    stage.addEventListener('slidechange', onChange);
    return () => stage.removeEventListener('slidechange', onChange);
  }, []);

  const jumpTo = (i) => {
    if (stageRef.current) stageRef.current.goTo(i);
  };

  return (
    <>
      {/* Overview trigger — bottom-left */}
      <button className="ov-trigger" onClick={() => setOverviewOpen(true)} aria-label="Übersicht aller Slides öffnen">
        <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
          <rect x="1.5" y="1.5" width="5" height="5" rx="1"/>
          <rect x="9.5" y="1.5" width="5" height="5" rx="1"/>
          <rect x="1.5" y="9.5" width="5" height="5" rx="1"/>
          <rect x="9.5" y="9.5" width="5" height="5" rx="1"/>
        </svg>
        Übersicht
        <span style={{
          marginLeft: 4, padding: '1px 6px', borderRadius: 4,
          fontFamily: 'ui-monospace, Menlo, monospace', fontSize: 10,
          background: 'rgba(255,255,255,0.12)', color: 'rgba(255,255,255,0.85)',
        }}>O</span>
      </button>

      <OverviewModal open={overviewOpen}
                     onClose={() => setOverviewOpen(false)}
                     currentIndex={currentIndex}
                     onJump={jumpTo} />

      <TweaksPanel title="Tweaks">
        <TweakSection label="Theme">
          <TweakToggle label="Dark Mode (global)" value={t.dark}
                       onChange={(v) => setTweak('dark', v)} />
          <TweakRadio label="Akzentfarbe" value={t.accent}
                      options={[
                        { value: 'teal',  label: 'Teal' },
                        { value: 'gold',  label: 'Gold' },
                        { value: 'ocean', label: 'Ocean' },
                      ]}
                      onChange={(v) => setTweak('accent', v)} />
        </TweakSection>

        <TweakSection label="Typografie">
          <TweakSlider label="Schriftgröße" value={t.fontScale}
                       min={0.85} max={1.2} step={0.05} unit="×"
                       onChange={(v) => setTweak('fontScale', v)} />
        </TweakSection>

        <TweakSection label="Slide-Chrome">
          <TweakToggle label="Footer ein" value={t.footerOn}
                       onChange={(v) => setTweak('footerOn', v)} />
          <TweakToggle label="Logo ein" value={t.logoOn}
                       onChange={(v) => setTweak('logoOn', v)} />
          <TweakToggle label="Animationen" value={t.animOn}
                       onChange={(v) => setTweak('animOn', v)} />
        </TweakSection>
      </TweaksPanel>

      <DeckPortal templates={TEMPLATES} ctx={{
        footerOn: t.footerOn,
        logoOn: t.logoOn,
        total: TEMPLATES.length,
        forceDark: t.dark,
      }} />
    </>
  );
}

/* Render slides into <deck-stage> via a portal so they live in the light DOM
   children of the web component (deck-stage requires its slides as direct
   element children of the slot). */
function DeckPortal({ templates, ctx }) {
  const host = document.querySelector('deck-stage');
  if (!host) return null;

  return ReactDOM.createPortal(
    <>
      {templates.map((tpl, i) => {
        const Comp = window[tpl.comp];
        const slideCtx = { ...ctx, index: i + 1 };
        // Wrapper div so we can apply data-mode override per slide based on
        // the global "dark" toggle. When dark=true everything goes deep-sea;
        // when false we use each template's defaultDark.
        const dark = ctx.forceDark || tpl.defaultDark;
        return (
          <div key={tpl.id}
               data-mode={dark ? 'dark' : 'light'}
               data-label={tpl.label}
               style={{ width: 1920, height: 1080, position: 'relative' }}>
            {Comp ? <Comp ctx={slideCtx} /> : <div style={{ padding: 100, color: 'red' }}>Missing: {tpl.comp}</div>}
          </div>
        );
      })}
    </>,
    host
  );
}

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