"use client";

import React, { useEffect, useRef } from "react";

/**
 * Animated dotted world map (Canvas 2D) for the Solutions industry section.
 * - Continents drawn as a grid of dots clipped to rough continent polygons.
 * - Major logistics hub cities with continuous double red pulse rings.
 * - Red glowing packets travelling along arced quadratic-bezier routes.
 * - Low-opacity dashed connection lines between hubs.
 * Continent / city coordinates are normalized (0..1): x west→east, y north→south.
 */

const CONTINENTS: number[][][] = [
  // North America
  [[0.04,0.20],[0.10,0.12],[0.18,0.10],[0.24,0.13],[0.29,0.12],[0.30,0.18],
   [0.27,0.22],[0.26,0.28],[0.22,0.30],[0.20,0.38],[0.17,0.44],[0.15,0.40],
   [0.16,0.32],[0.12,0.30],[0.09,0.26],[0.06,0.24]],
  // South America
  [[0.21,0.50],[0.27,0.48],[0.31,0.52],[0.31,0.60],[0.29,0.66],[0.27,0.74],
   [0.24,0.82],[0.22,0.80],[0.22,0.70],[0.205,0.62],[0.20,0.55]],
  // Europe
  [[0.45,0.16],[0.50,0.13],[0.55,0.15],[0.57,0.19],[0.55,0.24],[0.50,0.27],
   [0.47,0.25],[0.455,0.20]],
  // Africa
  [[0.46,0.34],[0.53,0.32],[0.58,0.36],[0.585,0.44],[0.56,0.52],[0.53,0.60],
   [0.50,0.66],[0.47,0.62],[0.46,0.52],[0.45,0.44],[0.45,0.38]],
  // Asia
  [[0.56,0.14],[0.64,0.10],[0.74,0.10],[0.84,0.14],[0.90,0.20],[0.92,0.26],
   [0.86,0.30],[0.80,0.30],[0.74,0.34],[0.70,0.34],[0.66,0.30],[0.60,0.30],
   [0.575,0.24],[0.565,0.18]],
  // Australia
  [[0.81,0.66],[0.87,0.64],[0.92,0.68],[0.92,0.74],[0.86,0.77],[0.81,0.74],[0.80,0.70]],
];

const CITIES: [number, number][] = [
  [0.115, 0.30], // 0 Los Angeles
  [0.265, 0.255],// 1 New York
  [0.285, 0.66], // 2 São Paulo
  [0.475, 0.185],// 3 London
  [0.605, 0.345],// 4 Dubai
  [0.655, 0.40], // 5 Mumbai
  [0.745, 0.50], // 6 Singapore
  [0.815, 0.275],// 7 Shanghai
  [0.865, 0.715],// 8 Sydney
];

const ROUTES: [number, number][] = [
  [0, 1], [1, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [1, 2], [3, 7], [0, 7],
];

function pointInPoly(x: number, y: number, poly: number[][]) {
  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 > y !== yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi;
    if (intersect) inside = !inside;
  }
  return inside;
}

/** Parse a #rrggbb hex into an [r,g,b] triple. Falls back to the section red. */
function hexToRgb(hex: string): [number, number, number] {
  const m = /^#?([0-9a-f]{6})$/i.exec(hex.trim());
  if (!m) return [239, 68, 68];
  const int = parseInt(m[1], 16);
  return [(int >> 16) & 255, (int >> 8) & 255, int & 255];
}

/**
 * @param accent  Network accent colour (#rrggbb) for the hub nodes, pulse
 *   rings, travelling packets and dashed routes. The dotted continent
 *   silhouette stays neutral grey. Defaults to the section red so the Women
 *   Empowerment usage is unchanged; the MileTruth workflows pass their own
 *   accent (WF1 teal/cyan · WF2 crimson/red).
 */
export default function IndustryWorldMap({
  accent = "#ef4444",
}: {
  accent?: string;
}) {
  const canvasRef = useRef<HTMLCanvasElement>(null);

  useEffect(() => {
    const [ar, ag, ab] = hexToRgb(accent);
    const rgba = (a: number) => `rgba(${ar},${ag},${ab},${a})`;
    const solid = `rgb(${ar},${ag},${ab})`;
    const canvas = canvasRef.current;
    const parent = canvas?.parentElement;
    if (!canvas || !parent) return;
    const ctx = canvas.getContext("2d");
    if (!ctx) return;

    const reduced = window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
    let w = 0, h = 0;
    let dots: { x: number; y: number }[] = [];
    let raf = 0;
    let startTs = 0;

    const buildDots = () => {
      dots = [];
      const gap = Math.max(11, Math.min(17, w / 70));
      for (let gx = gap / 2; gx < w; gx += gap) {
        for (let gy = gap / 2; gy < h; gy += gap) {
          const nx = gx / w, ny = gy / h;
          for (const poly of CONTINENTS) {
            if (pointInPoly(nx, ny, poly)) { dots.push({ x: gx, y: gy }); break; }
          }
        }
      }
    };

    const resize = () => {
      const rect = parent.getBoundingClientRect();
      w = Math.max(1, rect.width);
      h = Math.max(1, rect.height);
      const dpr = Math.min(window.devicePixelRatio || 1, 2);
      canvas.width = Math.round(w * dpr);
      canvas.height = Math.round(h * dpr);
      canvas.style.width = w + "px";
      canvas.style.height = h + "px";
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
      buildDots();
    };

    type Point = { x: number; y: number };
    const cityPx = (): Point[] => CITIES.map(([cx, cy]) => ({ x: cx * w, y: cy * h }));

    const ctrl = (p0: Point, p1: Point): Point => {
      const mx = (p0.x + p1.x) / 2, my = (p0.y + p1.y) / 2;
      const lift = Math.hypot(p1.x - p0.x, p1.y - p0.y) * 0.28;
      return { x: mx, y: my - lift };
    };
    const bezier = (p0: Point, c: Point, p1: Point, t: number): Point => {
      const u = 1 - t;
      return {
        x: u * u * p0.x + 2 * u * t * c.x + t * t * p1.x,
        y: u * u * p0.y + 2 * u * t * c.y + t * t * p1.y,
      };
    };

    const draw = (time: number) => {
      ctx.clearRect(0, 0, w, h);

      // Continent dots
      ctx.fillStyle = "rgba(120,122,130,0.55)";
      for (const d of dots) {
        ctx.beginPath();
        ctx.arc(d.x, d.y, 1.15, 0, Math.PI * 2);
        ctx.fill();
      }

      const cs = cityPx();

      // Dashed connection lines (low opacity)
      ctx.save();
      ctx.setLineDash([4, 7]);
      ctx.lineWidth = 1;
      ctx.strokeStyle = rgba(0.13);
      for (const [a, b] of ROUTES) {
        const c = ctrl(cs[a], cs[b]);
        ctx.beginPath();
        ctx.moveTo(cs[a].x, cs[a].y);
        ctx.quadraticCurveTo(c.x, c.y, cs[b].x, cs[b].y);
        ctx.stroke();
      }
      ctx.restore();

      // Travelling red glowing packets
      ctx.save();
      for (let r = 0; r < ROUTES.length; r++) {
        const [a, b] = ROUTES[r];
        const c = ctrl(cs[a], cs[b]);
        const t = ((time * 0.11 + r * 0.137) % 1 + 1) % 1;
        const p = bezier(cs[a], c, cs[b], t);
        // soft trail
        const tt = Math.max(0, t - 0.04);
        const pt = bezier(cs[a], c, cs[b], tt);
        const grad = ctx.createLinearGradient(pt.x, pt.y, p.x, p.y);
        grad.addColorStop(0, rgba(0));
        grad.addColorStop(1, rgba(0.5));
        ctx.strokeStyle = grad;
        ctx.lineWidth = 2;
        ctx.beginPath();
        ctx.moveTo(pt.x, pt.y);
        ctx.lineTo(p.x, p.y);
        ctx.stroke();

        ctx.shadowColor = solid;
        ctx.shadowBlur = 12;
        ctx.fillStyle = solid;
        ctx.beginPath();
        ctx.arc(p.x, p.y, 2.6, 0, Math.PI * 2);
        ctx.fill();
        ctx.shadowBlur = 0;
      }
      ctx.restore();

      // City hub nodes + double pulse rings
      for (const c of cs) {
        for (let k = 0; k < 2; k++) {
          const period = 2.6;
          const phase = (((time + (k * period) / 2) % period) + period) % period / period;
          const radius = 3 + phase * 24;
          const alpha = (1 - phase) * 0.45;
          ctx.beginPath();
          ctx.strokeStyle = rgba(alpha);
          ctx.lineWidth = 1.5;
          ctx.arc(c.x, c.y, radius, 0, Math.PI * 2);
          ctx.stroke();
        }
        ctx.fillStyle = solid;
        ctx.shadowColor = solid;
        ctx.shadowBlur = 8;
        ctx.beginPath();
        ctx.arc(c.x, c.y, 2.6, 0, Math.PI * 2);
        ctx.fill();
        ctx.shadowBlur = 0;
      }
    };

    const loop = (ts: number) => {
      if (!startTs) startTs = ts;
      draw((ts - startTs) / 1000);
      raf = requestAnimationFrame(loop);
    };

    resize();
    if (reduced) {
      draw(0);
    } else {
      raf = requestAnimationFrame(loop);
    }

    const ro = new ResizeObserver(() => {
      resize();
      if (reduced) draw(0);
    });
    ro.observe(parent);

    return () => {
      cancelAnimationFrame(raf);
      ro.disconnect();
    };
  }, [accent]);

  return <canvas ref={canvasRef} className="ind__map" aria-hidden="true" />;
}
