/* FINAZ — Shell con pestañas (Intradía / Drawdown / Causa-efecto) y la
   vista de gráfico intradía. El shell aplica el tema y el toggle Oscuro/Claro;
   cada vista gestiona su propia interacción y narrativa. */
(function () {
  "use strict";
  const { useState, useEffect, useLayoutEffect, useRef, useCallback } = React;
  const e = React.createElement;
  const UI = window.FinazUI;

  const CHART_W = 880, CHART_H = 440;
  const PLAY_DUR = 26000;

  function beatAt(beats, idx) {
    if (idx == null) return null;
    for (const b of beats) if (idx >= b.i0 && idx <= b.i1) return b;
    return beats[beats.length - 1];
  }

  // auto-narración una sola vez por vista en la sesión
  function autoNarrateOnce(key, setPlaying, delay) {
    if (!window.__fzNarr) window.__fzNarr = {};
    if (!window.__fzNarr[key]) {
      window.__fzNarr[key] = true;
      const t = setTimeout(() => setPlaying(true), delay || 1400);
      return () => clearTimeout(t);
    }
  }

  /* ═══════════════════════ SHELL ═══════════════════════ */
  function FinazApp() {
    const THEMES = window.FINAZ_THEMES;
    const [themeId, setThemeId] = useState("organico");
    const [view, setView] = useState("intraday");
    const theme = THEMES[themeId];
    const T = theme.tokens;

    useLayoutEffect(() => {
      const root = document.documentElement;
      root.classList.add("fz-switching");
      const t = setTimeout(() => root.classList.remove("fz-switching"), 90);
      return () => clearTimeout(t);
    }, [themeId]);

    const cssVars = {
      "--fz-bg": T.bg, "--fz-panel": T.panel, "--fz-edge": T.panelEdge,
      "--fz-ink": T.ink, "--fz-sub": T.sub, "--fz-faint": T.faint,
      "--fz-accent": T.accent, "--fz-accent2": T.accent2, "--fz-accent3": T.accent3,
      "--fz-pos": T.pos, "--fz-neg": T.neg, "--fz-chip": T.chipBg, "--fz-chipink": T.chipInk,
      "--fz-display": theme.fonts.display, "--fz-body": theme.fonts.body, "--fz-mono": theme.fonts.mono,
      "--fz-glow": T.glowText, "--fz-rad": (theme.chart.radius ? "14px" : "0px"),
      "--fz-rad-sm": (theme.chart.radius ? "8px" : "0px"),
      "--fz-bg-grad": (T.bgGrad && T.bgGrad !== "none") ? T.bgGrad : ("linear-gradient(" + T.bg + "," + T.bg + ")"),
      fontFamily: theme.fonts.body,
    };

    const tabs = [["intraday", "Intradía"], ["drawdown", "Drawdown"], ["chain", "Causa-efecto"]];

    return e("div", { className: "fz-root" + (theme.chart.grain ? " fz-grain" : ""), style: cssVars, "data-mode": theme.mode },
      e("header", { className: "fz-top" },
        e("div", { className: "fz-brand" },
          e("span", { className: "fz-logo" }, "FINAZ"),
          e("span", { className: "fz-lab" }, "Orgánico Verde — sistema de gráficos")
        ),
        e("div", { className: "fz-headright" },
          e("nav", { className: "fz-tabs" },
            tabs.map(([id, lab]) => e("button", { key: id, className: "fz-tab" + (view === id ? " on" : ""), onClick: () => setView(id) }, lab))
          ),
          e("div", { className: "fz-modetoggle" },
            e("div", { className: "fz-seg" },
              [["organico", "Oscuro", "☾"], ["organicoLight", "Claro", "☀"]].map(([id, lab, ic]) =>
                e("button", { key: id, className: "fz-segbtn" + (themeId === id ? " on" : ""), onClick: () => setThemeId(id) },
                  e("span", { className: "fz-segic" }, ic), lab))
            )
          )
        )
      ),
      view === "intraday" && e(IntradayView, { theme }),
      view === "drawdown" && e(window.FinazDrawdownView, { theme }),
      view === "chain" && e(window.FinazChainView, { theme })
    );
  }

  /* ═══════════════════ VISTA INTRADÍA ═══════════════════ */
  function IntradayView({ theme }) {
    const data = window.FINAZ_DATA;
    const n = data.points.length;
    const [focusIdx, setFocusIdx] = useState(null);
    const [playing, setPlaying] = useState(false);
    const [marker, setMarker] = useState(null);
    const [layers, setLayers] = useState({ anotaciones: true, niveles: false, volumen: false, fuentes: true });
    const activeBeat = beatAt(data.beats, focusIdx);

    useEffect(() => autoNarrateOnce("intraday", setPlaying, 1400), []);
    useEffect(() => { setFocusIdx(null); setPlaying(false); setMarker(null); }, [theme.family]);

    useEffect(() => {
      if (!playing) return;
      const startP = (focusIdx == null || focusIdx >= n - 1) ? 0 : focusIdx / (n - 1);
      const t0 = performance.now();
      const iv = setInterval(() => {
        const p = Math.min(1, startP + (performance.now() - t0) / PLAY_DUR);
        setFocusIdx(Math.round(p * (n - 1)));
        if (p >= 1) { clearInterval(iv); setPlaying(false); }
      }, 33);
      return () => clearInterval(iv);
    }, [playing]); // eslint-disable-line

    const userFocus = useCallback((idx) => { setPlaying(false); setFocusIdx(idx); }, []);
    const toggleLayer = (k) => setLayers((s) => ({ ...s, [k]: !s[k] }));
    const togglePlay = () => {
      if (playing) setPlaying(false);
      else { if (focusIdx == null || focusIdx >= n - 1) setFocusIdx(0); setPlaying(true); }
    };

    const tlRef = useRef(null);
    const tlScrub = useCallback((ev) => {
      const r = tlRef.current.getBoundingClientRect();
      const k = Math.max(0, Math.min(1, (ev.clientX - r.left) / r.width));
      userFocus(Math.round(k * (n - 1)));
    }, [userFocus, n]);

    const m = data.meta, up = m.changeAbs >= 0;
    const cards = [];
    if (activeBeat && activeBeat.glossary) { const g = data.glossary[activeBeat.glossary]; cards.push({ type: "term", label: "Glosario", head: g.term, text: g.text }); }
    if (activeBeat && activeBeat.news) { const nw = data.news[activeBeat.news]; cards.push({ type: "news", label: "Noticia", head: nw.source + " · " + nw.time, headline: nw.headline, text: nw.text }); }

    return e("div", { className: "fz-stage" },
      e("section", { className: "fz-left" },
        // cabecera de cotización
        e("div", { className: "fz-symrow" },
          e("div", { className: "fz-sym" },
            e("div", { className: "fz-symname" }, e("strong", null, m.symbol), e("span", null, m.name + " · " + m.date)),
            e("div", { className: "fz-price" },
              e("span", { className: "fz-pv" }, (focusIdx == null ? m.last : data.points[focusIdx].v).toLocaleString("es-ES")),
              e("span", { className: "fz-unit" }, m.currency)),
            e("div", { className: "fz-chg " + (up ? "pos" : "neg") }, (up ? "▲ +" : "▼ ") + m.changeAbs + "  (" + (up ? "+" : "") + m.changePct + "%)")
          ),
          UI.e(UI.LayerChips, { layers, onToggle: toggleLayer, defs: [["anotaciones", "Anotaciones"], ["niveles", "Niveles"], ["volumen", "Volumen"], ["fuentes", "Fuentes"]] })
        ),

        e("div", { className: "fz-chartcard" },
          e(window.FinazChart, { theme, data, width: CHART_W, height: CHART_H, layers, focusIdx, playing, activeBeat, onFocus: userFocus, onMarker: setMarker }),
          marker && e(UI.Popover, { marker })
        ),

        e("div", { className: "fz-timeline", ref: tlRef,
          onPointerDown: (ev) => { try { ev.currentTarget.setPointerCapture(ev.pointerId); } catch (err) {} tlScrub(ev); },
          onPointerMove: (ev) => { if (ev.buttons) tlScrub(ev); } },
          data.beats.map((b, i) => e("div", { key: i, className: "fz-tlseg" + (activeBeat === b ? " on" : ""), style: { flex: (b.i1 - b.i0) }, title: b.title },
            e("span", { className: "fz-tltag" }, b.tag))),
          focusIdx != null && e("div", { className: "fz-playhead", style: { left: (focusIdx / (n - 1) * 100) + "%" } })
        ),

        e(UI.SourcesFooter, { on: layers.fuentes, source: data.source, disclaimer: data.disclaimer })
      ),

      e("aside", { className: "fz-right" },
        e(UI.PlayBar, { playing, idle: focusIdx == null, progress: focusIdx == null ? 0 : focusIdx / (n - 1), onToggle: togglePlay }),
        activeBeat
          ? e(UI.NarrativeCard, { anim: activeBeat.tag, tag: activeBeat.tag, kind: activeBeat.kind, time: data.points[activeBeat.i0].t + "–" + data.points[activeBeat.i1].t, title: activeBeat.title, body: activeBeat.body })
          : e(UI.NarrativeCard, { summary: true, tag: "Sesión completa", title: "Una jornada en una sola línea",
              body: e(React.Fragment, null, "Pulsa ", e("strong", null, "Reproducir explicación"), " para que FINAZ te narre la sesión, o ", e("strong", null, "arrastra"), " sobre el gráfico para explorar cualquier instante."),
              children: e(UI.StatGrid, { stats: [["Apertura", m.open], ["Cierre", m.last], ["Máximo", m.hi], ["Mínimo", m.lo]] }) }),
        e(UI.ExtraCards, { cards })
      )
    );
  }

  window.FinazApp = FinazApp;
})();
