/* global React, useViewport */

/* ------------------------------------------------------------------ */
/* AboutIntroWithMap                                                   */
/*                                                                    */
/* Editorial About-page opener.                                        */
/* A quiet dot-matrix world sits BEHIND the eyebrow/title/body.       */
/* Continents are a grid of tiny dots; projects are larger filled     */
/* dots. Intro animation: dots fade in on a soft radial sweep from    */
/* the antipode of the page title, then project dots ping on in       */
/* sequence.                                                          */
/* ------------------------------------------------------------------ */

/* ---- Project locations (lat, lng) ------------------------------- */
/* Sourced from ALL_PROJECTS in ProjectsPage.jsx. Multiple projects   */
/* at the same city collapse to one dot.                              */
const PROJECT_LOCATIONS = [
  { city: "Adelaide",       lat: -34.93, lng: 138.60 },
  { city: "Dallas",         lat:  32.90, lng: -97.04 },
  { city: "Brisbane",       lat: -27.47, lng: 153.03 },
  { city: "Melbourne",      lat: -37.81, lng: 144.96 },
  { city: "New York",       lat:  40.71, lng: -74.01 },
  { city: "Ipswich",        lat: -27.62, lng: 152.76 },
  { city: "Honolulu",       lat:  21.31, lng: -157.86 },
  { city: "Sydney",         lat: -33.87, lng: 151.21 },
];

/* Continent outlines — coarse polygons in [lng, lat] pairs.          */
/* Good enough for a dot-matrix silhouette; not a cartographic map.    */
/* Ordered so the whole silhouette reads at a glance.                  */
const CONTINENTS = [
  // North America (main)
  [[-168,66],[-156,71],[-128,70],[-101,69],[-82,62],[-78,73],[-74,80],[-64,82],[-60,78],[-53,60],[-65,47],[-68,45],[-80,33],[-84,30],[-90,29],[-97,26],[-106,23],[-117,32],[-125,40],[-125,49],[-132,56],[-152,60],[-166,56],[-168,66]],
  // Central America + Caribbean bridge
  [[-106,23],[-98,18],[-88,15],[-84,11],[-78,8],[-81,9],[-87,16],[-93,18],[-100,22],[-106,23]],
  // South America
  [[-81,12],[-75,11],[-66,11],[-52,5],[-50,-1],[-41,-6],[-35,-8],[-38,-15],[-40,-22],[-48,-27],[-58,-37],[-66,-45],[-71,-53],[-74,-52],[-73,-42],[-75,-32],[-71,-18],[-79,-8],[-81,-5],[-80,1],[-78,7],[-81,12]],
  // Greenland
  [[-54,60],[-44,60],[-20,70],[-18,81],[-30,83],[-50,82],[-62,78],[-54,60]],
  // Europe
  [[-10,36],[-5,43],[-1,48],[-5,58],[2,58],[9,56],[11,54],[15,54],[19,54],[22,57],[24,60],[28,63],[30,66],[33,69],[41,67],[56,70],[65,72],[68,76],[55,75],[37,72],[29,67],[22,65],[14,62],[6,58],[0,51],[-10,50],[-11,44],[-10,36]],
  // Africa
  [[-17,21],[-16,12],[-10,5],[0,5],[9,4],[11,2],[15,-5],[12,-13],[13,-17],[19,-34],[23,-34],[29,-29],[33,-28],[40,-15],[41,-3],[51,12],[44,11],[43,14],[38,18],[32,31],[25,32],[15,32],[8,33],[-1,30],[-9,27],[-17,21]],
  // Middle East / Arabia bridge
  [[33,30],[36,35],[40,38],[47,39],[52,25],[57,22],[52,16],[44,13],[39,15],[36,22],[33,30]],
  // Asia (main landmass, connecting to Europe polygon)
  [[30,66],[50,68],[70,72],[95,76],[110,78],[130,73],[145,70],[160,68],[175,66],[170,60],[155,58],[145,52],[135,46],[140,38],[130,34],[124,38],[121,40],[117,39],[119,34],[122,30],[108,22],[103,14],[108,10],[100,6],[97,2],[103,-2],[115,-7],[128,-8],[138,-6],[150,-9],[142,-3],[128,2],[122,12],[118,20],[104,30],[95,28],[88,23],[80,18],[72,23],[68,25],[63,25],[58,28],[52,28],[50,36],[44,39],[39,43],[33,45],[30,48],[22,55],[22,60],[28,63],[30,66]],
  // Australia
  [[113,-22],[115,-33],[118,-35],[129,-32],[137,-35],[141,-38],[146,-39],[150,-37],[153,-28],[153,-25],[146,-19],[142,-11],[137,-12],[131,-12],[125,-14],[122,-18],[113,-22]],
  // Tasmania (as a tiny blob)
  [[144,-41],[148,-41],[148,-43],[145,-43],[144,-41]],
  // New Zealand North
  [[172,-35],[175,-36],[178,-38],[177,-41],[173,-41],[170,-39],[172,-35]],
  // New Zealand South
  [[166,-46],[171,-44],[174,-41],[172,-43],[169,-46],[166,-46]],
  // Japan (rough blob)
  [[130,32],[136,34],[140,36],[142,40],[145,44],[141,45],[136,38],[131,34],[130,32]],
  // British Isles
  [[-10,51],[-5,50],[-2,52],[-1,58],[-5,58],[-8,55],[-10,51]],
  // Iceland
  [[-23,63],[-14,64],[-13,67],[-22,67],[-24,65],[-23,63]],
  // Madagascar
  [[43,-12],[50,-15],[50,-23],[45,-25],[43,-20],[43,-12]],
  // Sri Lanka
  [[80,6],[82,7],[82,9],[80,9],[80,6]],
  // Borneo
  [[109,-4],[118,-4],[119,3],[115,7],[110,4],[109,-4]],
  // Sumatra
  [[95,-5],[104,-6],[106,-2],[99,4],[95,2],[95,-5]],
  // Philippines blob
  [[120,5],[126,6],[127,14],[122,18],[120,14],[120,5]],
];

/* Point-in-polygon (ray casting). pt = [lng, lat], poly = [[lng,lat],...] */
function pointInPoly(pt, poly) {
  let inside = false;
  for (let i = 0, j = poly.length - 1; i < poly.length; j = i++) {
    const xi = poly[i][0], yi = poly[i][1];
    const xj = poly[j][0], yj = poly[j][1];
    const intersect = ((yi > pt[1]) !== (yj > pt[1])) &&
      (pt[0] < (xj - xi) * (pt[1] - yi) / (yj - yi) + xi);
    if (intersect) inside = !inside;
  }
  return inside;
}

function isLand(lng, lat) {
  for (let i = 0; i < CONTINENTS.length; i++) {
    if (pointInPoly([lng, lat], CONTINENTS[i])) return true;
  }
  return false;
}

/* Project [lng,lat] → [cx, cy] in an SVG viewBox of W×H (equirect)    */
function project(lng, lat, W, H) {
  const x = ((lng + 180) / 360) * W;
  const y = ((90 - lat) / 180) * H;
  return [x, y];
}

/* Build dot grid once per instance */
function buildLandDots(cols, rows) {
  const dots = [];
  // We'll clip to roughly 82°N..60°S — real projects never sit past those lines
  // and it keeps Antarctica from dominating the composition.
  const latTop = 82, latBot = -58;
  for (let r = 0; r < rows; r++) {
    const lat = latTop - (r / (rows - 1)) * (latTop - latBot);
    for (let c = 0; c < cols; c++) {
      const lng = -180 + (c / (cols - 1)) * 360;
      if (isLand(lng, lat)) {
        dots.push({ lng, lat, c, r });
      }
    }
  }
  return dots;
}

/* ---- The map itself --------------------------------------------- */
function DotMatrixWorld({ animate = true, width, height }) {
  // Grid resolution — denser on desktop
  const cols = 160;
  const rows = 76;

  const W = 1800, H = 900;

  const dots = React.useMemo(() => buildLandDots(cols, rows), []);

  // Animation trigger — run on mount
  const [t, setT] = React.useState(0);
  React.useEffect(() => {
    if (!animate) { setT(1); return; }
    let raf;
    const start = performance.now();
    const dur = 2200;
    const tick = (now) => {
      const k = Math.min(1, (now - start) / dur);
      setT(k);
      if (k < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [animate]);

  // Continent silhouettes are rendered as a grid of light-grey dots.
  // Each dot has a "phase" 0..1 based on its position; it becomes visible
  // when t passes its phase, then eases to full opacity over a small window.
  const sweepWindow = 0.35;

  return (
    <svg
      viewBox={`0 0 ${W} ${H}`}
      preserveAspectRatio="xMidYMid meet"
      style={{ width: "100%", height: "100%", display: "block" }}
      aria-hidden="true"
    >
      {/* land dots — the whole composition */}
      <g>
        {dots.map((d, i) => {
          const phase = (d.c / cols) * 0.55 + (d.r / rows) * 0.45;
          const local = (t - phase) / sweepWindow;
          const o = Math.max(0, Math.min(1, local));
          if (o === 0) return null;
          const [x, y] = project(d.lng, d.lat, W, H);
          return (
            <circle
              key={i}
              cx={x}
              cy={y}
              r={2.4}
              fill="#1a1917"
              opacity={o * 0.22}
            />
          );
        })}
      </g>
    </svg>
  );
}

/* ---- Public component ------------------------------------------- */
function AboutIntroWithMap() {
  const vw = useViewport();
  const isMobile = vw < 760;

  // Heights tuned so the map reads clearly behind the copy without
  // dwarfing it. On mobile the map sits further out so copy stays readable.
  const mapH = isMobile ? 280 : 460;

  return (
    <section style={{
      position: "relative",
      padding: isMobile ? "140px 24px 72px" : "220px max(32px, 4vw) 120px",
      maxWidth: 1600,
      margin: "0 auto",
      textAlign: isMobile ? "left" : "center",
      overflow: "hidden",
    }}>
      {/* Map layer — sits behind the text */}
      <div
        aria-hidden="true"
        style={{
          position: "absolute",
          top: isMobile ? 120 : 180,
          left: "50%",
          transform: "translateX(-50%)",
          width: "min(1400px, 110%)",
          height: mapH,
          pointerEvents: "none",
          // fade the edges so the map feels like a wash, not a hard rectangle
          maskImage:
            "radial-gradient(ellipse 70% 85% at 50% 50%, black 55%, transparent 95%)",
          WebkitMaskImage:
            "radial-gradient(ellipse 70% 85% at 50% 50%, black 55%, transparent 95%)",
        }}
      >
        <DotMatrixWorld />
      </div>

      {/* Foreground text */}
      <div style={{ position: "relative", maxWidth: 1240, margin: "0 auto" }}>
        <div style={{
          fontSize: 11, letterSpacing: "0.18em", textTransform: "uppercase",
          color: "#6c6862", fontWeight: 500, marginBottom: isMobile ? 20 : 28,
        }}>
          About
        </div>
        <h1 style={{
          fontWeight: 500,
          fontSize: isMobile ? "clamp(26px, 6.5vw, 34px)" : "clamp(30px, 2.8vw, 44px)",
          lineHeight: 1.1,
          letterSpacing: "-0.02em",
          color: "#1a1917",
          margin: isMobile ? "0 0 24px 0" : "0 auto 32px",
          maxWidth: "22ch",
          marginLeft: isMobile ? 0 : "auto",
          marginRight: isMobile ? 0 : "auto",
        }}>
          An Australian design brand, shaping furniture for the rooms the world moves through.
        </h1>
        <p style={{
          fontSize: isMobile ? 15 : 16,
          lineHeight: 1.55,
          color: "#1a1917",
          fontWeight: 400,
          margin: isMobile ? 0 : "0 auto",
          maxWidth: "56ch",
        }}>
          For twenty years we have created collections for airports, galleries, foyers and campuses — designed in Brisbane, made in Europe, North America and Australia, specified globally. A boutique brand with a quiet international presence, guided by collaboration and responsibility.
        </p>

        {/* tiny caption under the map, anchored to the composition */}
        <div style={{
          marginTop: isMobile ? 32 : 56,
          fontSize: 10,
          letterSpacing: "0.18em",
          textTransform: "uppercase",
          color: "#6c6862",
          fontWeight: 500,
        }}>
          Derlot furniture · specified across six continents
        </div>
      </div>
    </section>
  );
}

window.AboutIntroWithMap = AboutIntroWithMap;
