// Shared UI: BookingModal, Tag, Stagger wrapper.
// Exposes: window.BookingModal, window.Stagger, window.useReveal.

const { useState, useEffect, useRef, useCallback } = React;

// Mount-time reveal hook. The per-element `delay` already provides the
// cascade — artboards are fixed-size, so we don't need IntersectionObserver
// (and it doesn't reliably fire inside the preview iframe).
function useReveal() {
  const ref = useRef(null);
  const [shown, setShown] = useState(false);
  useEffect(() => {
    const id = requestAnimationFrame(() => setShown(true));
    return () => cancelAnimationFrame(id);
  }, []);
  return [ref, shown];
}

// Stagger: animates children in with a delay.
function Stagger({ children, delay = 0, duration = 700, distance = 16, as: As = "div", style, className, ...rest }) {
  const [ref, shown] = useReveal();
  return (
    <As
      ref={ref}
      className={className}
      style={{
        opacity: shown ? 1 : 0,
        transform: shown ? "translateY(0)" : `translateY(${distance}px)`,
        transition: `opacity ${duration}ms cubic-bezier(.2,.7,.2,1) ${delay}ms, transform ${duration}ms cubic-bezier(.2,.7,.2,1) ${delay}ms`,
        ...style,
      }}
      {...rest}
    >
      {children}
    </As>
  );
}

// Booking modal — variant-aware via theme prop. When `embedUrl` is given it
// shows the Google appointment-scheduling form inline (iframe) so the user
// books without leaving the site; otherwise it falls back to an external link.
function BookingModal({ topic, onClose, theme, calendar, embedUrl }) {
  const open = !!topic;
  const [mounted, setMounted] = useState(false);
  const hasEmbed = !!embedUrl;
  useEffect(() => {
    if (open) {
      requestAnimationFrame(() => setMounted(true));
    } else {
      setMounted(false);
    }
  }, [open]);

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

  if (!open) return null;

  const t = theme || {};
  const isDark = t.isDark;
  const accent = t.accent || "#111";
  const bg = isDark ? "#0e0e10" : "#ffffff";
  const fg = isDark ? "#f4f3ee" : "#16140f";
  const muted = isDark ? "rgba(244,243,238,0.6)" : "rgba(22,20,15,0.55)";
  const border = isDark ? "rgba(255,255,255,0.08)" : "rgba(0,0,0,0.08)";

  return (
    <div
      onClick={onClose}
      style={{
        position: "absolute",
        inset: 0,
        background: isDark ? "rgba(0,0,0,0.7)" : "rgba(20,18,14,0.32)",
        backdropFilter: "blur(8px)",
        WebkitBackdropFilter: "blur(8px)",
        zIndex: 50,
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
        padding: 24,
        opacity: mounted ? 1 : 0,
        transition: "opacity 220ms ease",
      }}
    >
      <div
        onClick={(e) => e.stopPropagation()}
        style={{
          width: hasEmbed ? "min(860px, 100%)" : "min(440px, 100%)",
          maxHeight: "calc(100% - 16px)",
          display: "flex",
          flexDirection: "column",
          background: bg,
          color: fg,
          borderRadius: 18,
          border: `1px solid ${border}`,
          boxShadow: isDark ? "0 20px 60px rgba(0,0,0,0.6)" : "0 20px 60px rgba(20,18,14,0.18)",
          padding: hasEmbed ? 0 : 28,
          overflow: "hidden",
          transform: mounted ? "translateY(0) scale(1)" : "translateY(12px) scale(0.98)",
          opacity: mounted ? 1 : 0,
          transition: "opacity 260ms cubic-bezier(.2,.7,.2,1), transform 320ms cubic-bezier(.2,.7,.2,1)",
        }}
      >
        {/* Header */}
        <div style={{
          display: "flex", alignItems: "flex-start", justifyContent: "space-between",
          gap: 16,
          padding: hasEmbed ? "20px 24px 16px" : 0,
          marginBottom: hasEmbed ? 0 : 14,
          borderBottom: hasEmbed ? `1px solid ${border}` : "none",
        }}>
          <div>
            <span style={{
              fontSize: 11, letterSpacing: "0.14em", textTransform: "uppercase",
              color: muted, fontWeight: 500, display: "block", marginBottom: hasEmbed ? 6 : 0,
            }}>Book a session</span>
            {hasEmbed && (
              <div>
                <h3 style={{
                  fontSize: 21, lineHeight: 1.1, fontWeight: 600, margin: "0 0 4px",
                  letterSpacing: "-0.02em",
                }}>{topic.title}</h3>
                <div style={{
                  display: "flex", gap: 12, alignItems: "center",
                  fontSize: 12.5, color: muted,
                }}>
                  <span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
                    <span style={{ width: 6, height: 6, borderRadius: 999, background: accent, display: "inline-block" }} />
                    {topic.duration}
                  </span>
                  <span>·</span>
                  <span>{topic.for}</span>
                </div>
              </div>
            )}
          </div>
          <button
            onClick={onClose}
            data-cursor="hover"
            style={{
              border: "none", background: "transparent", color: muted, cursor: "pointer",
              fontSize: 20, lineHeight: 1, padding: 4, borderRadius: 6, flexShrink: 0,
            }}
            aria-label="Close"
          >×</button>
        </div>

        {hasEmbed ? (
          /* Inline booking form */
          <div style={{ flex: 1, minHeight: 0, background: "#fff", position: "relative" }}>
            <iframe
              src={embedUrl}
              title={`Book ${topic.title}`}
              style={{
                display: "block",
                width: "100%",
                height: "min(640px, 70vh)",
                border: "none",
              }}
            ></iframe>
          </div>
        ) : (
          /* Fallback: external link */
          <React.Fragment>
            <h3 style={{
              fontSize: 28, lineHeight: 1.1, fontWeight: 500, margin: "0 0 6px",
              letterSpacing: "-0.02em",
            }}>{topic.title}</h3>
            <div style={{
              display: "flex", gap: 14, alignItems: "center",
              fontSize: 13, color: muted, marginBottom: 18,
            }}>
              <span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
                <span style={{ width: 6, height: 6, borderRadius: 999, background: accent, display: "inline-block" }} />
                {topic.duration}
              </span>
              <span>·</span>
              <span>{topic.for}</span>
            </div>

            <p style={{
              fontSize: 14.5, lineHeight: 1.55, color: isDark ? "rgba(244,243,238,0.78)" : "rgba(22,20,15,0.72)",
              margin: "0 0 22px",
            }}>{topic.blurb}</p>

            <a
              href={topic.href || calendar || window.PERSON.bookingBase}
              target="_blank"
              rel="noreferrer"
              data-cursor="hover"
              style={{
                display: "flex", alignItems: "center", justifyContent: "space-between",
                background: isDark ? accent : fg,
                color: isDark ? "#0e0e10" : "#fff",
                padding: "14px 18px",
                borderRadius: 12,
                textDecoration: "none",
                fontSize: 14, fontWeight: 500, letterSpacing: "-0.005em",
                transition: "transform 200ms ease, opacity 200ms ease",
              }}
              onMouseEnter={(e) => { e.currentTarget.style.transform = "translateY(-1px)"; }}
              onMouseLeave={(e) => { e.currentTarget.style.transform = "translateY(0)"; }}
            >
              <span>Open Google Calendar</span>
              <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
                <path d="M3 8h10M9 4l4 4-4 4" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round"/>
              </svg>
            </a>

            <div style={{
              marginTop: 14, fontSize: 11.5, color: muted, textAlign: "center", letterSpacing: "-0.005em"
            }}>
              You'll land on {(window.PERSON && window.PERSON.firstName) || "the"}'s Google Calendar booking page.
            </div>
          </React.Fragment>
        )}
      </div>
    </div>
  );
}

// Guided "Submit a feature" modal — collects structured input, then opens the
// mail client with everything pre-formatted so submissions are consistent.
function SubmitFeatureModal({ open, onClose, theme, config }) {
  const [mounted, setMounted] = useState(false);
  const cfg = config || {};
  const areas = cfg.areas || ["Creators platform", "Internal tooling", "Website", "Other"];
  const priorities = ["Nice to have", "Important", "Critical"];

  const [form, setForm] = useState({
    title: "", area: areas[0], priority: "Important",
    what: "", why: "", name: "",
  });
  const [status, setStatus] = useState("idle"); // idle | sending | success | error
  const set = (k) => (e) => setForm((f) => ({ ...f, [k]: e.target.value }));
  const setVal = (k, v) => setForm((f) => ({ ...f, [k]: v }));

  // Reset to a clean form whenever the modal is (re)opened.
  useEffect(() => {
    if (open) {
      setStatus("idle");
      setForm({ title: "", area: areas[0], priority: "Important", what: "", why: "", name: "" });
    }
  }, [open]);

  useEffect(() => {
    if (open) requestAnimationFrame(() => setMounted(true));
    else setMounted(false);
  }, [open]);

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

  if (!open) return null;

  const t = theme || {};
  const isDark = t.isDark;
  const accent = t.accent || "#7A5AE0";
  const bg = isDark ? "#0e0e10" : "#ffffff";
  const fg = isDark ? "#f4f3ee" : "#16140f";
  const muted = isDark ? "rgba(244,243,238,0.6)" : "rgba(22,20,15,0.55)";
  const border = isDark ? "rgba(255,255,255,0.10)" : "rgba(0,0,0,0.12)";
  const fieldBg = isDark ? "rgba(255,255,255,0.04)" : "#fafbfc";

  const valid = form.title.trim() && form.what.trim();

  const submit = async () => {
    if (!valid || status === "sending") return;

    // Preferred: POST to a form endpoint (Formspree) → real delivery, no mail app needed.
    if (cfg.endpoint) {
      setStatus("sending");
      try {
        const res = await fetch(cfg.endpoint, {
          method: "POST",
          headers: { "Accept": "application/json", "Content-Type": "application/json" },
          body: JSON.stringify({
            _subject: `[Feature] ${form.title} — ${form.priority}`,
            Feature: form.title,
            Area: form.area,
            Priority: form.priority,
            "What it should do": form.what,
            "Why it matters": form.why || "—",
            "Submitted by": form.name || "—",
          }),
        });
        if (res.ok) {
          setStatus("success");
        } else {
          setStatus("error");
        }
      } catch (e) {
        setStatus("error");
      }
      return;
    }

    // Fallback: mailto (depends on the visitor's mail app).
    const subject = `[Feature] ${form.title} — ${form.priority}`;
    const body =
`NEW FEATURE REQUEST
───────────────────

Feature: ${form.title}
Area: ${form.area}
Priority: ${form.priority}

What it should do
${form.what}

Why it matters / problem it solves
${form.why || "—"}

Submitted by: ${form.name || "—"}`;
    window.location.href = `mailto:${cfg.email}?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`;
    setTimeout(onClose, 400);
  };

  const labelStyle = {
    display: "block", fontSize: 11, letterSpacing: "0.10em", textTransform: "uppercase",
    color: muted, fontWeight: 600, marginBottom: 7,
  };
  const inputStyle = {
    width: "100%", boxSizing: "border-box",
    padding: "11px 13px", fontSize: 14.5, color: fg,
    background: fieldBg, border: `1px solid ${border}`, borderRadius: 10,
    fontFamily: "inherit", outline: "none", transition: "border-color 160ms ease",
  };

  const Chip = ({ active, children, onClick }) => (
    <button
      type="button"
      onClick={onClick}
      data-cursor="hover"
      style={{
        padding: "7px 13px", fontSize: 13, fontWeight: 500,
        borderRadius: 999, cursor: "pointer", fontFamily: "inherit",
        border: `1px solid ${active ? accent : border}`,
        background: active ? accent : "transparent",
        color: active ? "#fff" : fg,
        transition: "all 160ms ease",
      }}
    >{children}</button>
  );

  return (
    <div
      onClick={onClose}
      style={{
        position: "fixed", inset: 0,
        background: isDark ? "rgba(0,0,0,0.72)" : "rgba(20,18,14,0.34)",
        backdropFilter: "blur(8px)", WebkitBackdropFilter: "blur(8px)",
        zIndex: 60, display: "flex", alignItems: "center", justifyContent: "center",
        padding: 24, opacity: mounted ? 1 : 0, transition: "opacity 220ms ease",
      }}
    >
      <div
        onClick={(e) => e.stopPropagation()}
        style={{
          width: "min(520px, 100%)", maxHeight: "calc(100% - 16px)",
          display: "flex", flexDirection: "column",
          background: bg, color: fg, borderRadius: 18,
          border: `1px solid ${border}`,
          boxShadow: isDark ? "0 20px 60px rgba(0,0,0,0.6)" : "0 20px 60px rgba(20,18,14,0.18)",
          overflow: "hidden",
          transform: mounted ? "translateY(0) scale(1)" : "translateY(12px) scale(0.98)",
          opacity: mounted ? 1 : 0,
          transition: "opacity 260ms cubic-bezier(.2,.7,.2,1), transform 320ms cubic-bezier(.2,.7,.2,1)",
        }}
      >
        {/* Header */}
        <div style={{
          display: "flex", alignItems: "flex-start", justifyContent: "space-between",
          gap: 16, padding: "22px 24px 16px", borderBottom: `1px solid ${border}`,
        }}>
          <div>
            <span style={{
              fontSize: 11, letterSpacing: "0.14em", textTransform: "uppercase",
              color: muted, fontWeight: 600, display: "block", marginBottom: 6,
            }}>Product roadmap</span>
            <h3 style={{ fontSize: 22, lineHeight: 1.1, fontWeight: 700, margin: 0, letterSpacing: "-0.02em" }}>
              Submit a feature
            </h3>
          </div>
          <button
            onClick={onClose}
            data-cursor="hover"
            style={{
              border: "none", background: "transparent", color: muted, cursor: "pointer",
              fontSize: 20, lineHeight: 1, padding: 4, borderRadius: 6, flexShrink: 0,
            }}
            aria-label="Close"
          >×</button>
        </div>

        {/* Body */}
        {status === "success" ? (
          <div style={{
            padding: "48px 28px 44px", textAlign: "center",
            display: "flex", flexDirection: "column", alignItems: "center", gap: 14,
          }}>
            <div style={{
              width: 56, height: 56, borderRadius: 999,
              background: accent, color: "#fff",
              display: "flex", alignItems: "center", justifyContent: "center",
            }}>
              <svg width="26" height="26" viewBox="0 0 24 24" fill="none">
                <path d="M5 12.5l4.5 4.5L19 7.5" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"/>
              </svg>
            </div>
            <h3 style={{ fontSize: 22, fontWeight: 700, margin: 0, letterSpacing: "-0.02em" }}>
              Thanks{form.name ? `, ${form.name.split(" ")[0]}` : ""}!
            </h3>
            <p style={{
              fontSize: 14.5, lineHeight: 1.55, margin: 0, maxWidth: 340,
              color: isDark ? "rgba(244,243,238,0.7)" : "rgba(22,20,15,0.65)",
            }}>
              Your feature request reached Luigi. The best ideas make it onto the roadmap.
            </p>
            <button
              onClick={onClose}
              data-cursor="hover"
              style={{
                marginTop: 10, padding: "11px 20px", borderRadius: 11, border: "none",
                background: isDark ? "rgba(255,255,255,0.08)" : "#0e0e10",
                color: "#fff", fontSize: 14, fontWeight: 600, cursor: "pointer", fontFamily: "inherit",
              }}
            >Done</button>
          </div>
        ) : (
        <div style={{ padding: "20px 24px 8px", overflowY: "auto", display: "flex", flexDirection: "column", gap: 18 }}>
          <div>
            <label style={labelStyle}>Feature <span style={{ color: accent }}>*</span></label>
            <input
              style={inputStyle}
              placeholder="Short name — e.g. Bulk message scheduling"
              value={form.title}
              onChange={set("title")}
              onFocus={(e) => e.target.style.borderColor = accent}
              onBlur={(e) => e.target.style.borderColor = border}
            />
          </div>

          <div>
            <label style={labelStyle}>Area</label>
            <div style={{ display: "flex", flexWrap: "wrap", gap: 8 }}>
              {areas.map((a) => (
                <Chip key={a} active={form.area === a} onClick={() => setVal("area", a)}>{a}</Chip>
              ))}
            </div>
          </div>

          <div>
            <label style={labelStyle}>What should it do? <span style={{ color: accent }}>*</span></label>
            <textarea
              style={{ ...inputStyle, minHeight: 78, resize: "vertical", lineHeight: 1.5 }}
              placeholder="Describe the feature in one or two sentences."
              value={form.what}
              onChange={set("what")}
              onFocus={(e) => e.target.style.borderColor = accent}
              onBlur={(e) => e.target.style.borderColor = border}
            />
          </div>

          <div>
            <label style={labelStyle}>Why it matters</label>
            <textarea
              style={{ ...inputStyle, minHeight: 64, resize: "vertical", lineHeight: 1.5 }}
              placeholder="What problem does it solve? Who benefits?"
              value={form.why}
              onChange={set("why")}
              onFocus={(e) => e.target.style.borderColor = accent}
              onBlur={(e) => e.target.style.borderColor = border}
            />
          </div>

          <div>
            <label style={labelStyle}>Priority</label>
            <div style={{ display: "flex", flexWrap: "wrap", gap: 8 }}>
              {priorities.map((p) => (
                <Chip key={p} active={form.priority === p} onClick={() => setVal("priority", p)}>{p}</Chip>
              ))}
            </div>
          </div>

          <div>
            <label style={labelStyle}>Your name</label>
            <input
              style={inputStyle}
              placeholder="So Luigi knows who to thank"
              value={form.name}
              onChange={set("name")}
              onFocus={(e) => e.target.style.borderColor = accent}
              onBlur={(e) => e.target.style.borderColor = border}
            />
          </div>
        </div>
        )}

        {/* Footer (hidden on success) */}
        {status !== "success" && (
        <React.Fragment>
        <div style={{
          padding: "16px 24px 20px", borderTop: `1px solid ${border}`,
          display: "flex", alignItems: "center", gap: 12,
        }}>
          <button
            onClick={submit}
            disabled={!valid || status === "sending"}
            data-cursor="hover"
            style={{
              flex: 1, display: "flex", alignItems: "center", justifyContent: "center", gap: 8,
              padding: "13px 18px", borderRadius: 12, border: "none",
              background: (valid && status !== "sending") ? (isDark ? accent : "#0e0e10") : (isDark ? "rgba(255,255,255,0.08)" : "rgba(0,0,0,0.10)"),
              color: (valid && status !== "sending") ? "#fff" : muted,
              fontSize: 14, fontWeight: 600, letterSpacing: "-0.005em",
              cursor: (valid && status !== "sending") ? "pointer" : "not-allowed", fontFamily: "inherit",
              transition: "transform 180ms ease, background 180ms ease",
            }}
            onMouseEnter={(e) => { if (valid && status !== "sending") e.currentTarget.style.transform = "translateY(-1px)"; }}
            onMouseLeave={(e) => { e.currentTarget.style.transform = "translateY(0)"; }}
          >
            <span>{status === "sending" ? "Sending…" : "Send to Luigi"}</span>
            {status !== "sending" && (
              <svg width="15" height="15" viewBox="0 0 16 16" fill="none">
                <path d="M3 8h10M9 4l4 4-4 4" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
              </svg>
            )}
          </button>
        </div>
        <div style={{
          padding: "0 24px 18px", fontSize: 11.5,
          color: status === "error" ? "#e0533d" : muted,
          textAlign: "center", letterSpacing: "-0.005em",
        }}>
          {status === "error"
            ? "Something went wrong — please try again in a moment."
            : "Sent straight to Luigi — no email app needed."}
        </div>
        </React.Fragment>
        )}
      </div>
    </div>
  );
}

Object.assign(window, { useReveal, Stagger, BookingModal, SubmitFeatureModal });
