/* Globby Wizard — app shell: phased flow (Define → Target multi-page) + routing hub + destinations. */

const DEFAULT_DATA = {
  goals: [],
  mode: "web", website: "", _profileSite: null, aiResult: null, aiConfirmed: false, aiPicks: [], products: [], aiKeywords: [],
  productName: "", trade: "export", country: "TR",
  sectorId: null, subSlug: null,
  niches: [], nicheCustom: [], note: "", hsCodes: [],
  keywords: [], _kwKey: null,
  problems: [], problemNote: "", genChallenges: [], _chKey: null,
  personas: [], personaCustom: [], personasInit: false, _personaKey: null,
  titles: [], buyerInds: [], buyerIndCustom: [],
  buyerSize: [], volume: [], channel: [], markets: [],
  findMode: "company", filters: { locations: [] }, results: [], searched: false, selected: [],
  contact: null,
  planSent: false,
};

// Fields DERIVED from the analyzed site/product. On a confirmed SITE CHANGE these are
// wiped back to defaults so nothing from the previous site leaks through. Nulling the
// _kwKey/_chKey/_personaKey sentinels forces every downstream step to re-seed.
const SITE_DERIVED_DEFAULTS = {
  aiKeywords: [], products: [],
  niches: [], nicheCustom: [], note: "", hsCodes: [],
  problems: [], problemNote: "", genChallenges: [], _chKey: null,
  personas: [], personaCustom: [], personasInit: false, _personaKey: null,
  titles: [], buyerInds: [], buyerIndCustom: [],
  buyerSize: [], volume: [], channel: [], markets: [],
  keywords: [], _kwKey: null,
  findMode: "company", filters: { locations: [] },
  results: [], resultsTotal: null, searched: false, selected: [],
};

function loadState() {
  try { const raw = localStorage.getItem("globby_wizard_v2"); if (raw) return JSON.parse(raw); } catch (e) {}
  return null;
}

// compact summary of the user's wizard choices — attached to lead writes (keeps Supabase jsonb small)
function snapshotOf(d) {
  d = d || {};
  return { product: d.productName, trade: d.trade, sectorId: d.sectorId, subSlug: d.subSlug,
           goals: d.goals, markets: d.markets, titles: d.titles, website: d.website || null };
}

function App() {
  const saved = loadState();
  const [lang, setLang] = useState(saved ? saved.lang : window.detectLang());
  const [phase, setPhase] = useState(saved ? (saved.phase || 0) : 0); // 0 define, 1 target
  const [ppage, setPpage] = useState(saved ? (saved.ppage || 0) : 0); // sub-page within target phase
  const [route, setRoute] = useState(saved ? (saved.route || null) : null);
  // Backfill _profileSite for legacy localStorage blobs: if the user already confirmed a
  // profile under the old code, treat their current website as the profile's site so the
  // first post-upgrade confirm of the SAME site does not wipe their in-progress work.
  const [data, setData] = useState(function () {
    if (!saved) return DEFAULT_DATA;
    const d = Object.assign({}, DEFAULT_DATA, saved.data);
    if (d._profileSite == null && d.aiConfirmed && d.website) d._profileSite = d.website;
    return d;
  });
  const [toastMsg, setToastMsg] = useState(null);
  const [showContact, setShowContact] = useState(false);
  const L = window.I18N[lang];
  const PAGES = window.PROFILE_PAGES; // [sectorsub, words, hs, who, prefs, problems]

  useEffect(() => {
    try { localStorage.setItem("globby_wizard_v2", JSON.stringify({ lang, phase, ppage, route, data })); } catch (e) {}
  }, [lang, phase, ppage, route, data]);
  useEffect(() => { document.documentElement.lang = lang; }, [lang]);
  // publish the analysed website so every persisted analytics row / lead carries it
  useEffect(() => { window.setTrackSite && window.setTrackSite(data.website || null); }, [data.website]);

  // analytics: announce session start once (only for brand-new visitors) + publish current lang
  const startedRef = React.useRef(false);
  useEffect(() => {
    if (startedRef.current) return; startedRef.current = true;
    window.setTrackLang && window.setTrackLang(lang);
    if (!saved) window.track && window.track("wizard_start", { lang });
  }, []);

  // One persisted analytics row per page the user lands on. The visible page is the active
  // route (hub/market/find/email) or, in the wizard, the define step / current target page.
  // Granular interaction events still fire to GA4 but are no longer written to the database.
  const curPage = route || (phase === 0 ? "define" : (PAGES[ppage] || ("step-" + ppage)));
  const pageRef = React.useRef(null);
  useEffect(() => {
    if (pageRef.current === curPage) return;
    pageRef.current = curPage;
    window.track && window.track("page_view", { page: curPage, phase: phase, trade: data.trade, lang: lang });
  }, [curPage]);

  // Auto-detect the origin country for brand-new visitors only (no saved progress),
  // so we never override a returning user's manual selection. Server IP geo first
  // (where they're accessing from), with a browser-locale fallback for local dev.
  useEffect(() => {
    if (saved) return;
    let cancelled = false;
    (async () => {
      let cc = null;
      try {
        const r = await fetch("/api/geo");
        if (r.ok) { const j = await r.json(); cc = (j && j.country ? j.country : "").toUpperCase(); }
      } catch (e) {}
      if (!cc && window.detectCountry) cc = window.detectCountry();
      if (cancelled || !cc || !(window.COUNTRY_BY && window.COUNTRY_BY[cc])) return;
      setData(d => (d.country === cc ? d : Object.assign({}, d, { country: cc })));
    })();
    return () => { cancelled = true; };
  }, []);

  const set = (patch) => setData(d => Object.assign({}, d, patch));
  // Confirm a freshly-analyzed profile. `patch` carries the new product/sector/keyword
  // fields. If the analyzed website differs from the one that produced the CURRENT profile,
  // also wipe all site-derived state so the wizard re-seeds clean. `base` is applied before
  // `patch`, so fields the analysis sets (keywords/aiKeywords) win over the reset default.
  const confirmAnalysis = (patch) => setData(d => {
    const siteChanged = (d._profileSite || "") !== (d.website || "");
    const base = siteChanged ? Object.assign({}, SITE_DERIVED_DEFAULTS) : {};
    return Object.assign({}, d, base, patch, { _profileSite: d.website });
  });
  const toast = (msg) => { setToastMsg(msg); setTimeout(() => setToastMsg(null), 2600); };
  const switchLang = (l) => { window.track && window.track("language_changed", { from: lang, to: l }); window.setTrackLang && window.setTrackLang(l); setLang(l); try { localStorage.setItem("globby_lang", l); } catch (e) {} };
  const scrollTop = () => window.scrollTo({ top: 0, behavior: "smooth" });

  const dests = window.destsForGoals(data.goals);

  // per-page validation
  const pageOk = () => {
    if (phase === 0) return data.goals.length >= 1 && !!(data.productName && data.productName.trim());
    const which = PAGES[ppage];
    if (which === "sectorsub") return !!data.sectorId && !!data.subSlug;
    if (which === "words") return data.niches.length > 0 || (data.nicheCustom || []).length > 0;
    if (which === "who") return data.personas.length > 0 || (data.personaCustom || []).length > 0;
    return true; // hs, prefs, problems optional
  };

  const isLastProfilePage = () => ppage >= PAGES.length - 1;

  const goHub = () => {
    if (dests.length === 1) { window.track && window.track("destination_opened", { dest: dests[0], auto: true, lang }); setRoute(dests[0]); }
    else setRoute("hub");
    scrollTop();
  };

  const next = () => {
    if (phase === 0) {
      window.track && window.track("goal_selected", { goals: data.goals, trade: data.trade, lang });
      window.track && window.track("product_submitted", { product: data.productName, trade: data.trade, mode: data.mode, hasWebsite: !!data.website, lang });
      setPhase(1); setPpage(0); scrollTop(); toast(L.flow.savedToast + " · 1/" + PAGES.length); return;
    }
    // phase 1: record completion of the current target page (+ sector pick on the sectorsub page)
    const pg = PAGES[ppage];
    window.track && window.track("profile_step_completed", { page: pg, index: ppage, total: PAGES.length, lang });
    if (pg === "sectorsub") window.track && window.track("sector_selected", { sectorId: data.sectorId, subSlug: data.subSlug, lang });
    if (!isLastProfilePage()) { setPpage(ppage + 1); scrollTop(); toast(L.flow.savedToast + " · " + (ppage + 2) + "/" + PAGES.length); return; }
    // finished target → collect contact info first (only if not already collected)
    if (!data.contact) { setShowContact(true); scrollTop(); return; }
    goHub();
  };

  const submitContact = (contactData) => {
    window.track && window.track("contact_submitted", { company: contactData.company, lang },
      { type: "lead", contact: contactData, snapshot: snapshotOf(data) });
    set({ contact: contactData });
    // Email the sales team the moment the contact form is submitted (Resend, via /api/send-plan).
    // Guarded by planSent so Hub/Thanks don't send a duplicate.
    if (!data.planSent) {
      set({ planSent: true });
      try {
        var planData = window.buildPlanSummary(Object.assign({}, data, { contact: contactData }), lang);
        window.sendPlan(Object.assign({}, planData, { contact: contactData }));
      } catch (e) {}
    }
    setShowContact(false);
    goHub();
  };
  const back = () => {
    if (route) {
      if (dests.length > 1 && route !== "hub") setRoute("hub"); else setRoute(null);
      scrollTop(); return;
    }
    if (phase === 1) {
      if (ppage > 0) { setPpage(ppage - 1); scrollTop(); }
      else { setPhase(0); scrollTop(); }
      return;
    }
  };

  const goRoute = (r) => { window.track && window.track("destination_opened", { dest: r, lang }); setRoute(r); scrollTop(); };
  const restart = () => { window.track && window.track("restart", { lang }); setData(DEFAULT_DATA); setPhase(0); setPpage(0); setRoute(null); try { localStorage.removeItem("globby_wizard_v2"); } catch (e) {} scrollTop(); };

  const stepProps = { L, lang, data, set, confirmAnalysis, toast, goRoute, next, multiDest: dests.length > 1, profilePage: ppage };

  // ---------- ROUTE (destination) VIEW ----------
  if (route) {
    // "market" route currently points to ThanksPage (MarketPage kept for when real
    // trade data is connected) — users see a thank-you instead of the demo analysis.
    const RouteComp = { hub: window.HubPage, market: window.ThanksPage, find: window.FindStep, email: window.EmailPage }[route];
    return React.createElement("div", { className: "app" },
      React.createElement(Topbar, { L, lang, switchLang, restart }),
      React.createElement("div", { className: "stage" },
        React.createElement("div", { className: "card-wrap wide" },
          React.createElement("div", { className: route === "hub" ? "" : "stepcard", key: route },
            (route !== "hub") ? React.createElement("button", { className: "route-back", onClick: back },
              React.createElement(GIcon, { name: "arrow-left", size: 16 }), L.flow.backHub) : null,
            RouteComp ? React.createElement(RouteComp, stepProps) : null)
        )
      ),
      toastMsg ? React.createElement(Toast, { msg: toastMsg }) : null
    );
  }

  // ---------- WIZARD VIEW ----------
  const PhaseComp = phase === 0 ? window.SetupPhase : window.ProfilePhase;
  const phaseLabels = [L.flow.phase1, L.flow.phase2];
  // overall progress: phase 0 = 1 segment; phase 1 = PAGES.length segments
  const totalTarget = PAGES.length;
  // friendly overall step counter across the whole wizard (Define = 1 step, Target = PAGES.length steps)
  const totalSteps = 1 + PAGES.length;
  const curStep = phase === 0 ? 1 : ppage + 2;
  const curPhaseName = phase === 0 ? phaseLabels[0] : phaseLabels[1];
  const pct = Math.round((curStep / totalSteps) * 100);
  const pageTitle = phase === 0 ? L.flow.p1Title : L.flow.p2Title;
  const pageSub = phase === 0 ? L.flow.p1Sub : L.flow.p2Sub;

  return React.createElement("div", { className: "app" },
    React.createElement(Topbar, { L, lang, switchLang, restart }),
    // progress
    React.createElement("div", { className: "progress" },
      // friendly overall step counter — visible the same way on desktop & mobile
      React.createElement("div", { className: "progress-head" },
        React.createElement("span", { className: "step-counter" },
          React.createElement("span", { className: "step-counter-word" }, L.flow.step + " "),
          React.createElement("span", { className: "step-counter-num" }, curStep),
          React.createElement("span", { className: "step-counter-sep" }, " " + L.flow.of + " "),
          React.createElement("span", { className: "step-counter-tot" }, totalSteps)),
        React.createElement("span", { className: "step-phase" }, curPhaseName + "  ·  " + (lang === "tr" ? "%" + pct : pct + "%"))),
      React.createElement("div", { className: "phaserow two" },
        React.createElement("div", { className: "phase" + (phase === 0 ? " active" : " done") },
          React.createElement("span", { className: "phase-label" }, "1. " + phaseLabels[0]),
          React.createElement("div", { className: "segs" },
            React.createElement("div", { className: "seg" + (phase > 0 ? " done" : " cur") }, React.createElement("div", { className: "fill" })))),
        React.createElement("div", { className: "phase" + (phase === 1 ? " active" : "") },
          React.createElement("span", { className: "phase-label" }, "2. " + phaseLabels[1] + (phase === 1 ? "  ·  " + (ppage + 1) + "/" + totalTarget : "")),
          React.createElement("div", { className: "segs" },
            PAGES.map((p, i) => React.createElement("div", { key: i, className: "seg" + (phase === 1 && i < ppage ? " done" : phase === 1 && i === ppage ? " cur" : "") }, React.createElement("div", { className: "fill" }))))))
    ),
    // stage
    React.createElement("div", { className: "stage" },
      React.createElement("div", { className: "card-wrap" },
        (phase === 0) ? React.createElement("div", { className: "phase-intro" },
          React.createElement("h2", { className: "step-title" }, pageTitle),
          React.createElement("p", { className: "step-sub" }, pageSub)) : null,
        React.createElement("div", { className: "stepcard", key: phase + "-" + ppage },
          React.createElement(PhaseComp, stepProps))
      )
    ),
    // footer nav
    React.createElement("div", { className: "footnav" },
      React.createElement("div", { className: "inner" },
        (phase > 0) ? React.createElement("button", { className: "btn btn-back", onClick: back }, React.createElement(GIcon, { name: "arrow-left", size: 18 }), L.flow.back) : React.createElement("span", null),
        React.createElement("button", { className: "btn btn-primary", disabled: !pageOk(), onClick: next },
          (phase === 1 && isLastProfilePage()) ? L.flow.buildPlan : L.flow.continue,
          React.createElement(GIcon, { name: (phase === 1 && isLastProfilePage()) ? "sparkles" : "arrow-right", size: 18, stroke: 2.4 })))
    ),
    toastMsg ? React.createElement(Toast, { msg: toastMsg }) : null,
    showContact ? React.createElement(ContactModal, { L, lang, onSubmit: submitContact, defaultCountry: data.country }) : null
  );
}

// KVKK / privacy disclosure link target (repoint to a dedicated page when available).
var KVKK_URL = "https://theglobby.com";

function ContactModal(props) {
  const { L, lang, onSubmit, defaultCountry } = props;
  const C = L.contact || {};
  // country list for the phone dial-code picker (only countries we have a dial code for)
  const dialList = (window.COUNTRIES_ALL || []).map(function (c) {
    return { c: c.c, f: c.f, name: lang === "tr" ? c.tr : c.en, dial: (window.DIAL_BY && window.DIAL_BY[c.c]) || "" };
  }).filter(function (x) { return x.dial; }).sort(function (a, b) { return a.name.localeCompare(b.name); });
  const initCc = (defaultCountry && window.DIAL_BY && window.DIAL_BY[defaultCountry]) ? defaultCountry : "TR";
  const [f, setF] = useState({ firstName: "", lastName: "", company: "", email: "", phone: "", cc: initCc, kvkk: false });
  const upd = (k) => (e) => setF(function (p) { return Object.assign({}, p, { [k]: e.target.value }); });
  const dial = (window.DIAL_BY && window.DIAL_BY[f.cc]) || "";
  const canSubmit = f.firstName.trim() && f.lastName.trim() && f.company.trim() && f.email.trim() && f.phone.trim() && f.kvkk;
  const submit = () => {
    if (!canSubmit) return;
    const fullPhone = (dial ? "+" + dial + " " : "") + f.phone.trim();
    onSubmit({ firstName: f.firstName.trim(), lastName: f.lastName.trim(), company: f.company.trim(), email: f.email.trim(), phone: fullPhone, kvkk: true });
  };
  const star = React.createElement("span", { style: { color: "var(--gb-violet)", marginLeft: 2 } }, "*");
  const field = (key, label, type, ac) =>
    React.createElement("div", { className: "field" },
      React.createElement("label", null, label, star),
      React.createElement("input", { className: "inp", type: type || "text", value: f[key], onChange: upd(key), autoComplete: ac || "on", required: true }));
  return React.createElement("div", { className: "contact-overlay" },
    React.createElement("div", { className: "contact-modal" },
      React.createElement("div", { className: "contact-modal-head" },
        React.createElement("div", { className: "hub-badge", style: { margin: "0 auto 10px" } }, React.createElement(GIcon, { name: "user-round", size: 26 })),
        React.createElement("h3", { style: { margin: "0 0 6px", fontSize: 20, fontWeight: 800, color: "#fff" } }, C.title || "Your details"),
        React.createElement("p", { style: { margin: 0, fontSize: 14, color: "rgba(255,255,255,.8)", lineHeight: 1.5 } }, C.sub || "")),
      React.createElement("div", { className: "contact-modal-body" },
        React.createElement("div", { className: "contact-row" },
          field("firstName", C.firstName || "First name", "text", "given-name"),
          field("lastName",  C.lastName  || "Last name",  "text", "family-name")),
        field("company", C.company || "Company",      "text",  "organization"),
        field("email",   C.email   || "Email",         "email", "email"),
        // phone: country dial-code select + number
        React.createElement("div", { className: "field" },
          React.createElement("label", null, C.phone || "Mobile phone", star),
          React.createElement("div", { style: { display: "flex", gap: 8 } },
            React.createElement("select", { className: "sel", style: { flex: "0 0 auto", maxWidth: 168 }, value: f.cc, onChange: upd("cc"), "aria-label": "Country code" },
              dialList.map(function (d) { return React.createElement("option", { key: d.c, value: d.c }, d.f + "  " + d.name + " (+" + d.dial + ")"); })),
            React.createElement("input", { className: "inp", type: "tel", inputMode: "tel", style: { flex: 1 }, value: f.phone, onChange: upd("phone"), autoComplete: "tel", placeholder: dial ? "+" + dial + " …" : "", required: true }))),
        // KVKK consent — mandatory
        React.createElement("label", { className: "field", style: { display: "flex", alignItems: "flex-start", gap: 9, marginTop: 4, fontSize: 13, lineHeight: 1.5, color: "var(--gb-ink-700)", cursor: "pointer" } },
          React.createElement("input", { type: "checkbox", checked: f.kvkk, onChange: function (e) { setF(function (p) { return Object.assign({}, p, { kvkk: e.target.checked }); }); }, style: { marginTop: 2, flex: "0 0 auto", width: 17, height: 17, accentColor: "var(--gb-violet)" }, required: true }),
          React.createElement("span", null,
            (C.kvkk || "I consent to the processing of my personal data and to being contacted."), " ",
            React.createElement("a", { href: KVKK_URL, target: "_blank", rel: "noopener noreferrer", style: { color: "var(--gb-violet)", textDecoration: "underline" }, onClick: function (e) { e.stopPropagation(); } }, C.kvkkLink || "Privacy Notice"),
            star))),
      React.createElement("div", { className: "contact-modal-foot" },
        React.createElement("button", { className: "btn btn-primary", style: { width: "100%" }, disabled: !canSubmit, onClick: submit },
          React.createElement(GIcon, { name: "sparkles", size: 17, stroke: 2.4 }), C.submit || "Get the plan"))));
}

function Topbar(props) {
  const { L, lang, switchLang, restart } = props;
  return React.createElement("div", { className: "topbar" },
    React.createElement("div", { className: "brand" },
      React.createElement("img", { src: "assets/logo-globby.png", alt: "Globby" }),
      React.createElement("span", { className: "brand-sub" }, L.wizardTitle)),
    React.createElement("div", { className: "topbar-right" },
      React.createElement("div", { className: "langtoggle" },
        React.createElement("button", { className: lang === "tr" ? "on" : "", onClick: () => switchLang("tr") }, "TR"),
        React.createElement("button", { className: lang === "en" ? "on" : "", onClick: () => switchLang("en") }, "EN")),
      React.createElement("button", { className: "exit-btn", onClick: restart }, React.createElement(GIcon, { name: "x", size: 15 }), L.flow.restart))
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(React.createElement(App));
