// Receivers — driver-facing search across 33K+ delivery docks.
//
// The data is already in receiver_locations (Walmart, Home Depot, Lowe's,
// Costco, Target, Kroger, Sam's, Aldi, Safeway, Publix, Amazon, Trader
// Joe's, BJ's, Whole Foods, Wegmans, Lineage, Americold). This page is
// the front door — find your dock by brand, state, or city.
//
// Performance: 33K rows is too many to render at once. We default to a
// brand-grid landing view; clicking a brand loads up to 200 locations
// for that brand (filterable by state). Real production would paginate
// with cursors, but 200/brand is enough for v1 and Postgres handles
// it instantly.

const { useState: useStateRcv, useEffect: useEffectRcv, useMemo: useMemoRcv, useRef: useRefRcv } = React;

const RCV_BRAND_LABEL = {
  "walmart":            "Walmart",
  "sams-club":          "Sam's Club",
  "target":             "Target",
  "costco":             "Costco",
  "home-depot":         "Home Depot",
  "lowes":              "Lowe's",
  "bjs":                "BJ's Wholesale",
  "kroger":             "Kroger",
  "publix":             "Publix",
  "aldi":               "Aldi",
  "whole-foods":        "Whole Foods",
  "trader-joes":        "Trader Joe's",
  "safeway":            "Safeway / Albertsons",
  "wegmans":            "Wegmans",
  "amazon":             "Amazon FC / Sortation",
  "lineage":            "Lineage Logistics",
  "americold":          "Americold",
  "us-cold":            "US Cold Storage",
  "burris":             "Burris Logistics",
  "newcold":            "NewCold",
  "realcold":           "RealCold",
  "walgreens":          "Walgreens",
  "cvs":                "CVS",
  "dollar-general":     "Dollar General",
  "family-dollar":      "Family Dollar",
  "dollar-tree":        "Dollar Tree",
  "tractor-supply":     "Tractor Supply",
  "best-buy":           "Best Buy",
  "ikea":               "IKEA",
  "menards":            "Menards",
  "ace-hardware":       "Ace Hardware",
  "autozone":           "AutoZone",
  "oreilly":            "O'Reilly Auto Parts",
};

const RCV_BRAND_COLOR = {
  "walmart":        "#0071ce",
  "sams-club":      "#0066b2",
  "target":         "#cc0000",
  "costco":         "#005DAA",
  "home-depot":     "#F96302",
  "lowes":          "#012169",
  "bjs":            "#D40029",
  "kroger":         "#00529B",
  "publix":         "#007A33",
  "aldi":           "#002F87",
  "whole-foods":    "#00674B",
  "trader-joes":    "#D9131F",
  "safeway":        "#E11B22",
  "wegmans":        "#003F2D",
  "amazon":         "#FF9900",
  "lineage":        "#005EB8",
  "americold":      "#0072CE",
  "us-cold":        "#1E4D8C",
  "burris":         "#1F3864",
  "newcold":        "#0E7C7B",
  "realcold":       "#3F88C5",
  "walgreens":      "#E31837",
  "cvs":            "#CC0000",
  "dollar-general": "#FFC72C",
  "family-dollar":  "#D71921",
  "dollar-tree":    "#3D8B40",
  "tractor-supply": "#C8102E",
  "best-buy":       "#0046BE",
  "ikea":           "#0058A3",
  "menards":        "#1F8B4C",
  "ace-hardware":   "#E4002B",
  "autozone":       "#F47B20",
  "oreilly":        "#01643F",
};

// US state name-code map (lazy import — small enough to inline)
const RCV_STATES = [
  ["", "All states"],
  ["AL","Alabama"],["AK","Alaska"],["AZ","Arizona"],["AR","Arkansas"],["CA","California"],
  ["CO","Colorado"],["CT","Connecticut"],["DE","Delaware"],["FL","Florida"],["GA","Georgia"],
  ["HI","Hawaii"],["ID","Idaho"],["IL","Illinois"],["IN","Indiana"],["IA","Iowa"],
  ["KS","Kansas"],["KY","Kentucky"],["LA","Louisiana"],["ME","Maine"],["MD","Maryland"],
  ["MA","Massachusetts"],["MI","Michigan"],["MN","Minnesota"],["MS","Mississippi"],
  ["MO","Missouri"],["MT","Montana"],["NE","Nebraska"],["NV","Nevada"],["NH","New Hampshire"],
  ["NJ","New Jersey"],["NM","New Mexico"],["NY","New York"],["NC","North Carolina"],
  ["ND","North Dakota"],["OH","Ohio"],["OK","Oklahoma"],["OR","Oregon"],["PA","Pennsylvania"],
  ["RI","Rhode Island"],["SC","South Carolina"],["SD","South Dakota"],["TN","Tennessee"],
  ["TX","Texas"],["UT","Utah"],["VT","Vermont"],["VA","Virginia"],["WA","Washington"],
  ["WV","West Virginia"],["WI","Wisconsin"],["WY","Wyoming"],
];

function ReceiversMap({ rows }) {
  const ref = React.useRef(null);
  const mapRef = React.useRef(null);

  useEffectRcv(() => {
    if (!ref.current || !window.L || !rows || rows.length === 0) return;
    if (!mapRef.current) {
      mapRef.current = window.L.map(ref.current, {
        zoomControl: true, scrollWheelZoom: true, attributionControl: true,
      }).setView([rows[0].lat, rows[0].lng], 5);
      window.L.tileLayer(
        "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
        { attribution: "© OpenStreetMap", maxZoom: 18 }
      ).addTo(mapRef.current);
    }
    mapRef.current.eachLayer(l => { if ((l.options && l.options.pane === "markerPane") || l._icon) mapRef.current.removeLayer(l); });
    const bounds = [];
    rows.slice(0, 500).forEach(r => {   // safety cap on map markers
      const c = RCV_BRAND_COLOR[r.brand] || "#444";
      const icon = window.L.divIcon({
        className: "rcv-pin",
        html: `<span style="display:inline-block;width:10px;height:10px;border-radius:50%;background:${c};border:1.5px solid #fff;box-shadow:0 0 0 1px rgba(0,0,0,0.25)"></span>`,
        iconSize: [12, 12], iconAnchor: [6, 6],
      });
      const marker = window.L.marker([r.lat, r.lng], { icon }).addTo(mapRef.current);
      const addr = [r.address, r.city, r.state, r.postcode].filter(Boolean).join(", ");
      marker.bindPopup(
        `<div style="min-width:200px">
           <div style="font-family:var(--font-serif);font-size:14px;font-weight:600">${(r.name || RCV_BRAND_LABEL[r.brand] || r.brand).replace(/'/g, "&#39;")}</div>
           <div style="font-size:11px;color:#666;margin-top:2px">${addr || `${r.lat.toFixed(4)}°, ${r.lng.toFixed(4)}°`}</div>
           <a target="_blank" rel="noopener noreferrer"
              href="https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(addr || `${r.lat},${r.lng}`)}"
              style="display:inline-block;margin-top:6px;font-family:var(--font-mono);font-size:10px;letter-spacing:0.1em;text-transform:uppercase;color:#0066B3;text-decoration:none">
             Open in Maps ↗
           </a>
         </div>`
      );
      bounds.push([r.lat, r.lng]);
    });
    if (bounds.length > 1) mapRef.current.fitBounds(bounds, { padding: [24, 24] });
    setTimeout(() => mapRef.current && mapRef.current.invalidateSize(), 50);
  }, [rows]);

  useEffectRcv(() => () => {
    if (mapRef.current) { mapRef.current.remove(); mapRef.current = null; }
  }, []);

  return <div ref={ref} style={{ width: "100%", height: 460, borderRadius: 8, overflow: "hidden", border: "1px solid var(--rule)" }} />;
}

// =============================================================
// RECEIVERS RADAR — focal hero for /#/receivers. Renders every
// delivery dock we have a position for, color-coded by brand,
// in a single dark-map view with marker clustering. Anonymous
// visitors see clusters and totals; signed-in users get full
// popups with brand + city + map deep-link.
// =============================================================

function ReceiversRadar({ user, onNav, brandLabels, brandColors }) {
  const mapRef = useRefRcv(null);
  const containerRef = useRefRcv(null);
  const clusterRef = useRefRcv(null);
  const lcRef = useRefRcv(null);
  const [docks, setDocks] = useStateRcv([]);
  const [progress, setProgress] = useStateRcv({ loaded: 0, total: 0 });
  const [activeBrand, setActiveBrand] = useStateRcv(null);
  const [loading, setLoading] = useStateRcv(true);

  const isAuthed = !!user && !!user.email;

  // Paginated fetch: PostgREST caps at 1000 rows per request, and we want
  // ALL 86K+ docks. Pull in chunks of 1000 via Range header until done.
  // Render incrementally so the user sees the radar fill in.
  useEffectRcv(() => {
    let alive = true;
    if (!window.SI_DB || !window.SI_DB.SUPABASE_URL) return;
    (async () => {
      const url = `${window.SI_DB.SUPABASE_URL}/rest/v1/receiver_locations?select=brand,lat,lng,name,city,state&order=brand.asc`;
      const PUB_KEY = "sb_publishable_0zNSihwdiVEKHD_HQj7Oqw_wEGGPFf6";
      const PAGE = 1000;
      let offset = 0;
      const all = [];
      // First, get the count cheaply.
      try {
        const countRes = await fetch(`${window.SI_DB.SUPABASE_URL}/rest/v1/receiver_locations?select=*`, {
          headers: { apikey: PUB_KEY, Authorization: `Bearer ${PUB_KEY}`, Range: "0-0", Prefer: "count=exact" },
        });
        const cr = countRes.headers.get("content-range") || "";
        const m = cr.match(/\/(\d+)/);
        const total = m ? parseInt(m[1], 10) : 0;
        if (alive) setProgress({ loaded: 0, total });
      } catch {}
      while (alive) {
        const res = await fetch(url, {
          headers: {
            apikey: PUB_KEY,
            Authorization: `Bearer ${PUB_KEY}`,
            Range: `${offset}-${offset + PAGE - 1}`,
            "Range-Unit": "items",
          },
        });
        if (!res.ok) break;
        const rows = await res.json();
        if (!Array.isArray(rows) || rows.length === 0) break;
        all.push(...rows);
        if (alive) {
          setDocks(all.slice());
          setProgress(p => ({ loaded: all.length, total: p.total || all.length }));
        }
        if (rows.length < PAGE) break;
        offset += PAGE;
      }
      if (alive) setLoading(false);
    })();
    return () => { alive = false; };
  }, []);

  // Mount-only: build the map.
  useEffectRcv(() => {
    if (!containerRef.current || !window.L || mapRef.current) return;
    const map = window.L.map(containerRef.current, {
      zoomControl: false, scrollWheelZoom: false, attributionControl: true,
      fadeAnimation: false, zoomAnimation: false, markerZoomAnimation: false,
      worldCopyJump: false, minZoom: 3, maxZoom: 14,
      maxBounds: [[10, -175], [72, -50]],
      maxBoundsViscosity: 1.0,
    }).setView([39.5, -98.5], 4);
    window.L.tileLayer(
      "https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png",
      {
        attribution: "© OpenStreetMap · © CARTO", subdomains: "abcd", maxZoom: 14,
        noWrap: true, bounds: [[-90, -180], [90, 180]],
      }
    ).addTo(map);
    window.L.control.zoom({ position: "bottomright" }).addTo(map);
    mapRef.current = map;
    setTimeout(() => map.invalidateSize(), 80);
    return () => { map.remove(); mapRef.current = null; };
  }, []);

  // Memoize the filtered set so the cluster doesn't rebuild on unrelated renders.
  const filtered = useMemoRcv(() =>
    docks.filter(d => !activeBrand || d.brand === activeBrand),
    [docks, activeBrand]);

  // Layer build — uses Leaflet.markercluster for performance with tens of thousands of markers.
  useEffectRcv(() => {
    const map = mapRef.current;
    if (!map || !window.L || !window.L.markerClusterGroup) return;

    // Tear down previous cluster group cleanly.
    if (clusterRef.current) {
      map.removeLayer(clusterRef.current);
      clusterRef.current = null;
    }

    const cluster = window.L.markerClusterGroup({
      chunkedLoading: true, chunkInterval: 80, chunkDelay: 30,
      showCoverageOnHover: false,
      // Color the cluster bubbles by the dominant brand inside.
      iconCreateFunction: function(c) {
        const childMarkers = c.getAllChildMarkers();
        const brandCount = {};
        childMarkers.forEach(m => {
          const b = m.options._brand;
          if (b) brandCount[b] = (brandCount[b] || 0) + 1;
        });
        const dominant = Object.entries(brandCount).sort((a,b) => b[1]-a[1])[0];
        const color = dominant ? (brandColors[dominant[0]] || "#444") : "#444";
        const count = c.getChildCount();
        const size = count > 1000 ? 56 : count > 250 ? 46 : count > 50 ? 38 : 30;
        const html = `
          <div class="rr-cluster" style="
            width:${size}px;height:${size}px;
            background:${color};
            box-shadow:0 0 0 4px ${color}33, 0 0 0 8px ${color}1a;">
            <span>${count.toLocaleString()}</span>
          </div>`;
        return window.L.divIcon({
          html, className: "rr-cluster-icon",
          iconSize: [size, size], iconAnchor: [size/2, size/2],
        });
      },
    });

    const markers = filtered.map(d => {
      const color = brandColors[d.brand] || "#888";
      const html = `<span class="rr-dot" style="background:${color}"></span>`;
      const icon = window.L.divIcon({
        className: "rr-icon", html,
        iconSize: [10, 10], iconAnchor: [5, 5],
      });
      const m = window.L.marker([d.lat, d.lng], { icon, _brand: d.brand });
      const label = brandLabels[d.brand] || d.brand;
      const addr = [d.city, d.state].filter(Boolean).join(", ");
      const popup = isAuthed ? `
        <div class="rr-pop">
          <div class="rr-pop-eye" style="color:${color}">📦 ${label}</div>
          <div class="rr-pop-num">${d.name || label}</div>
          <div class="rr-pop-meta">${addr || `${d.lat.toFixed(3)}, ${d.lng.toFixed(3)}`}</div>
          <a class="rr-pop-link" target="_blank" rel="noopener noreferrer"
             href="https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(d.name + " " + addr)}">
             Open in Maps ↗
          </a>
        </div>` : `
        <div class="rr-pop">
          <div class="rr-pop-eye" style="color:${color}">📦 ${label}</div>
          <div class="rr-pop-meta rr-pop-cta">Sign in for name · address · maps deep-link →</div>
        </div>`;
      m.bindPopup(popup);
      return m;
    });

    cluster.addLayers(markers);
    cluster.addTo(map);
    clusterRef.current = cluster;
  }, [filtered, isAuthed, brandColors, brandLabels]);

  // Brand chips — only render brands that have rows on the map.
  const chips = useMemoRcv(() => {
    const counts = {};
    docks.forEach(d => { counts[d.brand] = (counts[d.brand] || 0) + 1; });
    return Object.entries(counts)
      .map(([slug, count]) => ({
        slug, count,
        label: brandLabels[slug] || slug,
        color: brandColors[slug] || "#888",
      }))
      .sort((a, b) => b.count - a.count);
  }, [docks, brandLabels, brandColors]);

  const visible = filtered.length;
  const total = docks.length;

  return (
    <section className="rr-radar">
      <style>{`
        .rr-radar { position: relative; background: #0a0e15; overflow: hidden;
          border-bottom: 1px solid #1f2937; }
        .rr-radar-map { width: 100%; height: 76vh; min-height: 540px; max-height: 800px;
          background: #0a0e15; }
        @media (max-width: 760px) { .rr-radar-map { height: 66vh; min-height: 440px; } }
        .rr-radar-map::after {
          content: ""; position: absolute; inset: 0; pointer-events: none;
          background: radial-gradient(ellipse at center, transparent 55%, rgba(10,14,21,0.55) 100%);
          z-index: 401;
        }
        .rr-icon { background: transparent !important; border: 0 !important; }
        .rr-dot {
          display: block; width: 10px; height: 10px; border-radius: 50%;
          border: 1.5px solid rgba(255,255,255,0.55);
          box-shadow: 0 0 4px rgba(0,0,0,0.5);
        }
        .rr-cluster-icon { background: transparent !important; border: 0 !important; }
        .rr-cluster {
          color: #fff; border-radius: 50%; display: flex; align-items: center;
          justify-content: center; font-family: var(--font-mono); font-size: 12px;
          font-weight: 600; letter-spacing: 0.05em; border: 2px solid rgba(255,255,255,0.7);
          text-shadow: 0 1px 2px rgba(0,0,0,0.6);
        }
        .rr-cluster span { line-height: 1; }

        .rr-title {
          position: absolute; top: 18px; left: 22px; z-index: 500;
          color: #fff; pointer-events: none; max-width: 600px;
        }
        .rr-title-eye {
          font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.18em;
          text-transform: uppercase; color: #FFB347;
          display: inline-flex; align-items: center; gap: 8px;
          padding: 6px 10px; background: rgba(0,0,0,0.5); border-radius: 4px;
          backdrop-filter: blur(6px);
        }
        .rr-title-eye .dot {
          display: inline-block; width: 8px; height: 8px; border-radius: 50%;
          background: #FFB347; animation: rr-livedot 1.6s ease-in-out infinite;
        }
        @keyframes rr-livedot {
          0%, 100% { box-shadow: 0 0 0 0 rgba(255,179,71,0.6); }
          70% { box-shadow: 0 0 0 8px rgba(255,179,71,0); }
        }
        .rr-title-h {
          font-family: var(--font-serif); font-size: clamp(28px, 4vw, 46px);
          line-height: 1.05; letter-spacing: -0.025em;
          margin: 12px 0 6px;
          text-shadow: 0 2px 16px rgba(0,0,0,0.6);
        }
        .rr-title-h em { font-style: italic; color: #FFB347; }
        .rr-title-sub {
          font-size: 14px; color: #cbd5e1; line-height: 1.45;
          text-shadow: 0 1px 8px rgba(0,0,0,0.6);
        }

        .rr-chips {
          position: absolute; bottom: 18px; left: 50%; transform: translateX(-50%);
          z-index: 500; display: flex; flex-wrap: nowrap; gap: 6px;
          padding: 8px 12px; background: rgba(10,14,21,0.85);
          border: 1px solid rgba(255,255,255,0.08); border-radius: 8px;
          backdrop-filter: blur(10px); max-width: min(720px, 64vw);
          overflow-x: auto; overflow-y: hidden;
          scrollbar-width: thin; scrollbar-color: rgba(255,255,255,0.18) transparent;
          mask-image: linear-gradient(90deg, transparent 0, #000 4%, #000 96%, transparent 100%);
        }
        .rr-chips::-webkit-scrollbar { height: 4px; }
        .rr-chips::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.18); border-radius: 2px; }
        @media (max-width: 760px) { .rr-chips { max-width: 88vw; bottom: 12px; } }
        .rr-chip {
          display: inline-flex; align-items: center; gap: 6px;
          background: transparent; border: 1px solid rgba(255,255,255,0.12);
          padding: 5px 10px; border-radius: 999px; cursor: pointer;
          font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.06em;
          text-transform: uppercase; color: #cbd5e1;
          transition: all 0.15s; flex-shrink: 0;
        }
        .rr-chip:hover { background: rgba(255,255,255,0.06); }
        .rr-chip[data-active="true"] {
          background: var(--chip-c, #fff); color: #0a0e15;
          border-color: var(--chip-c, #fff);
        }
        .rr-chip-dot { display: inline-block; width: 7px; height: 7px;
          border-radius: 50%; background: var(--chip-c, #fff); }
        .rr-chip-meta { font-size: 9px; opacity: 0.75; margin-left: 2px; }

        .rr-cta-overlay {
          position: absolute; top: 18px; right: 22px; z-index: 500;
          background: rgba(10,14,21,0.85); backdrop-filter: blur(10px);
          border: 1px solid rgba(255,179,71,0.35); border-radius: 8px;
          padding: 14px 18px; max-width: 320px; color: #f1f5f9;
          box-shadow: 0 12px 36px rgba(0,0,0,0.4);
        }
        .rr-cta-eye { font-family: var(--font-mono); font-size: 10px;
          letter-spacing: 0.18em; text-transform: uppercase;
          color: #FFB347; margin-bottom: 6px; }
        .rr-cta-h { font-family: var(--font-serif); font-size: 17px;
          letter-spacing: -0.015em; margin: 0 0 6px; }
        .rr-cta-sub { font-size: 12px; color: #94a3b8; line-height: 1.45;
          margin-bottom: 10px; }
        .rr-cta-btn {
          display: inline-flex; align-items: center; gap: 6px;
          background: #FFB347; color: #0a0e15; border: 0;
          padding: 8px 14px; border-radius: 5px; font-family: inherit;
          font-weight: 600; font-size: 13px; cursor: pointer;
        }

        .rr-progress {
          position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
          z-index: 500; pointer-events: none;
          background: rgba(10,14,21,0.85); backdrop-filter: blur(10px);
          border: 1px solid rgba(255,179,71,0.35); border-radius: 8px;
          padding: 14px 22px; color: #cbd5e1;
          font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.05em;
          text-align: center;
        }
        .rr-progress-num { font-family: var(--font-serif); font-size: 26px;
          letter-spacing: -0.02em; color: #FFB347; margin-bottom: 4px; }

        /* Layer/popup theming same as other radars */
        .leaflet-popup-content-wrapper {
          background: rgba(10,14,21,0.95) !important; color: #f1f5f9;
          border: 1px solid rgba(255,255,255,0.08); border-radius: 8px;
        }
        .leaflet-popup-tip { background: rgba(10,14,21,0.95) !important; }
        .leaflet-popup-close-button { color: #94a3b8 !important; }
        .leaflet-control-zoom a {
          background: rgba(10,14,21,0.85) !important; color: #cbd5e1 !important;
          border: 1px solid rgba(255,255,255,0.08) !important;
        }
        .rr-pop { font-family: var(--font-sans, system-ui); min-width: 200px; padding: 4px 2px; }
        .rr-pop-eye { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.14em;
          text-transform: uppercase; margin-bottom: 4px; }
        .rr-pop-num { font-family: var(--font-serif); font-size: 16px;
          letter-spacing: -0.01em; color: #f1f5f9; }
        .rr-pop-meta { font-size: 11px; color: #94a3b8; margin-top: 4px; line-height: 1.45; }
        .rr-pop-cta { color: #FFB347; font-weight: 500; }
        .rr-pop-link { display: inline-block; margin-top: 8px;
          font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.12em;
          text-transform: uppercase; color: #FFB347; text-decoration: none;
          border-bottom: 1px dotted #FFB347; }
      `}</style>

      <div ref={containerRef} className="rr-radar-map" />

      <div className="rr-title">
        <span className="rr-title-eye">
          <span className="dot" />
          {loading
            ? `Loading docks · ${progress.loaded.toLocaleString()}${progress.total ? " / " + progress.total.toLocaleString() : ""}`
            : `${visible.toLocaleString()} of ${total.toLocaleString()} docks visible`}
        </span>
        <h1 className="rr-title-h">
          Find your <em>dock.</em>
        </h1>
        <p className="rr-title-sub">
          Every Walmart, Home Depot, Lowe's, Target, Costco, Walgreens, CVS, Dollar General,
          AutoZone, Tractor Supply — every named delivery dock we can position. Free for drivers.
          Filter by brand below; click any cluster to drill in.
        </p>
      </div>

      {!isAuthed && (
        <div className="rr-cta-overlay">
          <div className="rr-cta-eye"><span style={{display:"inline-block",width:6,height:6,borderRadius:"50%",background:"#FFB347",marginRight:6,verticalAlign:"middle"}}/>Anonymous view</div>
          <h3 className="rr-cta-h">Pin a dock with full address.</h3>
          <p className="rr-cta-sub">
            Sign in for the name, street address, and a one-tap "Open in Maps" link on every pin.
            Free magic-link · no password.
          </p>
          <button className="rr-cta-btn" onClick={() => onNav("signin")}>Sign in →</button>
        </div>
      )}

      {loading && progress.loaded === 0 && (
        <div className="rr-progress">
          <div className="rr-progress-num">Calibrating…</div>
          <div>Pulling 86,000+ delivery docks from OSM</div>
        </div>
      )}

      <div className="rr-chips">
        <button className="rr-chip" data-active={activeBrand === null}
                onClick={() => setActiveBrand(null)}>
          ALL · {chips.reduce((s,c) => s + c.count, 0).toLocaleString()}
        </button>
        {chips.slice(0, 14).map(c => (
          <button key={c.slug} className="rr-chip"
                  data-active={activeBrand === c.slug}
                  style={{ "--chip-c": c.color }}
                  onClick={() => setActiveBrand(activeBrand === c.slug ? null : c.slug)}>
            <span className="rr-chip-dot" />
            {c.label}
            <span className="rr-chip-meta">{c.count.toLocaleString()}</span>
          </button>
        ))}
      </div>
    </section>
  );
}

function ReceiversPage({ onNav }) {
  // Auth state for the radar's auth-aware popups + CTA card.
  const [authedUser, setAuthedUser] = useStateRcv(null);
  useEffectRcv(() => {
    let alive = true;
    if (window.SI_DB && window.SI_DB.auth && window.SI_DB.auth.getCurrentUser) {
      window.SI_DB.auth.getCurrentUser().then(u => { if (alive) setAuthedUser(u); }).catch(() => {});
    }
    return () => { alive = false; };
  }, []);
  const [brand, setBrand]       = useStateRcv("");      // "" = brand-grid landing
  const [state, setState]       = useStateRcv("");
  const [search, setSearch]     = useStateRcv("");
  const [rows, setRows]         = useStateRcv([]);
  const [counts, setCounts]     = useStateRcv({});      // brand → count
  const [loading, setLoading]   = useStateRcv(false);

  // Brand-counts. Chunked at 6 concurrent so a 30+ brand list doesn't fan out
  // a thundering herd that drops requests under burst rate limits — losing a
  // count silently hides the brand card. Render incrementally as chunks finish.
  useEffectRcv(() => {
    let alive = true;
    if (!window.SI_DB || !window.SI_DB.raw || !window.SI_DB.raw.count) return;
    (async () => {
      const brands = Object.keys(RCV_BRAND_LABEL);
      const out = {};
      const CHUNK = 6;
      for (let i = 0; i < brands.length; i += CHUNK) {
        if (!alive) return;
        const chunk = brands.slice(i, i + CHUNK);
        await Promise.all(chunk.map(async (b) => {
          try {
            const n = await window.SI_DB.raw.count("receiver_locations", `brand=eq.${b}`);
            if (n != null) out[b] = n;
          } catch {}
        }));
        if (alive) setCounts({ ...out });
      }
    })();
    return () => { alive = false; };
  }, []);

  // Per-brand row fetch
  useEffectRcv(() => {
    if (!brand) { setRows([]); return; }
    let alive = true;
    setLoading(true);
    (async () => {
      try {
        let q = `select=id,brand,kind,name,address,city,state,postcode,lat,lng,metro_city_id,amenities&brand=eq.${brand}&order=state.asc,city.asc&limit=400`;
        if (state) q += `&state=eq.${state}`;
        if (search.trim()) {
          const s = encodeURIComponent(`%${search.trim()}%`);
          q += `&or=(city.ilike.${s},name.ilike.${s},address.ilike.${s})`;
        }
        const r = await window.SI_DB.raw.select("receiver_locations", q);
        if (!alive) return;
        setRows(Array.isArray(r) ? r : []);
      } catch (e) {
        console.warn("[receivers] load failed", e);
      } finally {
        if (alive) setLoading(false);
      }
    })();
    return () => { alive = false; };
  }, [brand, state, search]);

  const brandOrder = useMemoRcv(() => {
    return Object.keys(RCV_BRAND_LABEL)
      .map(b => ({ slug: b, label: RCV_BRAND_LABEL[b], count: counts[b] || 0 }))
      .filter(b => b.count > 0)
      .sort((a, b) => b.count - a.count);
  }, [counts]);

  const total = brandOrder.reduce((s, b) => s + b.count, 0);

  return (
    <div className="page-receivers">
      {/* RECEIVERS RADAR — focal hero, every dock we have a position for,
          color-coded by brand. Marker-clusters at low zoom for performance. */}
      <ReceiversRadar
        user={authedUser}
        onNav={onNav}
        brandLabels={RCV_BRAND_LABEL}
        brandColors={RCV_BRAND_COLOR}
      />
      <style>{`
        .rcv-hero { padding: 56px 24px 32px; max-width: 1200px; margin: 0 auto; }
        .rcv-eyebrow { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.18em;
          text-transform: uppercase; color: var(--ink-soft); margin-bottom: 14px; }
        .rcv-eyebrow .dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%;
          background: oklch(0.55 0.18 145); margin-right: 8px; vertical-align: middle; }
        .rcv-title { font-family: var(--font-serif); font-size: 48px; line-height: 1.05;
          letter-spacing: -0.025em; margin: 0 0 14px; }
        .rcv-title em { font-style: italic; color: var(--red, oklch(0.50 0.16 250)); }
        .rcv-sub { color: var(--ink-soft); font-size: 17px; max-width: 680px;
          line-height: 1.5; margin: 0; }

        .rcv-controls { max-width: 1200px; margin: 32px auto; padding: 0 24px;
          display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 12px; }
        @media (max-width: 760px) { .rcv-controls { grid-template-columns: 1fr; } }
        .rcv-input, .rcv-select {
          padding: 12px 16px; font-size: 15px; font-family: inherit;
          border: 1px solid var(--rule); border-radius: 6px; box-sizing: border-box; width: 100%;
          background: #fff;
        }

        .rcv-grid-section { max-width: 1200px; margin: 0 auto 80px; padding: 0 24px; }
        .rcv-section-h { font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.18em;
          text-transform: uppercase; color: var(--ink-soft); padding-bottom: 14px;
          border-bottom: 1px solid var(--rule); margin-bottom: 24px; }
        .rcv-brand-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
          gap: 12px; }
        .rcv-brand-card { background: #fff; border: 1px solid var(--rule); border-radius: 8px;
          padding: 18px; cursor: pointer; transition: all 0.15s; text-align: left; }
        .rcv-brand-card:hover { border-color: var(--ink); transform: translateY(-2px); }
        .rcv-brand-bar { width: 28px; height: 4px; border-radius: 2px; margin-bottom: 12px; }
        .rcv-brand-name { font-family: var(--font-serif); font-size: 18px; letter-spacing: -0.01em;
          margin-bottom: 4px; }
        .rcv-brand-count { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.1em;
          color: var(--ink-soft); text-transform: uppercase; }

        .rcv-back { font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.14em;
          text-transform: uppercase; color: var(--ink-soft); background: none; border: none;
          cursor: pointer; padding: 0; margin-bottom: 14px; }

        .rcv-results { display: grid; grid-template-columns: 1fr 1.5fr; gap: 24px;
          align-items: start; }
        @media (max-width: 900px) { .rcv-results { grid-template-columns: 1fr; } }
        .rcv-list { max-height: 540px; overflow-y: auto; border: 1px solid var(--rule);
          border-radius: 8px; }
        .rcv-row { padding: 12px 16px; border-bottom: 1px solid var(--rule); cursor: pointer;
          transition: background 0.1s; }
        .rcv-row:hover { background: oklch(0.97 0.005 250); }
        .rcv-row:last-child { border-bottom: none; }
        .rcv-row-name { font-family: var(--font-serif); font-size: 15px; }
        .rcv-row-meta { font-size: 12px; color: var(--ink-soft); margin-top: 2px;
          font-family: var(--font-mono); letter-spacing: 0.05em; }
      `}</style>

      <section className="rcv-hero">
        <div className="rcv-eyebrow"><span className="dot" /> Free for drivers · {total > 0 ? `${total.toLocaleString()} docks on the network` : "loading…"}</div>
        <h1 className="rcv-title">
          Find your <em>dock.</em>
        </h1>
        <p className="rcv-sub">
          Every Walmart, Home Depot, Lowe's, Target, Costco, Kroger, Sam's, Aldi, Safeway,
          Publix, Amazon FC, Walgreens, CVS, Dollar General, Family Dollar, Tractor Supply,
          Best Buy, IKEA, Menards, Ace, AutoZone, O'Reilly, and named cold-storage receiving
          location in the country. Search by brand, state, or city. Open in maps. No login.
        </p>
      </section>

      {!brand && (
        <div className="rcv-grid-section">
          <div className="rcv-section-h">Pick a brand · {brandOrder.length} on the network</div>
          {brandOrder.length === 0 ? (
            <div style={{ color: "var(--ink-soft)", textAlign: "center", padding: 60 }}>
              Loading brands…
            </div>
          ) : (
            <div className="rcv-brand-grid">
              {brandOrder.map(b => (
                <button key={b.slug} className="rcv-brand-card" onClick={() => setBrand(b.slug)}>
                  <div className="rcv-brand-bar" style={{ background: RCV_BRAND_COLOR[b.slug] || "#444" }} />
                  <div className="rcv-brand-name">{b.label}</div>
                  <div className="rcv-brand-count">{b.count.toLocaleString()} locations</div>
                </button>
              ))}
            </div>
          )}
        </div>
      )}

      {brand && (
        <>
          <div className="rcv-controls">
            <input type="text" className="rcv-input" placeholder="Search city, address, or location name…"
                   value={search} onChange={e => setSearch(e.target.value)} />
            <select className="rcv-select" value={state} onChange={e => setState(e.target.value)}>
              {RCV_STATES.map(([code, name]) => <option key={code} value={code}>{name}</option>)}
            </select>
            <button className="rcv-input" style={{ cursor: "pointer", background: "var(--ink)", color: "#fff", border: "1px solid var(--ink)" }}
                    onClick={() => { setBrand(""); setState(""); setSearch(""); }}>
              ← All brands
            </button>
          </div>

          <div className="rcv-grid-section">
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline",
                          paddingBottom: 14, borderBottom: "1px solid var(--rule)", marginBottom: 18 }}>
              <h2 style={{ fontFamily: "var(--font-serif)", fontSize: 26, letterSpacing: "-0.02em", margin: 0 }}>
                {RCV_BRAND_LABEL[brand]}
              </h2>
              <span style={{ fontFamily: "var(--font-mono)", fontSize: 11, letterSpacing: "0.1em",
                             textTransform: "uppercase", color: "var(--ink-soft)" }}>
                {loading ? "loading…" : `${rows.length.toLocaleString()} shown${rows.length === 400 ? " · refine search" : ""}`}
              </span>
            </div>

            <div className="rcv-results">
              <div className="rcv-list">
                {rows.length === 0 && !loading && (
                  <div style={{ padding: 40, color: "var(--ink-soft)", textAlign: "center" }}>
                    No locations match.
                  </div>
                )}
                {rows.map(r => {
                  const addr = [r.address, r.city, r.state].filter(Boolean).join(", ");
                  return (
                    <div className="rcv-row" key={r.id}
                         onClick={() => window.open(
                           `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(addr || `${r.lat},${r.lng}`)}`,
                           "_blank"
                         )}>
                      <div className="rcv-row-name">{r.name || RCV_BRAND_LABEL[r.brand]}</div>
                      <div className="rcv-row-meta">
                        {addr || `${r.lat.toFixed(4)}°, ${r.lng.toFixed(4)}°`}
                      </div>
                    </div>
                  );
                })}
              </div>
              <ReceiversMap rows={rows} />
            </div>
          </div>
        </>
      )}
    </div>
  );
}

window.ReceiversPage = ReceiversPage;
