/* =========================================================
   Funnel Labs IA — App Root
   State · validation · persistence · submit · navigation · tweaks
   ========================================================= */
/* All components are already global (declared in their respective files):
   Header, Hero, ProgressBar, ThankYou (components.jsx)
   Step1..Step4, OPTIONS, PLANS (steps.jsx)
   TweaksPanel, useTweaks, TweakSection, TweakRadio, TweakToggle (tweaks-panel.jsx)
   React.Fragment is also global. */

const STORAGE_KEY = "funnel-labs-application-draft";
const PAGE_LOAD_TS = Date.now();
const ANTI_SPAM_MIN_MS = 4000;

const STEP_LABELS = ["Identificação", "Qualificação", "Comprometimento", "Investimento"];
const TOTAL_STEPS = 4;

const EMPTY_DATA = {
  // step 1
  nome: "", email: "", whatsapp: "",
  // step 2
  nivelIA: "", area: "", faturamento: "", tempo: "", ias: [],
  // step 3
  projeto: "", renovar: "",
  // step 4
  plano: "", atribuicao: "", indicacao: "", caixa: "",
  // honeypot
  company_url: "",
};

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "default",
  "progressStyle": "bar",
  "density": "default",
  "showHeroQuote": true
}/*EDITMODE-END*/;

/* ============================================================
   Validation
   ============================================================ */
function validateStep(step, data) {
  const e = {};
  const phoneDigits = (data.whatsapp || "").replace(/\D/g, "");

  if (step >= 1) {
    if (!data.nome || data.nome.trim().length < 3) e.nome = "Informe seu nome completo.";
    if (!data.email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data.email)) e.email = "E-mail inválido.";
    if (!data.whatsapp || phoneDigits.length < 10) e.whatsapp = "WhatsApp com DDD, mínimo 10 dígitos.";
  }
  if (step >= 2) {
    if (!data.nivelIA) e.nivelIA = "Selecione um nível.";
    if (!data.area) e.area = "Selecione uma área.";
    if (!data.faturamento) e.faturamento = "Selecione um faturamento.";
    if (!data.tempo) e.tempo = "Selecione um tempo.";
  }
  if (step >= 3) {
    if (!data.projeto || data.projeto.trim().length < 60) e.projeto = "Mínimo 60 caracteres — seja específico.";
    if (!data.renovar || data.renovar.trim().length < 60) e.renovar = "Mínimo 60 caracteres — defina o que é sucesso pra você.";
  }
  if (step >= 4) {
    if (!data.plano) e.plano = "Selecione um plano (ou peça pra conversar).";
    if (!data.atribuicao) e.atribuicao = "Selecione como chegou.";
    if (data.atribuicao === "indicacao" && !data.indicacao) e.indicacao = "Informe quem indicou.";
    if (!data.caixa) e.caixa = "Selecione uma opção.";
  }
  return e;
}

function stepIsComplete(step, data) {
  const e = validateStep(step, data);
  // only consider this step's keys
  const keys = {
    1: ["nome","email","whatsapp"],
    2: ["nivelIA","area","faturamento","tempo"],
    3: ["projeto","renovar"],
    4: ["plano","atribuicao","indicacao","caixa"],
  }[step];
  return keys.every(k => !e[k]);
}

/* ============================================================
   Persistence
   ============================================================ */
function loadDraft() {
  try {
    const raw = localStorage.getItem(STORAGE_KEY);
    if (!raw) return null;
    const parsed = JSON.parse(raw);
    return parsed && typeof parsed === "object" ? parsed : null;
  } catch (e) { return null; }
}
function saveDraft(data) {
  try {
    localStorage.setItem(STORAGE_KEY, JSON.stringify({ ...data, _ts: Date.now() }));
  } catch (e) {}
}
function clearDraft() {
  try { localStorage.removeItem(STORAGE_KEY); } catch (e) {}
}

/* ============================================================
   Submit (stub — TODO: plug Full Funnel / GoHighLevel webhook)
   ============================================================ */
async function submitApplication(payload) {
  // TODO ── substituir por POST real para webhook Full Funnel (whitelabel GHL)
  // Exemplo (descomentar e configurar):
  //
  // const res = await fetch("https://services.leadconnectorhq.com/hooks/SEU_ID/webhook-trigger/HASH", {
  //   method: "POST",
  //   headers: { "Content-Type": "application/json" },
  //   body: JSON.stringify(payload),
  // });
  // if (!res.ok) throw new Error("Falha no envio. Tente novamente.");
  // return await res.json();

  // Simulação:
  await new Promise(r => setTimeout(r, 1800));

  // Disparar pixels (slots configurados no index.html)
  try {
    if (window.fbq) window.fbq("trackCustom", "application_submitted", {
      plan: payload.plano,
      faturamento: payload.faturamento,
    });
    if (window.gtag) window.gtag("event", "application_submitted", {
      plan: payload.plano,
    });
  } catch (e) {}

  return { ok: true, protocol: payload.protocolo };
}

function generateProtocol() {
  const ts = Date.now().toString(36).toUpperCase();
  const rand = Math.random().toString(36).slice(2, 6).toUpperCase();
  return `FL-${ts.slice(-6)}-${rand}`;
}

/* ============================================================
   App Root
   ============================================================ */
function App() {
  const [data, setData] = React.useState(() => ({ ...EMPTY_DATA, ...(loadDraft() || {}) }));
  const [step, setStep] = React.useState(1);
  const [maxStepReached, setMaxStepReached] = React.useState(1);
  const [errors, setErrors] = React.useState({});
  const [ctxShown, setCtxShown] = React.useState([]);
  const [progressVisible, setProgressVisible] = React.useState(false);
  const [summaryOpen, setSummaryOpen] = React.useState(false);
  const [isSubmitting, setIsSubmitting] = React.useState(false);
  const [submitError, setSubmitError] = React.useState(null);
  const [submitted, setSubmitted] = React.useState(false);
  const [applicationCode, setApplicationCode] = React.useState("");
  const stepRefs = React.useRef({});
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);

  /* ---- Sticky progress visibility based on scroll ---- */
  React.useEffect(() => {
    const onScroll = () => {
      setProgressVisible(window.scrollY > 240);
    };
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);

  /* ---- Persist (debounced) ---- */
  React.useEffect(() => {
    const t = setTimeout(() => saveDraft(data), 500);
    return () => clearTimeout(t);
  }, [data]);

  /* ---- Analytics: step entered ---- */
  React.useEffect(() => {
    try {
      if (window.fbq) window.fbq("trackCustom", `application_step_${step}`);
      if (window.gtag) window.gtag("event", `application_step_${step}`);
    } catch (e) {}
  }, [step]);

  /* ---- Track max step ---- */
  React.useEffect(() => {
    setMaxStepReached((p) => Math.max(p, step));
  }, [step]);

  const set = React.useCallback((key, val) => {
    setData((d) => ({ ...d, [key]: val }));
    setErrors((e) => {
      if (!e[key]) return e;
      const cp = { ...e }; delete cp[key]; return cp;
    });
  }, []);

  const markCtxShown = React.useCallback((id) => {
    setCtxShown((list) => (list.includes(id) || list.length >= 2) ? list : [...list, id]);
  }, []);

  const goToStep = React.useCallback((n) => {
    setStep(n);
    // scroll to the section top with a tiny lag for transition
    setTimeout(() => {
      const el = stepRefs.current[n];
      if (el) {
        const y = el.getBoundingClientRect().top + window.scrollY - 80;
        window.scrollTo({ top: y, behavior: "smooth" });
      }
    }, 60);
  }, []);

  const onNext = React.useCallback(() => {
    const e = validateStep(step, data);
    const keys = {
      1: ["nome","email","whatsapp"],
      2: ["nivelIA","area","faturamento","tempo"],
      3: ["projeto","renovar"],
    }[step];
    const stepErrors = {};
    keys.forEach(k => { if (e[k]) stepErrors[k] = e[k]; });

    if (Object.keys(stepErrors).length > 0) {
      setErrors((curr) => ({ ...curr, ...stepErrors }));
      // shake first invalid field
      const firstInvalid = keys.find(k => stepErrors[k]);
      if (firstInvalid) {
        const el = document.getElementById(firstInvalid);
        if (el) el.focus();
      }
      return;
    }

    setErrors({});
    if (step < TOTAL_STEPS) goToStep(step + 1);
  }, [step, data, goToStep]);

  const onBack = React.useCallback(() => {
    if (step > 1) goToStep(step - 1);
  }, [step, goToStep]);

  /* ---- Keyboard: Enter advances (not on textarea, not on last step submit) ---- */
  React.useEffect(() => {
    const onKey = (e) => {
      if (e.key !== "Enter") return;
      if (e.target.tagName === "TEXTAREA") return;
      if (e.target.tagName === "BUTTON") return;
      if (step < TOTAL_STEPS) {
        e.preventDefault();
        onNext();
      }
    };
    document.addEventListener("keydown", onKey);
    return () => document.removeEventListener("keydown", onKey);
  }, [step, onNext]);

  /* ---- Submit ---- */
  const onSubmit = React.useCallback(async () => {
    setSubmitError(null);

    // full validation
    const e = validateStep(4, data);
    if (Object.keys(e).length > 0) {
      setErrors(e);
      // jump to first step with error
      const stepOf = (k) => {
        if (["nome","email","whatsapp"].includes(k)) return 1;
        if (["nivelIA","area","faturamento","tempo"].includes(k)) return 2;
        if (["projeto","renovar"].includes(k)) return 3;
        return 4;
      };
      const firstKey = Object.keys(e)[0];
      const targetStep = stepOf(firstKey);
      if (targetStep !== step) goToStep(targetStep);
      return;
    }

    // anti-spam: honeypot
    if (data.company_url) {
      setSubmitError("Algo deu errado. Atualize a página e tente novamente.");
      return;
    }
    // anti-spam: time gate
    if (Date.now() - PAGE_LOAD_TS < ANTI_SPAM_MIN_MS) {
      setSubmitError("Aplicação enviada rápido demais. Aguarde alguns segundos.");
      return;
    }

    const protocol = generateProtocol();
    setApplicationCode(protocol);
    setIsSubmitting(true);

    try {
      const { company_url, ...payload } = data;
      await submitApplication({
        ...payload,
        protocolo: protocol,
        enviado_em: new Date().toISOString(),
        origem: typeof window !== "undefined" ? document.referrer || "direct" : "direct",
        user_agent: typeof navigator !== "undefined" ? navigator.userAgent : "",
      });
      clearDraft();
      setSubmitted(true);
      window.scrollTo({ top: 0, behavior: "smooth" });
    } catch (err) {
      setSubmitError(err.message || "Falha no envio. Tente novamente.");
    } finally {
      setIsSubmitting(false);
    }
  }, [data, step, goToStep]);

  /* ---- Theme + density classes on body ---- */
  React.useEffect(() => {
    const cls = document.body.classList;
    cls.remove("theme--mono", "theme--default", "density--compact", "density--default");
    if (t.theme === "mono") cls.add("theme--mono");
    if (t.density === "compact") cls.add("density--compact");
  }, [t.theme, t.density]);

  /* ============================================================
     Render
     ============================================================ */
  if (submitted) {
    return (
      <div>
        <Header />
        <main className="shell">
          <ThankYou applicationCode={applicationCode} plan={data.plano} name={data.nome} />
        </main>
        <footer className="footer">
          <span>COPY S/A · Funnel Labs IA · 2026</span>
          <span>Protocolo {applicationCode}</span>
        </footer>
        <Tweaks t={t} setTweak={setTweak} />
      </div>
    );
  }

  return (
    <div>
      <Header />

      <ProgressBar
        visible={progressVisible}
        step={step}
        totalSteps={TOTAL_STEPS}
        stepLabels={STEP_LABELS}
        onJump={(n) => goToStep(n)}
        allowJump={true}
        style={t.progressStyle}
      />

      <main className="shell">
        <Hero />

        {/* Render only the active step (calm mental model + cleaner DOM) */}
        <div
          key={step}
          className="step-enter"
          ref={(el) => { if (el) stepRefs.current[step] = el; }}
        >
          {step === 1 && (
            <Step1 data={data} set={set} errors={errors} />
          )}
          {step === 2 && (
            <Step2
              data={data}
              set={set}
              errors={errors}
              ctxShown={ctxShown}
              markCtxShown={markCtxShown}
            />
          )}
          {step === 3 && (
            <Step3 data={data} set={set} errors={errors} />
          )}
          {step === 4 && (
            <Step4
              data={data}
              set={set}
              errors={errors}
              allData={data}
              isSubmitting={isSubmitting}
              submitError={submitError}
              onSubmit={onSubmit}
              onToggleSummary={() => setSummaryOpen(o => !o)}
              summaryOpen={summaryOpen}
            />
          )}

          <div className="stepnav">
            <button
              type="button"
              className={"btn-back " + (step === 1 ? "is-hidden" : "")}
              onClick={onBack}
              disabled={step === 1}
            >
              <span className="arrow">←</span>
              <span>Passo anterior</span>
            </button>
            {step < TOTAL_STEPS && (
              <button
                type="button"
                className="btn-next"
                onClick={onNext}
              >
                <span>{step === 1 ? "Continuar para qualificação"
                  : step === 2 ? "Continuar para comprometimento"
                  : "Continuar para envio"}</span>
                <span className="arrow">→</span>
              </button>
            )}
          </div>
        </div>
      </main>

      <footer className="footer">
        <span>COPY S/A · Funnel Labs IA · 2026</span>
        <span>Aplicação confidencial · LGPD respeitada</span>
      </footer>

      <Tweaks t={t} setTweak={setTweak} />
    </div>
  );
}

/* ============================================================
   Tweaks panel
   ============================================================ */
function Tweaks({ t, setTweak }) {
  return (
    <TweaksPanel title="Tweaks · Aplicação">
      <TweakSection title="Identidade visual">
        <TweakRadio
          label="Acento"
          value={t.theme}
          onChange={(v) => setTweak("theme", v)}
          options={[
            { value: "default", label: "Ignition" },
            { value: "mono", label: "Mono" },
          ]}
        />
      </TweakSection>

      <TweakSection title="Progresso">
        <TweakRadio
          label="Estilo da barra"
          value={t.progressStyle}
          onChange={(v) => setTweak("progressStyle", v)}
          options={[
            { value: "bar", label: "Linha" },
            { value: "dots", label: "Numerada" },
          ]}
        />
      </TweakSection>

      <TweakSection title="Densidade">
        <TweakRadio
          label="Espaçamento"
          value={t.density}
          onChange={(v) => setTweak("density", v)}
          options={[
            { value: "default", label: "Padrão" },
            { value: "compact", label: "Compacto" },
          ]}
        />
      </TweakSection>

      <TweakSection title="Demo / Reset">
        <div style={{display:"flex", flexDirection:"column", gap: 8}}>
          <button
            type="button"
            onClick={() => { clearDraft(); window.location.reload(); }}
            style={{
              padding:"10px 12px",
              background:"rgba(255,90,0,0.10)",
              border:"1px solid var(--accent-line)",
              color:"var(--accent)",
              fontFamily:"var(--mono)",
              fontSize:11,
              letterSpacing:".12em",
              textTransform:"uppercase",
              cursor:"pointer",
            }}
          >Limpar rascunho + recarregar</button>
          <button
            type="button"
            onClick={() => {
              const demo = {
                nome: "Marina Castilho",
                email: "marina@agenciacastilho.com.br",
                whatsapp: "(11) 98421-9087",
                nivelIA: "avancado",
                area: "agencia",
                faturamento: "1m-3m",
                tempo: "3-7",
                ias: ["claude", "gpt", "n8n"],
                projeto: "Quero ter uma esteira de aquisição de clientes B2B rodando para a agência: copy completa para uma sequência de outbound + landing page do diagnóstico gratuito + automação que qualifica e marca call. Meta: 12 reuniões qualificadas/mês até o final do ciclo, com ticket médio de R$ 6k.",
                renovar: "Bater meta de 12 reuniões qualificadas/mês de forma consistente, reduzir folha mensal em pelo menos 40% (hoje em R$ 32k) e ter ao menos dois funis perpétuos do meu próprio infoproduto rodando com I.A — isso pra mim define que valeu a pena renovar pra mais 12 meses.",
                plano: "parceiro",
                atribuicao: "ig-andre",
                indicacao: "",
                caixa: "agora",
                company_url: "",
              };
              localStorage.setItem(STORAGE_KEY, JSON.stringify(demo));
              window.location.reload();
            }}
            style={{
              padding:"10px 12px",
              background:"rgba(255,255,255,0.04)",
              border:"1px solid rgba(255,255,255,0.10)",
              color:"var(--ink-2)",
              fontFamily:"var(--mono)",
              fontSize:11,
              letterSpacing:".12em",
              textTransform:"uppercase",
              cursor:"pointer",
            }}
          >Preencher com dados demo</button>
        </div>
      </TweakSection>
    </TweaksPanel>
  );
}

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