// Salersons — warm dark, color photos, smooth serif, champagne gold accent
const { useEffect, useRef, useState } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "#D4A86A",
  "photos": true,
  "heroItalFont": "aBigDeal",
  "heroScale": 0.8,
  "heroVariant": "A",
  "heroSub": "Sales recruiting out of Limassol. Israeli desks first — then Cyprus, Bulgaria, Serbia, Dubai and Manila when the offer on the table is better.",
  "manifestoVariant": "A",
  "applyHeading": "Send the CV.",
  "applySub": "We read every line. If your numbers say what we hope they say, you'll hear back the same day with a floor worth your time.",
  "industriesIntro": "Five floors. One brief.",
  "locationsIntro": "Six Locations.",
  "closingVariant": "A"
}/*EDITMODE-END*/;

// ───── Data ─────
const INDUSTRIES = [
  { name: "Forex",   align: 0,   size: "clamp(54px, 13vw, 156px)", italic: true  },
  { name: "Crypto",  align: 28,  size: "clamp(60px, 14vw, 168px)", italic: false },
  { name: "CFDs",    align: 8,   size: "clamp(48px, 11vw, 132px)", italic: true  },
  { name: "Fintech", align: 36,  size: "clamp(56px, 13vw, 156px)", italic: false },
  { name: "iGaming", align: 14,  size: "clamp(50px, 12vw, 144px)", italic: true  },
];

const CITIES = [
  { name: "Israel",      tag: "primary",      size: "clamp(64px, 16vw, 192px)", anchor: true, align: 0  },
  { name: "Cyprus",      tag: "international",size: "clamp(44px, 10vw, 124px)", align: 18 },
  { name: "Bulgaria",    tag: "international",size: "clamp(46px, 10vw, 132px)", align: 6  },
  { name: "Serbia",      tag: "international",size: "clamp(42px, 9vw, 116px)",  align: 24 },
  { name: "Dubai",       tag: "international",size: "clamp(48px, 11vw, 144px)", align: 10 },
  { name: "Philippines", tag: "international",size: "clamp(40px, 9vw, 112px)",  align: 30 },
];

const SECTIONS = [
  { id: "hero",       img: "assets/scene1-telaviv.webp" },
  { id: "apply",      img: "assets/scene6-desk.webp" },
  { id: "about",      img: "assets/about-silhouette.webp" },
  { id: "industries", img: "assets/scene2-trading.webp" },
  { id: "process",    img: "assets/scene3-headset.webp" },
  { id: "locations",  img: "assets/scene5-globe.webp" },
  { id: "closing",    img: "assets/scene1-telaviv.webp" },
];

const PHOTO_URLS = [...new Set(SECTIONS.map(s => s.img))];

// ───── Copy variants ─────
const HERO_VARIANTS = {
  A: { l1: "Sales floors", l2: "are hiring", l3: "closers." },
  B: { l1: "The desks", l2: "that pay", l3: "in dollars." },
  C: { l1: "Your numbers", l2: "deserve a floor", l3: "that pays them." },
};

const MANIFESTO_VARIANTS = {
  A: <span>We don't coach you. <em className="dim">We don't run prep calls.</em> We read your numbers, we know every floor that's hiring, and we put you on the one where your closes are worth the most — <em className="accent">then we step back.</em></span>,
  B: <span>We are not a database. <em className="dim">We are not a CV blast.</em> We meet you, we read the work you've already done, and we match you to the desk that pays it what it's worth — <em className="accent">nothing more, nothing less.</em></span>,
  C: <span>Forget the LinkedIn voice. <em className="dim">Forget the prep call.</em> Walk us through your last desk, and we'll show you the one that should have been paying you in the first place — <em className="accent">if it's on our books, it's yours to take.</em></span>,
};

const CLOSING_VARIANTS = {
  A: <span>Your next desk is <em className="ital">already open.</em></span>,
  B: <span>Send what you've closed. <em className="ital">We'll send where you go next.</em></span>,
  C: <span>The right floor <em className="ital">pays in real money.</em></span>,
};

// ───── Directional reveal ─────
function useReveal() {
  useEffect(() => {
    const all = [...document.querySelectorAll(".reveal")];
    const pending = new Set(all);

    let lastY = window.scrollY;
    let direction = "down";

    const tick = () => {
      const y = window.scrollY;
      if (y > lastY + 1) direction = "down";
      else if (y < lastY - 1) direction = "up";
      lastY = y;

      const vh = window.innerHeight;
      for (const el of [...pending]) {
        const r = el.getBoundingClientRect();
        if (r.top < vh * 0.92 && r.bottom > 0) {
          // Set direction-aware starting offset, then trigger transition to 0
          el.style.transform = direction === "down"
            ? "translateY(28px)"
            : "translateY(-28px)";
          // Force browser to commit the inline style as starting frame
          el.offsetHeight; // eslint-disable-line
          requestAnimationFrame(() => {
            el.classList.add("in");
            el.style.transform = "";
          });
          pending.delete(el);
        }
      }
    };

    let ticking = false;
    const onScroll = () => {
      if (!ticking) {
        ticking = true;
        requestAnimationFrame(() => { tick(); ticking = false; });
      }
    };

    tick();
    window.addEventListener("scroll", onScroll, { passive: true });
    window.addEventListener("resize", onScroll);
    return () => {
      window.removeEventListener("scroll", onScroll);
      window.removeEventListener("resize", onScroll);
    };
  }, []);
}

// ───── Active photo (rAF + bounding rect — IO unreliable in this iframe) ─────
function useActivePhoto() {
  const [active, setActive] = useState(SECTIONS[0].img);
  useEffect(() => {
    const sections = SECTIONS
      .map(s => ({ s, el: document.getElementById(s.id) }))
      .filter(x => x.el);

    const pick = () => {
      const vh = window.innerHeight;
      const probe = vh * 0.45;
      let best = sections[0];
      let bestDist = Infinity;
      for (const item of sections) {
        const r = item.el.getBoundingClientRect();
        if (r.bottom < 0 || r.top > vh) continue;
        const center = r.top + r.height / 2;
        const dist = Math.abs(center - probe);
        if (dist < bestDist) {
          bestDist = dist;
          best = item;
        }
      }
      if (best) setActive(best.s.img);
    };

    let ticking = false;
    const onScroll = () => {
      if (!ticking) {
        ticking = true;
        requestAnimationFrame(() => { pick(); ticking = false; });
      }
    };

    pick();
    window.addEventListener("scroll", onScroll, { passive: true });
    window.addEventListener("resize", onScroll);
    return () => {
      window.removeEventListener("scroll", onScroll);
      window.removeEventListener("resize", onScroll);
    };
  }, []);
  return active;
}

// ───── Photo layer ─────
function PhotoStack({ enabled }) {
  const active = useActivePhoto();
  if (!enabled) return <div className="photo-stack" style={{ background: "var(--bg)" }} />;
  return (
    <div className="photo-stack">
      {PHOTO_URLS.map(url => (
        <div
          key={url}
          className={`photo${url === active ? " on" : ""}`}
          style={{ backgroundImage: `url("${url}")` }}
        />
      ))}
    </div>
  );
}

// ───── Sections ─────
function Nav() {
  return (
    <nav className="nav">
      <a href="#top" className="nav__mark"><img className="nav__logo" src="assets/salersons-logo.webp" alt="Salersons" width="36" height="40" />Salersons<span className="dot">.</span></a>
    </nav>
  );
}

function Hero({ variant, sub }) {
  const v = HERO_VARIANTS[variant] || HERO_VARIANTS.A;
  return (
    <section className="hero" id="hero">
      <h1 className="hero__title reveal">
        <span className="l">{v.l1}</span>
        <span className="l ital">{v.l2}</span>
        <span className="l"><span className="accent">{v.l3}</span></span>
      </h1>
      <p className="hero__sub reveal d2">{sub}</p>
      <div className="hero__scroll" aria-hidden="true">
        <span>Scroll</span>
        <span className="line" />
      </div>
    </section>
  );
}

function Apply({ heading, sub }) {
  // Real lead capture. Posts to the same /api/lead.php sink as Apply.html with
  // three-layer delivery (fetch -> beacon -> native form POST) so a submit is
  // never silently dropped. Field names are snake_case to match lead.php / GAS.
  const ENDPOINT = "/api/lead.php";
  // Same EU/EEA region test as the pixel gate (see <head>). When true the
  // browser pixel never loaded, so we tell the server (eu_region=1) to skip
  // server-side CAPI too, keeping the EU-block consistent on both sides.
  const EU_REGION = (() => {
    try {
      const tz = (window.Intl && Intl.DateTimeFormat().resolvedOptions().timeZone) || "";
      return /^Europe\//.test(tz) ||
        tz === "Atlantic/Reykjavik" || tz === "Atlantic/Canary" ||
        tz === "Atlantic/Madeira"  || tz === "Atlantic/Azores";
    } catch (e) { return false; }
  })();
  const MAX_BYTES = 5 * 1024 * 1024;
  const ACCEPT_EXTS = ["pdf", "doc", "docx", "rtf", "odt", "txt"];
  const ACCEPT_ATTR = ".pdf,.doc,.docx,.rtf,.odt,.txt,application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document";

  const [sending, setSending] = useState(false);
  const [sent, setSent] = useState(false);
  const [cvName, setCvName] = useState("");
  const [cvWarn, setCvWarn] = useState("");
  const fileRef = useRef(null);

  const onFileChange = (e) => {
    const f = e.target.files && e.target.files[0];
    if (!f) { setCvName(""); setCvWarn(""); return; }
    const ext = (f.name.split(".").pop() || "").toLowerCase();
    if (f.size > MAX_BYTES) {
      setCvWarn("File too large (max 5 MB). Choose a smaller one.");
      setCvName("");
      if (fileRef.current) fileRef.current.value = "";
      return;
    }
    if (!ACCEPT_EXTS.includes(ext)) {
      setCvWarn("Unsupported format. Use PDF, DOC, DOCX, RTF, ODT, or TXT.");
      setCvName("");
      if (fileRef.current) fileRef.current.value = "";
      return;
    }
    setCvWarn("");
    setCvName(f.name + " · " + (f.size / 1024 / 1024).toFixed(2) + " MB");
  };

  const onSubmit = async (e) => {
    e.preventDefault();
    // Validation is advisory only. NEVER preventDefault-and-return on a bad
    // field — that silently drops the lead. We always attempt delivery and
    // let lead.php validate softly. See form_submit_handler_pattern memory.
    const form = e.currentTarget;
    const data = new FormData(form);
    data.append("source", "home-apply");
    data.append("submitted_at", new Date().toISOString());

    setSending(true);

    // Layer 1: fetch.
    try {
      const res = await fetch(ENDPOINT, { method: "POST", body: data });
      if (res.ok) {
        // Browser-side Lead with eventID = server lead_id, so Meta dedupes it
        // against the CAPI Lead. Guarded: window.fbq is undefined for EU
        // visitors where the pixel never loaded, so this is a no-op there.
        try {
          const j = await res.json();
          if (window.fbq && j && j.lead_id) {
            window.fbq("track", "Lead", {}, { eventID: j.lead_id });
          }
        } catch (e) { /* server CAPI still records the Lead */ }
        setSent(true);
        return;
      }
    } catch (err) { /* fall through */ }

    // Layer 2: sendBeacon (fires even mid-navigation; covers a fetch failure).
    // Note: a large CV may exceed the beacon cap; layer 3 then takes over.
    try {
      if (navigator.sendBeacon && navigator.sendBeacon(ENDPOINT, data)) {
        setSent(true);
        return;
      }
    } catch (err) { /* fall through */ }

    // Layer 3: native POST. Last resort, never a silent drop.
    setSending(false);
    form.submit();
  };

  return (
    <section className="section" id="apply">
      <div className="container">
        <div className="apply__inner">
          <div className="apply__head">
            <h2 className="apply__h reveal">{heading}</h2>
            <p className="apply__sub reveal d1">{sub}</p>
          </div>
          {sent ? (
            <div
              className="apply__form apply__form--sent reveal d2"
              role="status"
              aria-live="polite"
            >
              <div className="apply__sent">
                <span className="apply__sent__mark" aria-hidden="true">✓</span>
                <h3 className="apply__sent__h">Got it.</h3>
                <p className="apply__sent__p">
                  A real person reads every line and will be back to you within one business day.
                  Check your inbox for a confirmation note.
                </p>
              </div>
            </div>
          ) : (
            <form
              className="apply__form reveal d2"
              method="post"
              action={ENDPOINT}
              encType="multipart/form-data"
              noValidate
              onSubmit={onSubmit}
            >
              <div aria-hidden="true" style={{ position: "absolute", left: "-9999px", top: "-9999px", width: "1px", height: "1px", overflow: "hidden" }}>
                <label htmlFor="hp-home-website">Leave this field empty</label>
                <input id="hp-home-website" type="text" name="website" tabIndex={-1} autoComplete="off" />
              </div>
              <input type="hidden" name="eu_region" value={EU_REGION ? "1" : ""} />
              <div className="field">
                <label className="field__label" htmlFor="home-first">First name</label>
                <input id="home-first" className="field__input" name="first_name" placeholder="First" required />
              </div>
              <div className="field">
                <label className="field__label" htmlFor="home-last">Last name</label>
                <input id="home-last" className="field__input" name="last_name" placeholder="Last" />
              </div>
              <div className="field">
                <label className="field__label" htmlFor="home-email">Email</label>
                <input id="home-email" type="email" className="field__input" name="email" placeholder="best way to reach you" required />
              </div>
              <div className="field">
                <label className="field__label" htmlFor="home-phone">Phone (with country code)</label>
                <input id="home-phone" type="tel" className="field__input" name="phone" placeholder="+972 ..." />
              </div>
              <div className="field">
                <label className="field__label" htmlFor="home-message">Your desk</label>
                <input id="home-message" className="field__input" name="message" placeholder="years on a real sales desk, and what you've closed" />
              </div>
              <div className="field">
                <label className="field__label">CV (optional — PDF, DOC, DOCX, max 5 MB)</label>
                <label htmlFor="home-cv" className="field__file">
                  {cvName || "Choose a file"}
                </label>
                <input
                  id="home-cv"
                  ref={fileRef}
                  type="file"
                  name="cv"
                  accept={ACCEPT_ATTR}
                  onChange={onFileChange}
                  style={{ position: "absolute", width: "1px", height: "1px", padding: 0, margin: "-1px", overflow: "hidden", clip: "rect(0,0,0,0)", whiteSpace: "nowrap", border: 0 }}
                />
                {cvWarn ? (
                  <span role="status" aria-live="polite" style={{ fontFamily: "var(--mono)", fontSize: "11px", letterSpacing: "0.14em", textTransform: "uppercase", color: "#E07D5C", marginTop: "8px" }}>
                    {cvWarn}
                  </span>
                ) : null}
              </div>
              <button className="apply__submit" type="submit" disabled={sending}>
                <span>{sending ? "Sending…" : "Send"}</span>
                <span className="arr">→</span>
              </button>
              <p
                className="apply__alt"
                style={{ marginTop: "14px", fontFamily: "var(--mono)", fontSize: "11px", letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--ink-3)" }}
              >
                Want to share more? <a href="Apply.html" style={{ color: "var(--accent)" }}>Use the full application →</a>
              </p>
            </form>
          )}
        </div>
      </div>
    </section>
  );
}

function About({ variant }) {
  const body = MANIFESTO_VARIANTS[variant] || MANIFESTO_VARIANTS.A;
  return (
    <section className="section" id="about">
      <div className="container">
        <p className="about__body reveal">{body}</p>
        <div className="about__sig reveal d2">Salersons · since 2021</div>
      </div>
    </section>
  );
}

function Industries({ intro }) {
  return (
    <section className="section industries" id="industries">
      <div className="container">
        <p className="industries__head reveal">{intro}</p>
        <div className="ind-grid">
          {INDUSTRIES.map((it, i) => (
            <div
              key={it.name}
              className="ind-name reveal"
              style={{
                fontSize: it.size,
                fontStyle: it.italic ? "italic" : "normal",
                paddingLeft: `${it.align}%`,
                transitionDelay: `${i * 90}ms`,
              }}
            >
              {it.name}
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

function Process() {
  return (
    <section className="section" id="process">
      <div className="container">
        <h2 className="process__h reveal">
          We evaluate.<br />
          <span className="ital">You earn.</span>
        </h2>
        <div className="stations">
          <div className="station reveal">
            <h3 className="station__t">We <span className="ital">listen</span>.</h3>
            <p className="station__d">One conversation. What you've closed, what you actually want, what you'll never do again.</p>
          </div>
          <div className="station reveal d1">
            <h3 className="station__t">We <span className="ital">evaluate</span>.</h3>
            <p className="station__d">Your numbers, your hours, your language pairs — read against every desk we know is hiring in Israel and abroad.</p>
          </div>
          <div className="station reveal d2">
            <h3 className="station__t">We <span className="ital">match</span>.</h3>
            <p className="station__d">Not a CV blast. A direct intro to the floor where your skill set commands the highest comp on offer right now.</p>
          </div>
          <div className="station reveal d3">
            <h3 className="station__t">You <span className="ital">close</span>.</h3>
            <p className="station__d">We step back. Your job is to do what you've always done. Ours is to make sure the seat was worth taking.</p>
          </div>
        </div>
      </div>
    </section>
  );
}

function Locations({ intro }) {
  return (
    <section className="section" id="locations">
      <div className="container">
        <p className="locations__head reveal">{intro}</p>
        <div className="cities">
          {CITIES.map((c, i) => (
            <div
              key={c.name}
              className={`city reveal${c.anchor ? " is-anchor" : ""}`}
              style={{
                fontSize: c.size,
                paddingLeft: `${c.align}%`,
                transitionDelay: `${i * 90}ms`,
              }}
            >
              {c.name}
              <span className="tail">{c.tag}</span>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

function Closing({ variant }) {
  const h = CLOSING_VARIANTS[variant] || CLOSING_VARIANTS.A;
  return (
    <section className="closing" id="closing">
      <div className="container">
        <div className="closing__eyebrow reveal">When you're ready</div>
        <h2 className="closing__h reveal d1">{h}</h2>
        <a href="Apply.html" className="closing__cta reveal d2">
          <span>Send your CV</span>
          <span className="arr">→</span>
        </a>
      </div>
    </section>
  );
}

function Footer() {
  return (
    <footer className="footer">
      <div className="container">
        <div className="footer__brand"><img className="footer__logo" src="assets/salersons-logo.webp" alt="" width="26" height="29" />Salersons<span className="dot">.</span></div>
        <p className="footer__addr">
          Spyrou Kyprianou 25, Limassol 4001, Cyprus<br />
          <a href="mailto:support@salersons.com">support@salersons.com</a> · <a href="tel:+35725808100">+357 25 808 100</a>
        </p>
        <div className="footer__grid">
          <div>
            <h6>About</h6>
            <ul>
              <li><a href="#about">What we do</a></li>
              <li><a href="Process.html">Our process</a></li>
              <li><a href="Industries.html">Industries</a></li>
            </ul>
          </div>
          <div>
            <h6>Candidates</h6>
            <ul>
              <li><a href="Apply.html">Apply</a></li>
              <li><a href="Apply.html#what-to-bring">What to bring</a></li>
            </ul>
          </div>
          <div>
            <h6>Legal</h6>
            <ul>
              <li><a href="Privacy.html">Privacy</a></li>
              <li><a href="Terms.html">Terms</a></li>
            </ul>
          </div>
          <div>
            <h6>Hours</h6>
            <ul>
              <li><a href="#">Sun – Thu · 09:00 – 19:00</a></li>
              <li><a href="#">By appointment otherwise</a></li>
            </ul>
          </div>
        </div>
        <p className="footer__disclaimer">
          Salersons acts as an introduction agent between sales professionals and licensed employers. We do not employ candidates directly and we are not party to any employment contract you sign with a hiring company. Compensation figures discussed during the process reflect what a hiring desk has indicated and are subject to change at their sole discretion. Outcomes vary; nothing on this site constitutes a guarantee of placement, salary, or relocation. Any information you share is held in confidence and used only to introduce you to vetted employers who match your stated criteria.
        </p>
        <div className="footer__bottom">
          <span>© 2026 Salersons · Limassol</span>
          <span><a href="Privacy.html">Privacy</a> &nbsp;·&nbsp; <a href="Terms.html">Terms</a></span>
        </div>
      </div>
    </footer>
  );
}

// ───── App ─────
function App() {
  // Design tokens are baked in at export time. The live tweaks panel was a
  // designer-only tool (tweaks-panel.jsx) and is not shipped to production.
  const t = TWEAK_DEFAULTS;
  useReveal();

  useEffect(() => {
    const r = document.documentElement;
    r.style.setProperty("--accent", t.accent);
    r.style.setProperty("--hero-ital", `"${t.heroItalFont || "aBigDeal"}"`);
    r.style.setProperty("--hero-scale", String(t.heroScale ?? 1));
  }, [t.accent, t.heroItalFont, t.heroScale]);

  return (
    <React.Fragment>
      <PhotoStack enabled={t.photos !== false} />
      <Nav />
      <Hero variant={t.heroVariant} sub={t.heroSub} />
      <Apply heading={t.applyHeading} sub={t.applySub} />
      <About variant={t.manifestoVariant} />
      <Industries intro={t.industriesIntro} />
      <Process />
      <Locations intro={t.locationsIntro} />
      <Closing variant={t.closingVariant} />
      <Footer />
    </React.Fragment>
  );
}

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