// Network map and waitlist form.

const CITIES = [
  { id: "sea", name: "Seattle",       region: "WA", status: "available", lat: 47.6062, lng: -122.3321, nodes: 0, demand: "High",      node: "P1" },
  { id: "sf",  name: "San Francisco", region: "CA", status: "available", lat: 37.7749, lng: -122.4194, nodes: 0, demand: "High",      node: "P1" },
  { id: "la",  name: "Los Angeles",   region: "CA", status: "reserved",  lat: 34.0522, lng: -118.2437, nodes: 4, demand: "Very High", node: "P2" },
  { id: "phx", name: "Phoenix",       region: "AZ", status: "pending",   lat: 33.4484, lng: -112.0740, nodes: 0, demand: "Moderate",  node: "P1" },
  { id: "den", name: "Denver",        region: "CO", status: "available", lat: 39.7392, lng: -104.9903, nodes: 0, demand: "Moderate",  node: "P1" },
  { id: "aus", name: "Austin",        region: "TX", status: "pending",   lat: 30.2672, lng: -97.7431,  nodes: 1, demand: "High",      node: "P2" },
  { id: "dal", name: "Dallas",        region: "TX", status: "available", lat: 32.7767, lng: -96.7970,  nodes: 0, demand: "High",      node: "P2" },
  { id: "hou", name: "Houston",       region: "TX", status: "available", lat: 29.7604, lng: -95.3698,  nodes: 0, demand: "Moderate",  node: "P2" },
  { id: "chi", name: "Chicago",       region: "IL", status: "pending",   lat: 41.8781, lng: -87.6298,  nodes: 1, demand: "High",      node: "P2" },
  { id: "atl", name: "Atlanta",       region: "GA", status: "reserved",  lat: 33.7490, lng: -84.3880,  nodes: 3, demand: "High",      node: "P1" },
  { id: "mia", name: "Miami",         region: "FL", status: "pending",   lat: 25.7617, lng: -80.1918,  nodes: 1, demand: "High",      node: "P1" },
  { id: "dc",  name: "Washington",    region: "DC", status: "reserved",  lat: 38.9072, lng: -77.0369,  nodes: 2, demand: "Very High", node: "P2" },
  { id: "nyc", name: "New York",      region: "NY", status: "reserved",  lat: 40.7128, lng: -74.0060,  nodes: 5, demand: "Very High", node: "P1" },
  { id: "bos", name: "Boston",        region: "MA", status: "available", lat: 42.3601, lng: -71.0589,  nodes: 0, demand: "Very High", node: "P2" },
];

const STATUS_TONE = {
  available: { dot: "#2EA84F", color: "#2EA84F", label: "Available" },
  pending:   { dot: "#F5A524", color: "#B9750A", label: "Pending"   },
  reserved:  { dot: "#E5484D", color: "#E5484D", label: "Reserved"  },
};

const TWENTY_MILES_M = 32186.9;

// Build the HTML for a single map pin (used inside L.divIcon).
const pinHtml = (city, selected) => {
  const t = STATUS_TONE[city.status];
  return `
    <div class="pyrra-pin ${selected ? "is-selected" : ""}" data-city="${city.id}">
      <div class="pyrra-pin__name">
        <span class="pyrra-pin__dot" style="background:${t.dot}"></span>
        ${city.name}
      </div>
      <div class="pyrra-pin__row">
        <span class="pyrra-pin__status" style="color:${t.color}">${t.label}</span>
        <span class="pyrra-pin__nodes">${city.nodes} live</span>
      </div>
    </div>`;
};

const NetworkMap = ({ selectedId = "nyc", onSelect = () => {}, showSidebar = true, onReserve }) => {
  const containerRef = React.useRef(null);
  const mapRef = React.useRef(null);
  const markersRef = React.useRef({});
  const ringsRef = React.useRef({});
  const onSelectRef = React.useRef(onSelect);
  React.useEffect(() => { onSelectRef.current = onSelect; }, [onSelect]);

  // Init Leaflet once
  React.useEffect(() => {
    if (!containerRef.current || mapRef.current || typeof L === "undefined") return;

    const map = L.map(containerRef.current, {
      zoomControl: false,
      attributionControl: false,
      scrollWheelZoom: false,
      doubleClickZoom: true,
      boxZoom: false,
      keyboard: false,
      dragging: true,
      worldCopyJump: false,
    });

    // Fit to continental US
    map.fitBounds([[24.5, -125], [49.5, -66.9]], { padding: [10, 10] });

    L.tileLayer("https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png", {
      subdomains: "abcd",
      minZoom: 3,
      maxZoom: 9,
      detectRetina: true,
    }).addTo(map);

    // Add 20-mile territory rings (real geographic radius)
    CITIES.forEach((c) => {
      const tone = STATUS_TONE[c.status];
      const ring = L.circle([c.lat, c.lng], {
        radius: TWENTY_MILES_M,
        color: tone.color,
        weight: c.id === selectedId ? 2 : 1,
        opacity: c.id === selectedId ? 0.75 : 0.35,
        fillColor: tone.dot,
        fillOpacity: c.id === selectedId ? 0.1 : 0.06,
        dashArray: c.id === selectedId ? null : "3,3",
        interactive: false,
      }).addTo(map);
      ringsRef.current[c.id] = ring;
    });

    // Add pin markers
    CITIES.forEach((c) => {
      const icon = L.divIcon({
        html: pinHtml(c, c.id === selectedId),
        className: "pyrra-pin-icon",
        iconSize: null,
        iconAnchor: [0, 0],
      });
      const marker = L.marker([c.lat, c.lng], { icon, riseOnHover: true, keyboard: false }).addTo(map);
      marker.on("click", () => onSelectRef.current(c.id));
      markersRef.current[c.id] = marker;
    });

    // (Zoom and recenter controls removed — map is presentational chrome here.)

    mapRef.current = map;
    // Recalc size once after mount (Leaflet needs this if container had no size at init)
    setTimeout(() => map.invalidateSize(), 50);

    return () => {
      map.remove();
      mapRef.current = null;
      markersRef.current = {};
      ringsRef.current = {};
    };
  }, []);

  // Re-render pin + ring styles when selectedId changes
  React.useEffect(() => {
    Object.entries(markersRef.current).forEach(([id, marker]) => {
      const city = CITIES.find((c) => c.id === id);
      if (!city) return;
      const el = marker.getElement();
      if (!el) return;
      el.innerHTML = pinHtml(city, id === selectedId);
      if (id === selectedId) {
        marker.setZIndexOffset(1000);
      } else {
        marker.setZIndexOffset(0);
      }
    });
    Object.entries(ringsRef.current).forEach(([id, ring]) => {
      const isSel = id === selectedId;
      ring.setStyle({
        weight: isSel ? 2 : 1,
        opacity: isSel ? 0.75 : 0.35,
        fillOpacity: isSel ? 0.1 : 0.06,
        dashArray: isSel ? null : "3,3",
      });
    });
  }, [selectedId]);

  const sel = CITIES.find((c) => c.id === selectedId) || CITIES[0];
  const t = STATUS_TONE[sel.status];
  const reservable = sel.status !== "reserved";
  const totalLive = CITIES.reduce((a, c) => a + c.nodes, 0);
  const cityCount = CITIES.filter((c) => c.nodes > 0).length;

  return (
    <div className={`pyrra-network ${showSidebar ? "" : "pyrra-network--solo"}`}>
      <div className="pyrra-network__map">
        <div ref={containerRef} className="pyrra-network__leaflet" />
      </div>
      {showSidebar ? (
        <aside className="pyrra-network__side">
          <Eyebrow>Selected City</Eyebrow>
          <h3>{sel.name}, {sel.region}</h3>
          <span className="pyrra-network__status-pill" style={{ borderColor: t.color, color: t.color }}>{t.label}</span>
          <dl>
            <div><dt>Status</dt><dd>{t.label}</dd></div>
            <div><dt>Live Nodes</dt><dd>{sel.nodes}</dd></div>
            <div><dt>Territory</dt><dd>20-mile radius</dd></div>
            <div><dt>Node Type</dt><dd>{sel.node}</dd></div>
            <div><dt>Est. Demand</dt><dd>{sel.demand}</dd></div>
          </dl>
          <div className="pyrra-network__order">
            <h4>{reservable ? "Pre-order your node" : "This city is taken"}</h4>
            <p>
              {reservable
                ? "Secure this 20-mile inference territory with a $5000 deposit. The remaining balance is due within 30 days to hold your location."
                : `${sel.name} has ${sel.nodes} live ${sel.nodes === 1 ? "node" : "nodes"} on the network. Join the waitlist to be notified when adjacent territories open up.`}
            </p>
            <div className="pyrra-network__deposit">
              <span className="pyrra-network__deposit-amt">$5000</span>
              <span className="pyrra-network__deposit-cur">USD Deposit</span>
            </div>
            <Button
              size="md"
              style={{ width: "100%" }}
              onClick={() => onReserve && onReserve(sel)}
            >
              {reservable ? `Reserve ${sel.name}` : "Join Waitlist"}
            </Button>
            <small>Fully refundable within 7 days</small>
          </div>
        </aside>
      ) : null}
    </div>
  );
};

// ---- Form submission endpoint (Web3Forms) ----------------------------------
// Register contact@pyrra.xyz at web3forms.com to obtain the access key.
// The destination email is configured in the Web3Forms dashboard — it is never
// present in this source file.
const FORM_KEY = "REPLACE_WITH_WEB3FORMS_ACCESS_KEY";

const postToWeb3Forms = async (payload) => {
  const res = await fetch("https://api.web3forms.com/submit", {
    method: "POST",
    headers: { "Content-Type": "application/json", Accept: "application/json" },
    body: JSON.stringify({ access_key: FORM_KEY, ...payload }),
  });
  if (!res.ok) throw new Error("submission_failed");
};

// ---- Waitlist form ---------------------------------------------------------

const WaitlistForm = ({ prefill = {} }) => {
  const [form, setForm] = React.useState({
    name: "",
    email: "",
    company: "",
    city: prefill.city || "",
    address: "",
    notes: "",
    ...prefill,
  });
  const [node, setNode] = React.useState(prefill.node || "P1");
  const [agree, setAgree] = React.useState(false);
  const [submitted, setSubmitted] = React.useState(false);
  const [submitting, setSubmitting] = React.useState(false);
  const [submitError, setSubmitError] = React.useState(null);

  // Apply prefill when it changes (e.g. when navigating from a Reserve button)
  React.useEffect(() => {
    if (prefill && (prefill.city || prefill.node)) {
      setForm((f) => ({ ...f, city: prefill.city || f.city }));
      if (prefill.node) setNode(prefill.node);
    }
  }, [prefill.city, prefill.node]);

  const update = (k) => (e) => setForm((f) => ({ ...f, [k]: e.target.value }));
  const valid = form.name.trim() && /\S+@\S+\.\S+/.test(form.email) && form.city.trim() && form.address.trim() && agree;

  const submit = async (e) => {
    e.preventDefault();
    if (!valid || submitting) return;
    setSubmitting(true);
    setSubmitError(null);
    try {
      await postToWeb3Forms({
        subject: `New Waitlist Registration – ${form.city}`,
        replyto: form.email,
        "Full Name": form.name,
        "Email": form.email,
        "Company": form.company || "—",
        "City to Reserve": form.city,
        "Install Address": form.address,
        "Preferred Node": node,
        "Site Notes": form.notes || "—",
      });
      setSubmitted(true);
    } catch {
      setSubmitError("Something went wrong. Please try again.");
    } finally {
      setSubmitting(false);
    }
  };

  if (submitted) {
    return (
      <div className="pyrra-waitlist">
        <div className="pyrra-waitlist__success">
          <div className="pyrra-waitlist__success-mark">
            <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
          </div>
          <Eyebrow>You're on the map</Eyebrow>
          <h2>Welcome to the Pyrra waitlist, {form.name.split(" ")[0] || "neighbor"}.</h2>
          <p>
            We've logged your reservation for <strong>{form.city}</strong> with a <strong>{node}</strong> node. Our team
            will reach out within 2 business days to begin site qualification and deposit coordination.
          </p>
          <div className="pyrra-waitlist__success-meta">
            <div><strong>City</strong>{form.city}</div>
            <div><strong>Install Address</strong>{form.address}</div>
            <div><strong>Preferred Node</strong>{node}</div>
            <div><strong>Contact</strong>{form.email}</div>
            <div><strong>Status</strong>Pending qualification</div>
          </div>
        </div>
        <aside className="pyrra-waitlist__side">
          <div className="pyrra-waitlist__benefit">
            <div className="pyrra-waitlist__benefit-icon"><IconDollar size={28} /></div>
            <div>
              <h4>Next: $5000 Deposit</h4>
              <p>Once you're qualified we'll send a secure link to place your fully refundable $5000 deposit.</p>
            </div>
          </div>
          <hr />
          <div className="pyrra-waitlist__benefit">
            <div className="pyrra-waitlist__benefit-icon"><IconCalendar size={28} /></div>
            <div>
              <h4>30-Day Activation</h4>
              <p>The remaining balance is due within 30 days of approval to lock in your territory.</p>
            </div>
          </div>
          <hr />
          <p className="pyrra-waitlist__contact"><strong>Questions in the meantime?</strong><br/>Reach our partnerships team via the <a href="#/contact">contact form</a>.</p>
        </aside>
      </div>
    );
  }

  return (
    <div className="pyrra-waitlist">
      <form className="pyrra-waitlist__form" onSubmit={submit}>
        <h2>Join the Pyrra Waitlist</h2>
        <p className="pyrra-waitlist__sub">Tell us about your location and preferred node.</p>

        <label>Full Name</label>
        <input className="pyrra-input" placeholder="Enter your full name" value={form.name} onChange={update("name")} required />

        <label>Email</label>
        <input className="pyrra-input" type="email" placeholder="name@company.com" value={form.email} onChange={update("email")} required />

        <div className="pyrra-waitlist__row">
          <div>
            <label>Company / Group</label>
            <input className="pyrra-input" placeholder="Your company or organization" value={form.company} onChange={update("company")} />
          </div>
          <div>
            <label>City to Reserve</label>
            <input className="pyrra-input" placeholder="e.g., Austin, TX" value={form.city} onChange={update("city")} required />
          </div>
        </div>

        <label>Exact Install Address</label>
        <input className="pyrra-input" placeholder="Street, building, unit / room — where the node will live" value={form.address} onChange={update("address")} required />
        <small className="pyrra-waitlist__hint">The specific location our engineers will site-survey. Include building, floor, and mechanical room if known.</small>

        <label>Preferred Node</label>
        <div className="pyrra-waitlist__radios">
          <button type="button" className={`pyrra-radio ${node === "P1" ? "is-checked" : ""}`} onClick={() => setNode("P1")}>
            <span className="pyrra-radio__ring" />
            <span><strong>P1 – Primary Node</strong><small>High-capacity primary inference.</small></span>
          </button>
          <button type="button" className={`pyrra-radio ${node === "P2" ? "is-checked" : ""}`} onClick={() => setNode("P2")}>
            <span className="pyrra-radio__ring" />
            <span><strong>P2 – Secondary Node</strong><small>Redundant, distributed inference.</small></span>
          </button>
        </div>

        <label>Tell Us About Your Site</label>
        <textarea className="pyrra-input pyrra-textarea" rows="4" value={form.notes} onChange={update("notes")} placeholder="Share details about your site, power availability, zoning, timelines, and any other relevant information." />

        <label className="pyrra-checkbox">
          <input type="checkbox" checked={agree} onChange={(e) => setAgree(e.target.checked)} />
          I agree to the Pyrra <a href="#" onClick={(e) => e.preventDefault()}>Terms of Service</a> and <a href="#" onClick={(e) => e.preventDefault()}>Privacy Policy</a>.
        </label>

        <Button size="lg" style={{ width: "100%" }} disabled={!valid || submitting} onClick={submit}>
          {submitting ? "Submitting…" : "Submit & Join Waitlist"}
        </Button>
        {submitError && <p style={{ color: "var(--status-reserved)", fontSize: "14px", margin: "4px 0 0" }}>{submitError}</p>}
        <div className="pyrra-waitlist__lock"><IconLock size={14} /> Your information is secure and will never be shared.</div>
      </form>

      <aside className="pyrra-waitlist__side">
        <div className="pyrra-waitlist__benefit">
          <div className="pyrra-waitlist__benefit-icon"><IconDollar size={28} /></div>
          <div>
            <h4>$5000 Deposit to<br/>Claim Your Inference Zone</h4>
            <p>A fully refundable $5000 deposit secures your place on the map while we qualify your location and infrastructure.</p>
          </div>
        </div>
        <hr />
        <div className="pyrra-waitlist__benefit">
          <div className="pyrra-waitlist__benefit-icon"><IconCalendar size={28} /></div>
          <div>
            <h4>Balance Due Within<br/>30 Days of Approval</h4>
            <p>Once your site is approved, the remaining balance is due within 30 days to activate your node reservation.</p>
          </div>
        </div>
        <hr />
        <div className="pyrra-waitlist__benefit">
          <div className="pyrra-waitlist__benefit-icon"><IconShield size={28} /></div>
          <div>
            <h4>Priority Access<br/>on the Network</h4>
            <p>Early reservations receive priority build sequencing and go-live readiness support.</p>
          </div>
        </div>
        <hr />
        <p className="pyrra-waitlist__contact"><strong>Have questions?</strong><br/>Reach our team via the <a href="#/contact">contact form</a>.</p>
      </aside>
    </div>
  );
};

Object.assign(window, { NetworkMap, WaitlistForm, CITIES });

// ---- Contact form ---------------------------------------------------------
// Submissions are routed to the configured contact inbox by the backend (kept
// out of source on purpose so the address is not published in markup).
function ContactForm() {
  const [form, setForm] = React.useState({
    name: "", email: "", company: "", topic: "Partnerships", message: "",
  });
  const [agree, setAgree] = React.useState(false);
  const [submitted, setSubmitted] = React.useState(false);
  const [submitting, setSubmitting] = React.useState(false);
  const [submitError, setSubmitError] = React.useState(null);
  const update = (k) => (e) => setForm((f) => ({ ...f, [k]: e.target.value }));
  const valid =
    form.name.trim() &&
    /\S+@\S+\.\S+/.test(form.email) &&
    form.message.trim().length >= 10 &&
    agree;

  const submit = async (e) => {
    e.preventDefault();
    if (!valid || submitting) return;
    setSubmitting(true);
    setSubmitError(null);
    try {
      await postToWeb3Forms({
        subject: `Contact Form – ${form.topic}`,
        replyto: form.email,
        "Full Name": form.name,
        "Email": form.email,
        "Company": form.company || "—",
        "Topic": form.topic,
        "Message": form.message,
      });
      setSubmitted(true);
    } catch {
      setSubmitError("Something went wrong. Please try again.");
    } finally {
      setSubmitting(false);
    }
  };

  if (submitted) {
    return (
      <div className="pyrra-waitlist">
        <div className="pyrra-waitlist__success">
          <div className="pyrra-waitlist__success-mark">
            <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
          </div>
          <Eyebrow>Message received</Eyebrow>
          <h2>Thanks, {form.name.split(" ")[0] || "there"}. We'll be in touch.</h2>
          <p>
            A Pyrra team member typically responds within two business days. We'll reply to{" "}
            <strong>{form.email}</strong>. If your question is time-sensitive, mention that in your follow-up.
          </p>
          <div className="pyrra-waitlist__success-meta">
            <div><strong>Topic</strong>{form.topic}</div>
            <div><strong>Contact</strong>{form.email}</div>
            {form.company ? <div><strong>Company</strong>{form.company}</div> : null}
            <div><strong>Status</strong>Received</div>
          </div>
        </div>
        <aside className="pyrra-waitlist__side">
          <div className="pyrra-waitlist__benefit">
            <div className="pyrra-waitlist__benefit-icon"><IconShield size={28} /></div>
            <div>
              <h4>Looking for a site survey?</h4>
              <p>If your message was about deploying a node, head to the waitlist to start the qualification flow in parallel.</p>
            </div>
          </div>
        </aside>
      </div>
    );
  }

  return (
    <div className="pyrra-waitlist">
      <form className="pyrra-waitlist__form" onSubmit={submit}>
        <h2>Talk to Pyrra</h2>
        <p className="pyrra-waitlist__sub">Send us a message. We read every one.</p>

        <label>Full Name</label>
        <input className="pyrra-input" placeholder="Enter your full name" value={form.name} onChange={update("name")} required />

        <label>Email</label>
        <input className="pyrra-input" type="email" placeholder="name@company.com" value={form.email} onChange={update("email")} required />

        <div className="pyrra-waitlist__row">
          <div>
            <label>Company / Organization</label>
            <input className="pyrra-input" placeholder="Optional" value={form.company} onChange={update("company")} />
          </div>
          <div>
            <label>Topic</label>
            <select className="pyrra-input" value={form.topic} onChange={update("topic")}>
              <option>Partnerships</option>
              <option>Building owner / site survey</option>
              <option>Press</option>
              <option>Investor relations</option>
              <option>General inquiry</option>
            </select>
          </div>
        </div>

        <label>Message</label>
        <textarea className="pyrra-input pyrra-textarea" rows="5" value={form.message} onChange={update("message")} placeholder="Tell us a bit about what you're working on, your timeline, and how we can help." required />

        <label className="pyrra-checkbox">
          <input type="checkbox" checked={agree} onChange={(e) => setAgree(e.target.checked)} />
          I agree to the Pyrra <a href="#" onClick={(e) => e.preventDefault()}>Terms of Service</a> and <a href="#" onClick={(e) => e.preventDefault()}>Privacy Policy</a>.
        </label>

        <Button size="lg" style={{ width: "100%" }} disabled={!valid || submitting} onClick={submit}>
          {submitting ? "Sending…" : "Send Message"}
        </Button>
        {submitError && <p style={{ color: "var(--status-reserved)", fontSize: "14px", margin: "4px 0 0" }}>{submitError}</p>}
        <div className="pyrra-waitlist__lock"><IconLock size={14} /> Your information is secure and will never be shared.</div>
      </form>

      <aside className="pyrra-waitlist__side">
        <div className="pyrra-waitlist__benefit">
          <div className="pyrra-waitlist__benefit-icon"><IconUsers size={28} /></div>
          <div>
            <h4>Partnerships</h4>
            <p>Building owners, operators, developers, and integrators who want to deploy or distribute Pyrra Nodes.</p>
          </div>
        </div>
        <hr />
        <div className="pyrra-waitlist__benefit">
          <div className="pyrra-waitlist__benefit-icon"><IconBuilding size={28} /></div>
          <div>
            <h4>Site qualification</h4>
            <p>Wondering if your building qualifies? Pick "Building owner / site survey" in the topic dropdown.</p>
          </div>
        </div>
        <hr />
        <div className="pyrra-waitlist__benefit">
          <div className="pyrra-waitlist__benefit-icon"><IconCalendar size={28} /></div>
          <div>
            <h4>Response time</h4>
            <p>A Pyrra team member typically replies within two business days.</p>
          </div>
        </div>
      </aside>
    </div>
  );
}

Object.assign(window, { ContactForm });
