/* global React, ReactDOM */
const { useState, useEffect, useRef } = React;

/* ===================================================================
   WAITLIST MODAL
   =================================================================== */
function WaitlistModal({ open, onClose, source, onSuccess }) {
  const [email, setEmail] = useState("");
  const [status, setStatus] = useState("idle");
  const [position, setPosition] = useState(null);
  const [shareCopied, setShareCopied] = useState(false);

  useEffect(() => {
    if (!open) {
      const t = setTimeout(() => {
        setStatus("idle");
        setPosition(null);
        setEmail("");
        setShareCopied(false);
      }, 260);
      return () => clearTimeout(t);
    }
  }, [open]);

  useEffect(() => {
    const onKey = (e) => { if (e.key === "Escape" && open) onClose(); };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [open, onClose]);

  useEffect(() => {
    if (!open) return;
    const prev = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    return () => { document.body.style.overflow = prev; };
  }, [open]);

  const fakePosition = () => 12848 + Math.floor(Math.random() * 47);

  // TODO: wire to real waitlist endpoint.
  // POST { method: 'wallet' | 'email', address?, email?, source } to provider.
  // source ∈ { 'top_nav_cta' | 'hero_cta' | 'footer_cta' | 'sticky_mobile_cta' }.
  const connectWallet = () => {
    setStatus("submittingWallet");
    setTimeout(() => {
      const pos = fakePosition();
      setPosition(pos);
      setStatus("success");
      onSuccess && onSuccess(pos);
    }, 1100);
  };

  const submitEmail = (e) => {
    e.preventDefault();
    if (!email.includes("@") || status === "submittingEmail") return;
    setStatus("submittingEmail");
    setTimeout(() => {
      const pos = fakePosition();
      setPosition(pos);
      setStatus("success");
      onSuccess && onSuccess(pos);
    }, 800);
  };

  const copyShareText = () => {
    const txt = `Just joined the @verdict waitlist. Leveraged prediction markets, live at the World Cup. #${position.toLocaleString("en-US")} on the list.`;
    if (navigator.clipboard && navigator.clipboard.writeText) {
      navigator.clipboard.writeText(txt).catch(() => {});
    }
    setShareCopied(true);
    setTimeout(() => setShareCopied(false), 2200);
  };

  if (!open) return null;
  const isSuccess = status === "success";

  return (
    <div className="modal-scrim" onMouseDown={onClose} role="presentation">
      <div
        className="modal"
        onMouseDown={(e) => e.stopPropagation()}
        role="dialog"
        aria-modal="true"
        aria-labelledby="waitlist-modal-title"
        data-source={source || "unknown"}
      >
        <button className="modal-x" onClick={onClose} aria-label="Close">×</button>

        {!isSuccess && (
          <div className="modal-fade" key="form">
            <div className="modal-lockup">
              <img src="assets/verdict-mark-white.svg" alt="" aria-hidden="true" />
              <span className="wm">Verdict</span>
            </div>

            <h2 className="modal-title" id="waitlist-modal-title">Join the waitlist.</h2>
            <p className="modal-sub">Beta opens June 11 at World Cup kickoff.</p>

            <button
              className="modal-cta-primary"
              onClick={connectWallet}
              disabled={status === "submittingWallet"}
            >
              {status === "submittingWallet" ? "Connecting…" : (<>Connect wallet <span className="arrow">→</span></>)}
            </button>

            <div className="modal-or" aria-hidden="true"><span>OR</span></div>

            <form className="email-form-v2" onSubmit={submitEmail}>
              <input
                type="email"
                placeholder="you@protocol.xyz"
                value={email}
                onChange={(e) => setEmail(e.target.value)}
                aria-label="Email"
                autoFocus
              />
              <button
                type="submit"
                className="modal-cta-secondary"
                disabled={status === "submittingEmail" || !email.includes("@")}
              >
                {status === "submittingEmail" ? "Joining…" : "Join with email"}
              </button>
            </form>

            <p className="modal-fineprint">No spam. One email at launch.</p>
          </div>
        )}

        {isSuccess && (
          <div className="success-wrap modal-fade" key="success">
            <div className="share-frame" role="img" aria-label={`Position #${position} on the Verdict waitlist`}>
              <div className="share-bloom" aria-hidden="true"></div>
              <div className="share-top">
                <img src="assets/verdict-mark-white.svg" alt="" aria-hidden="true" />
                <span className="wm">Verdict</span>
              </div>
              <div className="share-center">
                <div className="share-num">#{position.toLocaleString("en-US")}</div>
                <div className="share-caption">On the list · Beta Jun 11</div>
              </div>
              <div className="share-bottom">
                <span>World Cup Kickoff</span>
                <span className="right">verdict.trade</span>
              </div>
            </div>

            <div className="share-hint">Screenshot and tag @verdict</div>

            <div className="success-actions">
              <button
                className={`modal-cta-secondary copy-btn ${shareCopied ? "copied" : ""}`}
                onClick={copyShareText}
              >
                {shareCopied ? "Copied ✓" : "Copy share text"}
              </button>
              <button className="modal-cta-secondary" onClick={onClose} style={{ width: "auto", padding: "14px 22px" }}>Done</button>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

/* ===================================================================
   TICKER
   =================================================================== */
const SAMPLE_MARKETS = [
  { q: "Trump · President Jan 1, 2027", yes: 67 },
  { q: "Argentina · Win World Cup 2026", yes: 22 },
  { q: "BTC · $150k by Dec 31", yes: 38 },
  { q: "Fed · Cut rates in July", yes: 71 },
  { q: "France · Win World Cup", yes: 19 },
  { q: "ETH · Flips SOL by Q4", yes: 44 },
  { q: "GOP · Hold the House '26", yes: 53 },
  { q: "Brazil · Win World Cup", yes: 17 },
  { q: "USA · Win World Cup", yes: 4 },
  { q: "SPY · Above 700 by Aug", yes: 61 },
  { q: "Powell · Out before EOY", yes: 12 },
  { q: "Spain · Win World Cup", yes: 14 },
];

function Ticker({ speed = 60 }) {
  const items = [...SAMPLE_MARKETS, ...SAMPLE_MARKETS];
  return (
    <div className="ticker">
      <div className="ticker-track" style={{ animationDuration: `${speed}s` }}>
        {items.map((m, i) => {
          const isHot = m.yes >= 65 || m.yes <= 25;
          return (
            <div className="tk" key={i}>
              <span className="tk-q">{m.q}</span>
              <span className="tk-bar">
                <span className="tk-yes" style={{ width: `${m.yes}%` }} />
              </span>
              <span className={`tk-yes-num mono-num ${isHot ? "tk-hot" : ""}`}>{m.yes}%</span>
              <span className="tk-no mono-num">/ {100 - m.yes}%</span>
              <span className="tk-lev mono-num">10×</span>
              <span className="tk-dot">·</span>
            </div>
          );
        })}
      </div>
    </div>
  );
}

/* ===================================================================
   SAMPLE MARKET CARD
   =================================================================== */
const YES_PROB = 0.22;
const POSITION_SIZE = 1000;

const fmtUSD = (n) =>
  "$" + n.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
const fmtCents = (priceDollars) => `${(priceDollars * 100).toFixed(1)}\u00a2`;

function calcReadouts(side, lev) {
  const collateral = POSITION_SIZE;
  const notional = POSITION_SIZE * lev;
  if (side === "YES") {
    const gain = notional * (1 - YES_PROB);
    const maxPayout = collateral + gain;
    const liqDrop = collateral / notional;
    const liqPrice = YES_PROB - liqDrop;
    return {
      maxPayout,
      liqPrice: liqPrice > 0 ? liqPrice : null,
      note: "if YES resolves true.",
    };
  } else {
    const noProb = 1 - YES_PROB;
    const gain = notional * (1 - noProb);
    const maxPayout = collateral + gain;
    const liqRise = collateral / notional;
    const liqPrice = noProb + liqRise;
    return {
      maxPayout,
      liqPrice: liqPrice < 1 ? liqPrice : null,
      note: "if NO resolves true.",
    };
  }
}

function MarketCard() {
  const [side, setSide] = useState("YES");
  const [lev, setLev] = useState(10);
  const r = calcReadouts(side, lev);
  return (
    <div className="mkt-card">
      <div className="mkt-head">
        <div className="mkt-eyebrow">
          <span className="dot-static" aria-hidden="true" /> Sample market · 10× live
        </div>
        <div className="mkt-vol">$27.4M · 24h</div>
      </div>
      <div className="mkt-q">Will Argentina win the World Cup?</div>
      <div className="mkt-prob">
        <div className="prob-row">
          <span className="prob-label">YES</span>
          <span className="prob-bar"><span className="prob-fill yes" style={{ width: "22%" }} /></span>
          <span className="prob-pct">22%</span>
        </div>
        <div className="prob-row">
          <span className="prob-label no">NO</span>
          <span className="prob-bar"><span className="prob-fill no" style={{ width: "78%" }} /></span>
          <span className="prob-pct">78%</span>
        </div>
      </div>
      <div className="mkt-controls">
        <div className="seg">
          <button className={side === "YES" ? "active yes" : ""} onClick={() => setSide("YES")}>Long YES</button>
          <button className={side === "NO" ? "active no" : ""} onClick={() => setSide("NO")}>Short NO</button>
        </div>
        <div className="lev-row">
          <span className="caption">Leverage</span>
          <div className="lev-chips">
            {[1, 5, 10].map((n) => (
              <button key={n} className={lev === n ? "active" : ""} onClick={() => setLev(n)}>{n}×</button>
            ))}
          </div>
        </div>
        <div className="mkt-summary">
          <div>
            <span className="caption">Position size</span>
            <span className="num">{fmtUSD(POSITION_SIZE)}</span>
          </div>
          <div>
            <span className="caption">Buying power</span>
            <span className="num">{fmtUSD(POSITION_SIZE * lev)}</span>
          </div>
          <div>
            <span className="caption">Max payout</span>
            <span className="num accent">{fmtUSD(r.maxPayout)}</span>
            <span className="fineprint">{r.note}</span>
          </div>
          <div>
            <span className="caption">Liq. at</span>
            <span className="num warn">
              {r.liqPrice == null ? "—" : fmtCents(r.liqPrice)}
              {r.liqPrice == null ? "" : (side === "NO" ? " NO" : " YES")}
            </span>
            <span className="fineprint">{r.liqPrice == null ? "never at this size" : "price level"}</span>
          </div>
        </div>
        <button className={`mkt-cta ${side === "NO" ? "short" : ""}`}>
          {side === "YES" ? "Long YES" : "Short NO"} · {lev}×
        </button>
      </div>
    </div>
  );
}

/* ===================================================================
   COUNTER TICK
   =================================================================== */
function tickCounter() {
  const el = document.getElementById("waitlist-count");
  if (!el) return;
  const current = parseInt(String(el.textContent).replace(/[^\d]/g, ""), 10) || 0;
  const target = current + 1;
  const start = performance.now();
  const dur = 400;
  const easeOut = (t) => 1 - Math.pow(1 - t, 3);
  function step(now) {
    const t = Math.min(1, (now - start) / dur);
    const v = Math.round(current + (target - current) * easeOut(t));
    el.textContent = v.toLocaleString("en-US");
    if (t < 1) requestAnimationFrame(step);
  }
  requestAnimationFrame(step);
  el.dataset.target = String(target);
}

/* ===================================================================
   APP
   =================================================================== */
function App() {
  const [modalOpen, setModalOpen] = useState(false);
  const [modalSource, setModalSource] = useState(null);
  const submittedRef = useRef(false);

  useEffect(() => {
    const handler = (e) => {
      const src = e.currentTarget?.dataset?.ctaSource || "unknown";
      setModalSource(src);
      submittedRef.current = false;
      setModalOpen(true);
    };
    const els = document.querySelectorAll("[data-cta='waitlist']");
    els.forEach((el) => el.addEventListener("click", handler));
    return () => els.forEach((el) => el.removeEventListener("click", handler));
  }, []);

  const handleSuccess = () => {
    submittedRef.current = true;
  };

  const handleClose = () => {
    setModalOpen(false);
    if (submittedRef.current) {
      setTimeout(() => tickCounter(), 320);
      submittedRef.current = false;
    }
  };

  // TODO: replace data-target on #waitlist-count with real backend count
  // (e.g. fetch('/api/waitlist/count') and set el.dataset.target before this runs).
  useEffect(() => {
    const el = document.getElementById("waitlist-count");
    if (!el || el.dataset.animated) return;
    el.dataset.animated = "1";
    const target = parseInt(el.dataset.target || "12847", 10);
    const duration = 800;
    const start = performance.now();
    const easeOut = (t2) => 1 - Math.pow(1 - t2, 3);
    function step(now) {
      const t2 = Math.min(1, (now - start) / duration);
      const val = Math.round(target * easeOut(t2));
      el.textContent = val.toLocaleString("en-US");
      if (t2 < 1) requestAnimationFrame(step);
    }
    requestAnimationFrame(() => requestAnimationFrame(step));
  }, []);

  useEffect(() => {
    const rows = document.querySelectorAll(".wedge-row");
    if (!rows.length || !("IntersectionObserver" in window)) {
      rows.forEach((r) => r.classList.add("visible"));
      return;
    }
    let triggered = false;
    const io = new IntersectionObserver(
      (entries) => {
        if (triggered) return;
        const hit = entries.find((e) => e.isIntersecting);
        if (!hit) return;
        triggered = true;
        rows.forEach((row, i) => {
          setTimeout(() => row.classList.add("visible"), i * 120);
        });
        io.disconnect();
      },
      { threshold: 0.3 }
    );
    rows.forEach((r) => io.observe(r));
    return () => io.disconnect();
  }, []);

  useEffect(() => {
    const bar = document.getElementById("mobile-cta-bar");
    const heroCta = document.querySelector(".hero .btn-primary[data-cta='waitlist']");
    if (!bar || !heroCta || !("IntersectionObserver" in window)) return;
    const io = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting) {
          bar.classList.remove("visible");
          bar.setAttribute("aria-hidden", "true");
        } else {
          bar.classList.add("visible");
          bar.setAttribute("aria-hidden", "false");
        }
      },
      { rootMargin: "0px", threshold: 0 }
    );
    io.observe(heroCta);
    return () => io.disconnect();
  }, []);

  useEffect(() => {
    const slot = document.getElementById("ticker-slot");
    if (slot && !slot.dataset.mounted) {
      slot.dataset.mounted = "1";
      ReactDOM.createRoot(slot).render(<Ticker speed={50} />);
    }
  }, []);

  useEffect(() => {
    const slot = document.getElementById("market-card-slot");
    if (slot && !slot.dataset.mounted) {
      slot.dataset.mounted = "1";
      ReactDOM.createRoot(slot).render(<MarketCard />);
    }
  }, []);

  return (
    <WaitlistModal
      open={modalOpen}
      onClose={handleClose}
      source={modalSource}
      onSuccess={handleSuccess}
    />
  );
}

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