// IndieVertical - newsletter signup: one reusable component with variants
// (inline, footer, banner) placed at the email-collection points across the site.
// Backed by the Supabase subscribe_newsletter() RPC (see migration
// 20260616000001_newsletter_subscribers.sql).

const IV_EMAIL_RE = /^[^@\s]+@[^@\s]+\.[^@\s]+$/;

// Insert/refresh a subscriber. `segment` pre-tags the audience ('dev' | 'scout' |
// 'all'); `source` records where the signup happened, for attribution.
async function ivSubscribeNewsletter(email, segment, source) {
  const { error } = await SUPA.rpc("subscribe_newsletter", {
    p_email: email,
    p_segment: segment || "all",
    p_source: source || "",
  });
  if (error) throw error;
  // Fire a GTM event so signups are attributable without new infra.
  if (window.dataLayer) {
    window.dataLayer.push({ event: "newsletter_subscribe", segment: segment || "all", source: source || "" });
  }
}

// variant: "inline" | "footer" | "banner"
// segment: "dev" | "scout" | "all"   (pre-tags the subscriber)
// source:  attribution string, e.g. "home-inline" or "blog-post:<slug>"
// force:   render even for logged-in users (used on the post-signup consent step)
function IvNewsletter({ variant = "inline", segment = "all", source = "", heading, sub, button, force }) {
  const { state, api } = useStore();
  // Prefill the field for logged-in users so subscribing is one click.
  const userEmail = (state.session && state.session.user && state.session.user.email) || "";
  const [email, setEmail] = React.useState(userEmail);
  const [status, setStatus] = React.useState("idle"); // idle | submitting | done
  const [error, setError] = React.useState("");
  const honeypot = React.useRef(null);

  // Passive prompts never bother people who already gave us their email at signup.
  if (!force && state.role !== "visitor") return null;

  const title = heading || "The indie games briefing.";
  const subline = sub || "A short, regular read on the indie game industry: trends, standout new projects, and resources worth your time. No spam.";
  const cta = button || "Subscribe";

  const submit = async (e) => {
    e.preventDefault();
    setError("");
    if (honeypot.current && honeypot.current.value) return; // bot trap
    const v = email.trim();
    if (!IV_EMAIL_RE.test(v)) { setError("Please enter a valid email address."); return; }
    setStatus("submitting");
    try {
      await ivSubscribeNewsletter(v, segment, source);
      setStatus("done");
      if (api && api.showToast) api.showToast("You're subscribed. Thanks!");
    } catch (err) {
      setStatus("idle");
      if (err && (err.status === 429 || /rate limit/i.test(err.message || ""))) {
        setError("Too many attempts. Please wait a minute, then try again.");
      } else {
        setError("Something went wrong. Please try again.");
      }
    }
  };

  const cls = "nl nl-" + variant;

  if (status === "done") {
    return (
      <div className={cls}>
        <div className="nl-done">
          <span className="nl-done-tick">✓</span>
          <div>
            <div className="nl-title">You're on the list.</div>
            <p className="nl-sub">No confirmation needed. We'll start sending the newsletter soon — only when there's something worth your time.</p>
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className={cls}>
      <div className="nl-head">
        {variant === "banner" && <span className="nl-eyebrow">Newsletter</span>}
        <div className="nl-title">{title}</div>
        <p className="nl-sub">{subline}</p>
      </div>
      <form className="nl-form" onSubmit={submit} noValidate>
        {/* honeypot: hidden from humans, tempting to bots */}
        <input ref={honeypot} type="text" name="company" tabIndex="-1" autoComplete="off"
          aria-hidden="true" style={{ position: "absolute", left: "-9999px", width: 1, height: 1, opacity: 0 }} />
        <input
          className="f-input nl-input"
          type="email"
          placeholder="you@studio.com"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
          disabled={status === "submitting"}
          autoComplete="email"
          aria-label="Email address"
        />
        <button type="submit" className="btn btn-primary nl-btn" disabled={status === "submitting"}>
          {status === "submitting" ? "..." : cta}
        </button>
      </form>
      {error && <p className="nl-err">{error}</p>}
      <p className="nl-consent">
        By subscribing you agree to receive emails from IndieVertical. Unsubscribe anytime. See our{" "}
        <a href="/privacy">Privacy Policy</a>.
      </p>
    </div>
  );
}

// Floating, dismissible newsletter prompt. Fixed to the viewport so it stays
// visible from the hero down as the user scrolls, but non-modal (no backdrop)
// so everything below it stays interactive. Shown to visitors and logged-in
// users alike (force), and stays closed once dismissed.
function IvNewsletterPopup({ segment = "all", source = "home-popup", heading, sub, button }) {
  const [dismissed, setDismissed] = React.useState(() => {
    try { return localStorage.getItem("iv_nl_popup_dismissed") === "1"; } catch (e) { return false; }
  });
  if (dismissed) return null;

  const close = () => {
    setDismissed(true);
    try { localStorage.setItem("iv_nl_popup_dismissed", "1"); } catch (e) {}
  };

  return (
    <div className="nl-pop" role="complementary" aria-label="Newsletter signup">
      <button type="button" className="nl-pop-x" aria-label="Close" onClick={close}>×</button>
      <IvNewsletter
        variant="popup"
        segment={segment}
        source={source}
        force
        heading={heading || "Stay close to indie games."}
        sub={sub || "Industry news, trends, and standout new projects, in one short email. No spam."}
        button={button || "Subscribe"}
      />
    </div>
  );
}

Object.assign(window, { IvNewsletter, IvNewsletterPopup, ivSubscribeNewsletter });
