// ====================================================================
// APP — root, drill-down, modo kiosko, persistencia, idioma
// ====================================================================

// Drawer removed as per customer request

// ---- Modo kiosko ----
function Kiosk({ onExit }) {
  const { t, lang } = useLang();
  const views = [
    { key: "nav_summary", node: <Summary onOpen={() => {}} /> },
    { key: "nav_competitors", node: <Competitors onSelectComp={() => {}} /> },
  ];
  const [i, setI] = React.useState(0);
  React.useEffect(() => {
    const id = setInterval(() => setI(v => (v + 1) % views.length), 15000);
    return () => clearInterval(id);
  }, []);
  return (
    <div className="kiosk">
      <div className="kiosk-top">
        <img className="brand-logo" src="/logo.png" alt="QFIN" />
        <h2>{t(views[i].key)}</h2>
        <div className="kiosk-prog">
          {views.map((_, k) => <i key={`${i}-${k}`} className={k === i ? "on" : ""}></i>)}
        </div>
        <button className="kiosk-exit" onClick={onExit}><Ic name="x" style={{ width: 15, height: 15 }} />{t("kioskExit")}</button>
      </div>
      <div className="kiosk-body" style={{ overflowY: "auto" }} key={i}>
        <div style={{ fontSize: 11, color: "var(--ice-faint)", marginBottom: 14 }}>{t("kiosk_rotating")}</div>
        {views[i].node}
      </div>
    </div>
  );
}

// ---- App ----
function App() {
  const [lang, setLangState] = React.useState(() => localStorage.getItem("qo_lang") || "es");
  const [active, setActiveState] = React.useState(() => {
    const saved = localStorage.getItem("qo_section");
    return ["summary", "competitors", "reviews"].includes(saved) ? saved : "summary";
  });
  const [period, setPeriodState] = React.useState(() => localStorage.getItem("qo_period") || "d30");
  const [mention, setMention] = React.useState(null);
  const [kiosk, setKiosk] = React.useState(false);
  const [selectedComp, setSelectedComp] = React.useState(null); // { key, name, color }
  const [searchQuery, setSearchQuery] = React.useState("");

  // --- Ingest state + data refresh key ---
  const [ingesting, setIngesting] = React.useState(false);
  const [ingestProgress, setIngestProgress] = React.useState(0);
  const [ingestDetails, setIngestDetails] = React.useState("");
  const [ingestErr, setIngestErr] = React.useState("");
  // refreshKey: cuando sube, las secciones se remontan y releen window.MOCK actualizado
  const [refreshKey, setRefreshKey] = React.useState(0);

  const setLang = (l) => { setLangState(l); localStorage.setItem("qo_lang", l); };
  const setActive = (s) => { 
    setActiveState(s); 
    localStorage.setItem("qo_section", s); 
    setSearchQuery(""); // Limpiar búsqueda al cambiar de pestaña
  };
  const setPeriod = (p) => { setPeriodState(p); localStorage.setItem("qo_period", p); };

  React.useEffect(() => { document.documentElement.setAttribute("data-lang", lang); document.documentElement.lang = lang === "zh" ? "zh" : lang === "en" ? "en" : "es"; }, [lang]);
  React.useEffect(() => {
    const onKey = (e) => { if (e.key === "Escape") { setMention(null); setKiosk(false); } };
    window.addEventListener("keydown", onKey); return () => window.removeEventListener("keydown", onKey);
  }, []);

  // Consultar progreso real de la ingesta
  React.useEffect(() => {
    if (!ingesting) {
      setIngestProgress(0);
      setIngestDetails("");
      return;
    }
    const poll = async () => {
      try {
        const r = await fetch("/api/ingest/status");
        if (r.ok) {
          const status = await r.json();
          if (status.active) {
            setIngestProgress(status.progress);
            setIngestDetails(status.details);
          }
        }
      } catch (e) {
        console.warn("Error consultando progreso:", e);
      }
    };
    poll();
    const timer = setInterval(poll, 1200);
    return () => clearInterval(timer);
  }, [ingesting]);

  const triggerIngest = React.useCallback(async () => {
    setIngesting(true);
    setIngestErr("");
    try {
      const r = await fetch("/api/ingest", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({}),
      });
      if (r.ok) {
        // Ingest completo: leer datos frescos del backend (rápido, ya en memoria)
        try {
          if (typeof window.QO_LOAD === "function") {
            const fresh = await window.QO_LOAD();
            if (fresh) Object.assign(window.MOCK, fresh);
          }
        } catch (e2) {
          console.warn("QO_LOAD post-ingest:", e2);
        }
        // Guardar timestamp y forzar re-render de todas las secciones
        localStorage.setItem("qo_last_ingest", String(Date.now()));
        setRefreshKey(k => k + 1);
        setIngesting(false);
      } else {
        setIngestErr(`Error ${r.status}: ${r.statusText}`);
        setTimeout(() => setIngesting(false), 5000);
      }
    } catch (e) {
      setIngestErr("No se pudo conectar con el backend.");
      setTimeout(() => setIngesting(false), 5000);
    }
  }, []);

  const triggerClear = React.useCallback(async () => {
    if (!confirm("¿Seguro que deseas vaciar toda la base de datos de menciones?")) return;
    try {
      const r = await fetch("/api/clear", { method: "POST" });
      if (r.ok) {
        window.MOCK.MENTIONS = [];
        window.MOCK.ALERTS = [];
        window.MOCK.RAW_COMPLAINTS = [];
        window.MOCK.KPIS.risk.value = 0;
        window.MOCK.KPIS.contam.value = 0;
        window.MOCK.KPIS.mentions.value = 0;
        window.MOCK.KPIS.alerts.value = 0;
        window.MOCK.SENTIMENT_SERIES = Array.from({ length: 30 }, (_, i) => ({ d: i, pos: 0, neu: 0, neg: 0 }));
        window.MOCK.NARRATIVES = [];
        setRefreshKey(k => k + 1);
      } else {
        alert("Error al vaciar: " + r.statusText);
      }
    } catch (e) {
      alert("No se pudo conectar al backend para vaciar.");
    }
  }, []);

  const t = React.useCallback((k) => (STR[lang] && STR[lang][k]) || STR.es[k] || k, [lang]);
  const ctx = { lang, setLang, t };

  const titles = { summary: "title_summary", competitors: "title_competitors", reviews: "title_reviews", deep_research: "deep_research_title" };
  // Sufijo dinámico con el mes del snapshot (lo calcula api.jsx desde los datos)
  const snapPeriod = (window.MOCK && window.MOCK.PERIOD) || { labelEs: 'Mayo 2026', labelZh: '2026年5月', labelEn: 'May 2026' };
  const periodSuffix = (active === 'summary' || active === 'competitors')
    ? ' · ' + (lang === 'zh' ? snapPeriod.labelZh : (lang === 'en' ? (snapPeriod.labelEn || snapPeriod.labelEs) : snapPeriod.labelEs))
    : '';

  const open = (m) => setMention(m);
  const handleSelectComp = (comp) => {
    setSelectedComp(comp);
    setActiveState('reviews');
  };
  const handleBackFromReviews = () => {
    setSelectedComp(null);
    setActiveState('competitors');
  };
  // Pasar onIngest + ingesting a Summary para el panel de salud reputacional
  const SECT = {
    summary:     <Summary onOpen={open} onIngest={triggerIngest} ingesting={ingesting} />,
    competitors: <Competitors onSelectComp={handleSelectComp} />,
    reviews:     <CompReviews onOpen={open} comp={selectedComp} onBack={handleBackFromReviews} searchQuery={searchQuery} setSearchQuery={setSearchQuery} />,
    deep_research: <DeepResearchView />,
  };

  return (
    <LangContext.Provider value={ctx}>
      {ingesting && <LoadingOverlay progress={ingestProgress} details={ingestDetails} errMsg={ingestErr} />}
      {kiosk && <Kiosk onExit={() => setKiosk(false)} />}
      <div className="app">
        <Sidebar active={active} onNav={setActive} onKiosk={() => setKiosk(true)} />
        <div className="main">
          <TopBar
            title={t(titles[active]) + periodSuffix}
            searchQuery={searchQuery}
            setSearchQuery={setSearchQuery}
            isSearchable={active === "reviews"}
          />
          {/* key={active + refreshKey} → remonta la sección activa cuando llegan datos frescos */}
          <div className="content" key={active + "-" + refreshKey}>
            {SECT[active]}
          </div>
        </div>
      </div>
      {/* Drawer removed */}
    </LangContext.Provider>
  );
}

// Bootstrap: si ?live=1, muestra el pre-loader y carga datos reales del backend
// antes de montar React. En cualquier otro caso (o si falla) usa el mock curado.
(async function bootstrap() {
  const preload    = document.getElementById("qo-preload");
  const preloadMsg = document.getElementById("qo-preload-msg");

  // Mensajes rotativos mientras esperamos la respuesta del backend
  const PRE_MSGS = [
    "Conectando con el backend…",
    "Obteniendo reseñas de Play Store y App Store…",
    "Consultando prensa y foros…",
    "Analizando las menciones…",
    "Calculando índices de riesgo…",
  ];
  let mi = 0;
  let msgTimer = null;

  if (window.QO_USE_LIVE) {
    if (preload) preload.style.display = "flex";
    msgTimer = setInterval(() => {
      mi = (mi + 1) % PRE_MSGS.length;
      if (preloadMsg) preloadMsg.textContent = PRE_MSGS[mi];
    }, 3500);
  }

  if (window.QO_USE_LIVE && typeof window.QO_LOAD === "function") {
    try {
      const live = await window.QO_LOAD();
      if (live) Object.assign(window.MOCK, live);
    } catch (e) {
      console.warn("QO: carga en vivo falló, usando mock.", e);
    }
  }

  if (msgTimer) clearInterval(msgTimer);
  if (preload) preload.style.display = "none";
  ReactDOM.createRoot(document.getElementById("root")).render(<App />);
})();
