/* ============================================================
   EDUCARE — Root app: theme, auth gate, navigation
   ============================================================ */
(function () {
  const { useState, useEffect } = React;
  const { AppShell, NAV, LoginScreen, Dashboard, Placeholder } = window;

  // theme labels for placeholder screens
  const META = {
    pacientes:     { title: "Pacientes",     icon: "users" },
    agenda:        { title: "Agenda",        icon: "calendar" },
    atendimentos:  { title: "Atendimentos",  icon: "clipboardCheck" },
    planejamentos: { title: "Planejamentos", icon: "fileText" },
    avaliacoes:    { title: "Avaliações",    icon: "clipboardList" },
    financeiro:    { title: "Financeiro",    icon: "wallet" },
    whatsapp:      { title: "WhatsApp",      icon: "chat" },
    biblioteca:    { title: "Biblioteca",    icon: "book" },
    flashcards:    { title: "Flashcards",    icon: "layers" },
  };

  // Deriva nome/iniciais do usuário logado (Supabase) para exibir na UI.
  function deriveUser(u) {
    if (!u) return null;
    const meta = u.user_metadata || {};
    const name = String(meta.name || meta.full_name || (u.email ? u.email.split("@")[0] : "") || "Profissional").trim();
    const initials = (name.split(/\s+/).filter(Boolean).slice(0, 2).map((s) => s[0]).join("") || "U").toUpperCase();
    return { name, email: u.email || "", initials, role: meta.role || "Psicopedagogo", emailConfirmed: !!u.email_confirmed_at };
  }

  // Aplica o usuário logado à UI: expõe window.__USER e reflete no profissional "dono".
  function applyUser(sess) {
    const u = sess && sess.user ? deriveUser(sess.user) : null;
    window.__USER = u;
    if (u && Array.isArray(window.PROFESSIONALS)) {
      const owner = window.PROFESSIONALS.find((p) => p.owner);
      if (owner) { owner.name = u.name; owner.initials = u.initials; owner.role = u.role || owner.role; }
    }
    return u;
  }

  function getInitialTheme() {
    const saved = localStorage.getItem("educare-theme");
    if (saved === "light" || saved === "dark") return saved;
    return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
  }

  function App() {
    const [session, setSession] = useState(null);
    const [authLoading, setAuthLoading] = useState(true);
    const authed = !!session;
    const [active, setActive] = useState("dashboard");
    const [pac, setPac] = useState({ mode: "list", id: null }); // pacientes sub-view
    const [aten, setAten] = useState({ mode: "list" }); // atendimentos sub-view
    const [reportAudience, setReportAudience] = useState("pais");
    const [theme, setTheme] = useState(getInitialTheme);
    const [banner, setBanner] = useState(true);
    const [installEvt, setInstallEvt] = useState(null);
    const [activeProf, setActiveProf] = useState("all");
    const [dbEstado, setDbEstado] = useState("aguardando"); // aguardando | carregando | pronto | erro
    const [dbErro, setDbErro] = useState("");
    const [, setDbTick] = useState(0); // força re-render depois de hidratar
    const [avisoGravacao, setAvisoGravacao] = useState("");
    const [teamOpen, setTeamOpen] = useState(false);
    const [scheduler, setScheduler] = useState(null); // { date } | null
    const [rail, setRail] = useState(null); // override do painel direito (ex.: legenda do Hayling)
    const [agendaFocus, setAgendaFocus] = useState(null); // iso para focar a agenda
    const [focusTick, setFocusTick] = useState(0); // força re-foco mesmo na mesma data
    /* Ciclo com que a vitrine abre. Quem chega de um "quero pagar por
       ano" não deveria ter que achar o toggle de novo. */
    const [planosCiclo, setPlanosCiclo] = useState("mensal");

    useEffect(() => {
      document.documentElement.setAttribute("data-theme", theme);
      const meta = document.querySelector('meta[name="theme-color"]:not([media])') || (() => {
        const m = document.createElement("meta"); m.name = "theme-color"; document.head.appendChild(m); return m;
      })();
      meta.setAttribute("content", theme === "dark" ? "#0F1A19" : "#0F766E");
    }, [theme]);

    useEffect(() => {
      const onBip = (e) => { e.preventDefault(); setInstallEvt(e); };
      const onInstalled = () => setInstallEvt(null);
      window.addEventListener("beforeinstallprompt", onBip);
      window.addEventListener("appinstalled", onInstalled);
      return () => { window.removeEventListener("beforeinstallprompt", onBip); window.removeEventListener("appinstalled", onInstalled); };
    }, []);

    function doInstall() {
      if (!installEvt) return;
      installEvt.prompt();
      installEvt.userChoice.finally(() => setInstallEvt(null));
    }

    // Sessão do Supabase Auth = fonte de verdade da autenticação
    useEffect(() => {
      const sb = window.sb;
      if (!sb) { setAuthLoading(false); return; }
      sb.auth.getSession().then(({ data }) => {
        applyUser(data.session);
        setSession(data.session || null);
        setAuthLoading(false);
      });
      const { data: sub } = sb.auth.onAuthStateChange((_evt, sess) => { applyUser(sess); setSession(sess || null); });
      return () => { sub && sub.subscription && sub.subscription.unsubscribe(); };
    }, []);

    /* Carga do banco: só depois de autenticado, porque o RLS filtra por
       auth.uid(). Antes disso o app renderizaria vazio e pareceria que
       os dados sumiram. */
    async function carregarBanco() {
      setDbEstado("carregando");
      setDbErro("");
      try {
        const dados = await window.EducareDB.carregar();
        window.hidratarDados(dados);
        if (window.Billing && window.Billing.recarregar) window.Billing.recarregar();
        /* Assinatura. Uma falha aqui não derruba o app: a barreira de
           escrita é a RLS, não esta leitura. */
        if (window.EducareBilling) {
          try { await window.EducareBilling.carregar(); }
          catch (e) { console.error("[Educare] assinatura não carregou:", e); }
        }
        setDbEstado("pronto");
        setDbTick((t) => t + 1);
      } catch (e) {
        console.error("[Educare] carga do banco falhou:", e);
        setDbErro((e && e.message) || "Falha ao carregar seus dados.");
        setDbEstado("erro");
      }
    }

    useEffect(() => {
      if (!authed) { setDbEstado("aguardando"); return; }
      if (dbEstado === "aguardando") carregarBanco();
    }, [authed]);

    /* Falha de gravação precisa ser visível: um atendimento que não chegou
       ao servidor não pode passar despercebido. */
    useEffect(() => {
      const onErro = (e) => setAvisoGravacao(e.detail || "Falha ao salvar.");
      window.addEventListener("educare-db-erro", onErro);
      return () => window.removeEventListener("educare-db-erro", onErro);
    }, []);

    function setThemeManual(t) {
      setTheme(t);
      localStorage.setItem("educare-theme", t);
    }

    function navigate(id, opts) {
      if (id === "__logout") { window.sb && window.sb.auth.signOut(); setActive("dashboard"); return; }
      if (id === "pacientes") setPac({ mode: (opts && opts.mode) || "list", id: (opts && opts.id) || null });
      if (id === "atendimentos") setAten({ mode: (opts && opts.mode) || "list" });
      if (id === "planos") setPlanosCiclo(opts && opts.ciclo === "anual" ? "anual" : "mensal");
      setActive(id);
      document.querySelector(".main-scroll") && (document.querySelector(".main-scroll").scrollTop = 0);
    }

    function openPatient(id) { setPac({ mode: "detail", id }); setActive("pacientes"); }

    function openScheduler(dateIso) { setScheduler({ date: dateIso || (window.todayISO ? window.todayISO() : "2026-06-04") }); }
    function focusAgenda(iso) { setAgendaFocus(iso); setFocusTick((t) => t + 1); navigate("agenda"); }

    if (authLoading) {
      return (
        <div style={{ minHeight: "100vh", display: "flex", alignItems: "center", justifyContent: "center", background: "var(--surface-1, #0F1A19)", color: "var(--text-2, #94A3B8)", fontWeight: 700 }}>
          Carregando…
        </div>
      );
    }
    if (!authed) {
      return <LoginScreen onLogin={() => { /* onAuthStateChange atualiza a sessão */ }} />;
    }
    if (dbEstado === "aguardando" || dbEstado === "carregando") {
      return (
        <div style={{ minHeight: "100vh", display: "flex", alignItems: "center", justifyContent: "center", background: "var(--surface-1, #0F1A19)", color: "var(--text-2, #94A3B8)", fontWeight: 700 }}>
          Carregando seus dados…
        </div>
      );
    }
    if (dbEstado === "erro") {
      return (
        <div style={{ minHeight: "100vh", display: "flex", flexDirection: "column", gap: 14, alignItems: "center", justifyContent: "center", background: "var(--surface-1, #0F1A19)", color: "var(--text-2, #94A3B8)", padding: 24, textAlign: "center" }}>
          <b style={{ fontSize: 17, color: "var(--text, #fff)" }}>Não foi possível carregar seus dados</b>
          <span style={{ maxWidth: 420, fontSize: 14 }}>{dbErro}</span>
          <button className="btn btn-primary btn-sm" onClick={carregarBanco}>Tentar novamente</button>
        </div>
      );
    }

    const { PacientesList, PacienteForm, Prontuario, Agenda, AtendimentosList, AtendimentoForm, Planejamentos, Avaliacoes, Biblioteca, Flashcards, Financeiro, WhatsApp, Relatorio } = window;
    let content;
    if (active === "dashboard") {
      const emailConfirmed = !!(session && session.user && session.user.email_confirmed_at);
      content = <Dashboard onNavigate={navigate} showBanner={banner && !emailConfirmed} onDismissBanner={() => setBanner(false)} />;
    } else if (active === "pacientes") {
      if (pac.mode === "new") {
        content = <PacienteForm onCancel={() => setPac({ mode: "list" })} onSave={(data) => { const np = window.addPatient(data, activeProf); setPac({ mode: "detail", id: np.id }); }} />;
      } else if (pac.mode === "detail") {
        content = <Prontuario patientId={pac.id} onBack={() => setPac({ mode: "list" })} onPlan={() => navigate("planejamentos")} onReport={(id) => setPac({ mode: "report", id })} />;
      } else if (pac.mode === "report") {
        content = <Relatorio patientId={pac.id} audience={reportAudience} onAudience={setReportAudience} onBack={() => setPac({ mode: "detail", id: pac.id })} />;
      } else {
        content = <PacientesList onNew={() => setPac({ mode: "new" })} onOpen={(id) => setPac({ mode: "detail", id })} onNavigate={navigate} activeProf={activeProf} onManageTeam={() => setTeamOpen(true)} />;
      }
    } else if (active === "agenda") {
      content = <Agenda onOpen={openPatient} onSchedule={openScheduler} focusDate={agendaFocus} focusKey={focusTick} />;
    } else if (active === "planejamentos") {
      content = <Planejamentos onOpenPatient={openPatient} />;
    } else if (active === "avaliacoes") {
      content = <Avaliacoes onOpenPatient={openPatient} onRail={setRail} onNavigate={navigate} />;
    } else if (active === "biblioteca") {
      content = <Biblioteca />;
    } else if (active === "flashcards") {
      content = <Flashcards />;
    } else if (active === "financeiro") {
      content = <Financeiro />;
    } else if (active === "whatsapp") {
      content = <WhatsApp />;
    } else if (active === "planos") {
      content = <window.TelaPlanos ciclo={planosCiclo} onBack={() => navigate("dashboard")} />;
    } else if (active === "configuracoes") {
      content = <window.Configuracoes onNavigate={navigate} />;
    } else if (active === "admin") {
      content = <window.AdminPlanos onBack={() => navigate("dashboard")} />;
    } else if (active === "pagamentos") {
      content = <window.AtendPagamentos onNavigate={navigate} />;
    } else if (active === "atendimentos") {
      if (aten.mode === "new") {
        content = <AtendimentoForm onCancel={() => setAten({ mode: "list" })} onSave={(data) => { window.addAtendimento(data); setAten({ mode: "list" }); }} />;
      } else {
        content = <AtendimentosList onNew={() => setAten({ mode: "new" })} onOpen={openPatient} onNavigate={navigate} />;
      }
    } else {
      const m = META[active] || { title: "Em breve", icon: "sparkles" };
      content = <Placeholder title={m.title} icon={m.icon} crumb={m.title} />;
    }

    return (
      <AppShell active={active} onNavigate={navigate} theme={theme} onToggleTheme={setThemeManual} canInstall={!!installEvt} onInstall={doInstall} activeProf={activeProf} onSelectProf={setActiveProf} onManageTeam={() => setTeamOpen(true)} onSchedule={openScheduler} onPickDay={focusAgenda} rail={rail}>
        {avisoGravacao && (
          <div role="alert" style={{ position: "fixed", left: 16, right: 16, bottom: 16, zIndex: 60, maxWidth: 520, margin: "0 auto", background: "#FEE2E2", color: "#991B1B", border: "1px solid #FCA5A5", borderRadius: 12, padding: "12px 14px", display: "flex", alignItems: "center", gap: 10, boxShadow: "var(--shadow)" }}>
            <b style={{ flex: 1, fontSize: 13.5, fontWeight: 700 }}>Não salvo no servidor: {avisoGravacao}</b>
            <button className="btn btn-ghost btn-xs" onClick={carregarBanco}>Recarregar</button>
            <button className="btn btn-ghost btn-xs" onClick={() => setAvisoGravacao("")}>Fechar</button>
          </div>
        )}
        {content}
        {teamOpen && <window.TeamModal onClose={() => setTeamOpen(false)} />}
        {scheduler && <window.AgendarModal defaultDate={scheduler.date} onClose={() => setScheduler(null)} onSaved={(savedIso) => { setScheduler(null); focusAgenda(savedIso); }} />}
      </AppShell>
    );
  }

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