// Challenge Lamoniê — root app
const { useState: useAppState, useEffect: useAppEffect } = React;

// Presets por etapa — em produção, cada Edition no banco guarda o próprio
// objeto `theme` (ver API.md §1). O admin escolhe um preset e/ou ajusta as
// cores manualmente; o front consome via GET /api/content.
// Presets por etapa — em produção, cada Edition no banco guarda o próprio
// objeto `theme` (ver API.md §1). O admin escolhe um preset e/ou ajusta as
// cores manualmente; o front consome via GET /api/content.
const EDITION_PRESETS = {
  tokyo:     { theme: "energetic", accentRed: "#e6132a", accentRedGlow: "#ff2940" },
  marrakech: { theme: "energetic", accentRed: "#c8501a", accentRedGlow: "#f0a020" },
  lisboa:    { theme: "minimal",   accentRed: "#1c4e80", accentRedGlow: "#f0c419" },
  rio:       { theme: "energetic", accentRed: "#00a86b", accentRedGlow: "#ffd400" },
  newyork:   { theme: "minimal",   accentRed: "#b8121f", accentRedGlow: "#3a3a3a" }
};

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "energetic",
  "accentRed": "#e6132a",
  "accentRedGlow": "#ff2940",
  "heroSubtitle": "Etapa Tóquio. Você escolhe a distância, registra sua corrida e a gente envia a medalha direto na sua casa. Bora?",
  "primaryCta": "Quero minha medalha",
  "medalSrc": "assets/medal-tokyo.webp",
  "price5":   59.90,
  "price10":  69.90,
  "price15":  79.90,
  "price21":  89.90,
  "price42":  99.90,
  "price100": 89.90,
  "price200": 99.90,
  "price300": 109.90,
  "price500": 129.90
}/*EDITMODE-END*/;

function buildContent(t) {
  const base = window.CHALLENGE_DEFAULTS;
  return {
    ...base,
    heroSubtitle: t.heroSubtitle,
    primaryCta: t.primaryCta,
    modalities: {
      corrida: {
        ...base.modalities.corrida,
        tiers: base.modalities.corrida.tiers.map(x => ({...x, price: t[`price${x.km}`] ?? x.price}))
      },
      ciclismo: {
        ...base.modalities.ciclismo,
        tiers: base.modalities.ciclismo.tiers.map(x => ({...x, price: t[`price${x.km}`] ?? x.price}))
      }
    }
  };
}

function App() {
  // Tweaks são uma camada de PREVIEW LOCAL (não persistem no banco). Quando
  // vazios/iguais ao default, deixamos o Supabase vencer; quando o usuário
  // mexe no painel, a sobreposição passa por cima até ele resetar.
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [view, setView] = useAppState(() => location.hash === "#checkout" ? "checkout" : "landing");
  const [remote, setRemote] = useAppState(null); // conteúdo vindo do Supabase
  const [source, setSource] = useAppState("loading"); // loading | supabase | mock
  const [mockReason, setMockReason] = useAppState(""); // por que caiu pro mock

  // Carrega Supabase ao montar. NÃO empurra valores pro tweaks (isso
  // persistiria no arquivo via __edit_mode_set_keys e congelaria a fonte).
  // O tema do banco vai direto pra CSS — tweaks só sobrescrevem se mudados.
  useAppEffect(() => {
    if (!window.SB?.ready) {
      setSource("mock");
      setMockReason("cliente Supabase não inicializou — checa config.js");
      return;
    }
    (async () => {
      try {
        // Diagnóstico em paralelo: query crua na tabela pra detectar RLS / dados.
        const probe = await window.SB.client.from("editions").select("slug,is_active").limit(5);
        const c = await window.SB.fetchLandingContent();
        if (c) { setRemote(c); setSource("supabase"); return; }
        // Sem conteúdo: descobre o porquê.
        setSource("mock");
        if (probe.error) {
          setMockReason("RLS bloqueando 'editions': " + probe.error.message);
        } else if (!probe.data || probe.data.length === 0) {
          setMockReason("tabela 'editions' vazia — rode supabase/seed.sql");
        } else if (!probe.data.some(r => r.is_active)) {
          setMockReason("nenhuma edition com is_active=true. Rode: update editions set is_active=true where slug='" + (window.APP_CONFIG?.EDITION_SLUG || "tokyo-2026-05") + "';");
        } else {
          setMockReason("edition_content/edition_pricing pode estar vazia. Rode supabase/seed.sql.");
        }
      } catch (err) {
        console.warn("[supabase] fetch falhou:", err);
        setSource("mock");
        setMockReason(String(err?.message || err));
      }
    })();
  }, []);

  // Detecta quais tweaks foram realmente alterados pelo usuário (vs defaults).
  // Só esses sobrescrevem o Supabase.
  const isTweaked = (key) => t[key] !== TWEAK_DEFAULTS[key];

  // Resolve theme: tweak (se mexido) > supabase > default.
  const themeMode = isTweaked("theme") ? t.theme
                  : (remote?.theme?.mode === "minimal" ? "minimal" : remote?.theme?.mode === "energetic" ? "energetic" : t.theme);
  const themeRed  = isTweaked("accentRed")     ? t.accentRed     : (remote?.theme?.accentPrimary || t.accentRed);
  const themeGlow = isTweaked("accentRedGlow") ? t.accentRedGlow : (remote?.theme?.accentGlow    || t.accentRedGlow);
  const medalSrc  = isTweaked("medalSrc")      ? t.medalSrc      : (remote?.medalSrc             || t.medalSrc);

  useAppEffect(() => {
    document.body.setAttribute("data-theme", themeMode === "minimal" ? "minimal" : "energetic");
    document.documentElement.style.setProperty("--red", themeRed);
    document.documentElement.style.setProperty("--red-glow", themeGlow);
  }, [themeMode, themeRed, themeGlow]);

  useAppEffect(() => {
    const onHash = () => setView(location.hash === "#checkout" ? "checkout" : "landing");
    window.addEventListener("hashchange", onHash);
    return () => window.removeEventListener("hashchange", onHash);
  }, []);

  // Conteúdo final: Supabase > tweak > default, exceto onde o usuário mexeu.
  const baseContent = remote || window.CHALLENGE_DEFAULTS;
  const content = {
    ...baseContent,
    heroSubtitle: isTweaked("heroSubtitle") ? t.heroSubtitle : baseContent.heroSubtitle,
    primaryCta:   isTweaked("primaryCta")   ? t.primaryCta   : baseContent.primaryCta,
    modalities: {
      corrida: {
        ...baseContent.modalities.corrida,
        tiers: baseContent.modalities.corrida.tiers.map(x => ({ ...x, price: isTweaked(`price${x.km}`) ? t[`price${x.km}`] : x.price })),
      },
      ciclismo: {
        ...baseContent.modalities.ciclismo,
        tiers: baseContent.modalities.ciclismo.tiers.map(x => ({ ...x, price: isTweaked(`price${x.km}`) ? t[`price${x.km}`] : x.price })),
      },
    },
  };
  const goCheckout = (modality, km) => {
    if (modality && km) sessionStorage.setItem("pick", JSON.stringify({modality, km}));
    location.hash = "checkout";
  };
  const closeCheckout = () => { location.hash = ""; };

  if (view === "checkout") {
    return (
      <>
        <Checkout content={content} medalSrc={medalSrc} onClose={closeCheckout}/>
        <TweaksUI t={t} setTweak={setTweak}/>
        <DataSourceBadge source={source} edition={remote?.edition} theme={{ mode: themeMode, red: themeRed, glow: themeGlow }}/>
      </>
    );
  }

  return (
    <div data-screen-label="01 Landing">
      <TopBar brand={content.brand} edition={content.edition} onCta={() => goCheckout()}/>
      <Hero content={content} medalSrc={medalSrc} onCta={() => goCheckout()}/>
      <HowItWorks steps={content.steps}/>
      <Distances modalities={content.modalities} onPick={goCheckout}/>
      <MedalShowcase medal={content.medal} medalSrc={medalSrc}/>
      <Testimonials items={content.testimonials}/>
      <Schedule items={content.schedule}/>
      <Rules items={content.rules}/>
      <CtaBand onCta={() => goCheckout()}/>
      <Footer brand={content.brand}/>
      <TweaksUI t={t} setTweak={setTweak}/>
      <DataSourceBadge source={source} edition={remote?.edition} theme={{ mode: themeMode, red: themeRed, glow: themeGlow }}/>
    </div>
  );
}

// Pequeno badge no canto que mostra de onde vem o conteúdo (supabase vs mock)
// e os valores de tema sendo aplicados. Some em produção (controlado por
// ?debug=1 ou localStorage).
function DataSourceBadge({ source, reason, edition, theme }) {
  const [open, setOpen] = useAppState(false);
  const visible = typeof location !== "undefined" && (
    location.search.includes("debug") ||
    localStorage.getItem("lamonie.debug") === "1" ||
    source !== "supabase"
  );
  if (!visible) return null;
  const color = source === "supabase" ? "#2ec27e" : source === "loading" ? "#f0c419" : "#ff6a3d";
  const labels = { supabase: "Supabase", loading: "Carregando…", mock: "Modo demo (mock)" };
  return (
    <div style={{
      position: "fixed", bottom: 18, left: 18, zIndex: 1000,
      background: "rgba(10,8,7,0.92)",
      border: `1px solid ${color}`,
      borderRadius: 8,
      padding: open ? "12px 14px" : "8px 12px",
      fontFamily: "var(--font-mono, ui-monospace)",
      fontSize: 11, letterSpacing: "0.12em", textTransform: "uppercase",
      color: "#f5efe6",
      maxWidth: open ? 320 : "auto",
      cursor: "pointer",
      boxShadow: "0 8px 24px -8px rgba(0,0,0,0.6)"
    }} onClick={() => setOpen(!open)}>
      <div style={{display: "flex", alignItems: "center", gap: 8}}>
        <span style={{width: 8, height: 8, borderRadius: "50%", background: color, boxShadow: `0 0 8px ${color}`}}/>
        <span>{labels[source]}</span>
        <span style={{opacity: 0.4, marginLeft: "auto"}}>{open ? "×" : "i"}</span>
      </div>
      {open && (
        <div style={{marginTop: 10, paddingTop: 10, borderTop: "1px solid rgba(245,239,230,0.12)", textTransform: "none", letterSpacing: 0, lineHeight: 1.6, opacity: 0.9, fontSize: 11}}>
          {source === "mock" && reason && (
            <div style={{padding: "8px 10px", marginBottom: 10, background: "rgba(255,106,61,0.12)", borderRadius: 4, color: "#ffb088"}}>
              <b>Motivo:</b> {reason}
            </div>
          )}
          <div><b>Etapa:</b> {edition || "—"}</div>
          <div><b>Tema:</b> {theme.mode}</div>
          <div style={{display: "flex", alignItems: "center", gap: 6}}><b>Cor 1:</b> <span style={{width: 12, height: 12, background: theme.red, display:"inline-block", borderRadius: 2}}/> {theme.red}</div>
          <div style={{display: "flex", alignItems: "center", gap: 6}}><b>Cor 2:</b> <span style={{width: 12, height: 12, background: theme.glow, display:"inline-block", borderRadius: 2}}/> {theme.glow}</div>
          <div style={{marginTop: 8, opacity: 0.5, fontSize: 10}}>?debug=1 na URL pra sempre mostrar</div>
        </div>
      )}
    </div>
  );
}

function TweaksUI({ t, setTweak }) {
  const applyPreset = (key) => {
    const p = EDITION_PRESETS[key];
    if (p) setTweak({ ...p });
  };
  return (
    <TweaksPanel title="Tweaks · Challenge Lamoniê">
      <TweakSection label="Preset por etapa">
        <TweakSelect label="Etapa" value="—"
          options={["— escolher —", "Tóquio (preto + vermelho)", "Marrakech (terracota + ocre)", "Lisboa (azul + amarelo)", "Rio (verde + amarelo)", "New York (cream + bordô)"]}
          onChange={(v) => {
            const map = {
              "Tóquio (preto + vermelho)": "tokyo",
              "Marrakech (terracota + ocre)": "marrakech",
              "Lisboa (azul + amarelo)": "lisboa",
              "Rio (verde + amarelo)": "rio",
              "New York (cream + bordô)": "newyork"
            };
            if (map[v]) applyPreset(map[v]);
          }}/>
        <div style={{fontSize: 11, opacity: 0.65, lineHeight: 1.5, padding: "2px 4px"}}>
          Cada etapa tem sua paleta. No admin (PUT /api/content), você salva esse objeto <code>theme</code> por edição.
        </div>
      </TweakSection>
      <TweakSection label="Tema visual">
        <TweakRadio label="Estética" value={t.theme}
          options={["energetic", "minimal"]}
          onChange={(v) => setTweak("theme", v)}/>
        <TweakColor label="Cor principal" value={t.accentRed}
          options={["#e6132a", "#c8501a", "#1c4e80", "#00a86b", "#b8121f", "#7a1ea1"]}
          onChange={(v) => setTweak("accentRed", v)}/>
        <TweakColor label="Cor de brilho" value={t.accentRedGlow}
          options={["#ff2940", "#f0a020", "#f0c419", "#ffd400", "#3a3a3a", "#ff6a3d"]}
          onChange={(v) => setTweak("accentRedGlow", v)}/>
      </TweakSection>
      <TweakSection label="Copy da hero">
        <TweakText label="Subtítulo" value={t.heroSubtitle}
          onChange={(v) => setTweak("heroSubtitle", v)}/>
        <TweakText label="Texto do botão" value={t.primaryCta}
          onChange={(v) => setTweak("primaryCta", v)}/>
      </TweakSection>
      <TweakSection label="Preços · Corrida (R$)">
        <TweakNumber label="5 km"  value={t.price5}  min={0} max={500} step={0.10}
          onChange={(v) => setTweak("price5", v)}/>
        <TweakNumber label="10 km" value={t.price10} min={0} max={500} step={0.10}
          onChange={(v) => setTweak("price10", v)}/>
        <TweakNumber label="15 km" value={t.price15} min={0} max={500} step={0.10}
          onChange={(v) => setTweak("price15", v)}/>
        <TweakNumber label="21 km" value={t.price21} min={0} max={500} step={0.10}
          onChange={(v) => setTweak("price21", v)}/>
        <TweakNumber label="42 km" value={t.price42} min={0} max={500} step={0.10}
          onChange={(v) => setTweak("price42", v)}/>
      </TweakSection>
      <TweakSection label="Preços · Ciclismo (R$)">
        <TweakNumber label="100 km" value={t.price100} min={0} max={500} step={0.10}
          onChange={(v) => setTweak("price100", v)}/>
        <TweakNumber label="200 km" value={t.price200} min={0} max={500} step={0.10}
          onChange={(v) => setTweak("price200", v)}/>
        <TweakNumber label="300 km" value={t.price300} min={0} max={500} step={0.10}
          onChange={(v) => setTweak("price300", v)}/>
        <TweakNumber label="500 km" value={t.price500} min={0} max={500} step={0.10}
          onChange={(v) => setTweak("price500", v)}/>
      </TweakSection>
      <TweakSection label="Medalha">
        <TweakText label="Caminho da imagem" value={t.medalSrc}
          onChange={(v) => setTweak("medalSrc", v)}/>
      </TweakSection>
    </TweaksPanel>
  );
}

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