/* global window, React */
// ============================================================
// Route Map — simplified US outline with pickup/swap/delivery
// pins, route line, and metadata panel. Used in:
//   - Routing feasibility tab (single trip line)
//   - Edit drawer · Orders & drops tab (preview move impact)
// ============================================================

// Highly simplified US continental outline as an SVG path (Lng/Lat-like).
// Coordinates are baked in a -130..-65 lng × 24..50 lat box.
const US_OUTLINE_PATH = "M -124.7 48.4 L -124.4 42.0 L -124.2 40.4 L -124.0 38.0 L -122.5 37.5 L -120.6 34.5 L -117.3 32.5 L -114.7 32.7 L -111.0 31.3 L -108.2 31.8 L -106.5 31.8 L -103.3 28.9 L -99.0 26.2 L -97.4 25.9 L -97.1 27.5 L -94.0 29.7 L -89.2 30.0 L -88.0 30.4 L -85.0 29.7 L -83.5 28.0 L -81.1 25.2 L -80.1 25.8 L -80.5 27.9 L -81.5 30.7 L -81.3 31.9 L -80.8 32.7 L -78.9 33.7 L -77.0 35.0 L -75.5 35.5 L -75.5 37.5 L -76.0 38.5 L -76.5 39.0 L -75.0 39.5 L -74.0 40.5 L -74.0 41.5 L -71.0 41.6 L -71.0 42.0 L -70.6 41.7 L -70.0 41.9 L -70.6 42.6 L -70.7 43.6 L -69.0 44.2 L -67.0 44.5 L -67.0 45.2 L -68.0 47.0 L -69.0 47.5 L -71.0 45.0 L -75.0 45.0 L -76.0 44.0 L -78.0 43.6 L -79.5 43.3 L -83.0 41.7 L -83.5 41.7 L -83.0 42.3 L -82.5 43.0 L -82.4 44.0 L -82.1 45.0 L -83.5 45.8 L -83.6 46.0 L -84.4 45.9 L -84.7 46.0 L -85.0 46.0 L -86.8 41.7 L -87.5 41.7 L -88.0 47.2 L -90.2 46.7 L -90.4 47.7 L -94.7 49.4 L -95.2 49.0 L -96.0 49.0 L -123.3 49.0 L -124.7 48.4 Z";

function lngLatToSvg(lng, lat, w, h) {
  // bounding box: lng -125 to -66 (59 deg), lat 24 to 50 (26 deg)
  const padX = 30, padY = 18;
  const x = padX + ((lng + 125) / 59) * (w - padX * 2);
  // svg y grows down; lat 50 → top
  const y = padY + ((50 - lat) / 26) * (h - padY * 2);
  return { x, y };
}

function RouteMap({ trip, width = 720, height = 360, showLegend = true, extraTrips = null, highlightDropId = null }) {
  const W = width, H = height;
  const from = (window.CITY_COORDS || {})[trip.route.from];
  const to   = (window.CITY_COORDS || {})[trip.route.to];
  const wpKey = `${trip.route.from}|${trip.route.to}`;
  const waypoints = (window.ROUTE_WAYPOINTS || {})[wpKey] || [];

  if (!from || !to) {
    return <div className="map-empty">No route coordinates for {trip.route.from} → {trip.route.to}</div>;
  }

  const stops = [
    { ...from, role: 'pickup', label: from.label, sub: 'Pickup · ' + (trip.routing?.nodes?.[0]?.time || '') },
    ...waypoints.map(w => ({ ...w, role: 'swap', sub: '' })),
    { ...to,   role: 'delivery', label: to.label, sub: 'Delivery · ' + (trip.routing?.nodes?.[2]?.time || '') },
  ];

  // Build the route polyline points
  const points = stops.map(s => lngLatToSvg(s.lng, s.lat, W, H));
  const polyline = points.map(p => `${p.x},${p.y}`).join(' ');

  // Major cities for context
  const contextCities = [
    { lng: -87.65, lat: 41.85, n: 'Chicago' },
    { lng: -96.80, lat: 32.78, n: 'Dallas' },
    { lng: -80.19, lat: 25.76, n: 'Miami' },
    { lng: -118.24, lat: 34.05, n: 'LA' },
    { lng: -122.33, lat: 47.61, n: 'Seattle' },
    { lng: -74.00, lat: 40.71, n: 'NYC' },
    { lng: -84.39, lat: 33.75, n: 'Atlanta' },
    { lng: -104.99, lat: 39.74, n: 'Denver' },
  ].filter(c => !stops.some(s => Math.abs(s.lng - c.lng) < 0.5 && Math.abs(s.lat - c.lat) < 0.5));

  // Build US outline points
  const outlinePoints = US_OUTLINE_PATH.split(/\s+/).filter(t => /^-?\d/.test(t)).reduce((acc, tok, i, arr) => {
    if (i % 2 === 0) acc.push({ lng: parseFloat(tok), lat: parseFloat(arr[i + 1]) });
    return acc;
  }, []);
  const outlineSvgPath = outlinePoints.map((p, i) => {
    const { x, y } = lngLatToSvg(p.lng, p.lat, W, H);
    return (i === 0 ? 'M' : 'L') + ' ' + x.toFixed(1) + ' ' + y.toFixed(1);
  }).join(' ') + ' Z';

  // Render extra trips (e.g. consolidation / move-drops preview)
  const renderExtraTrip = (et, idx) => {
    const ef = (window.CITY_COORDS || {})[et.route.from];
    const et2 = (window.CITY_COORDS || {})[et.route.to];
    if (!ef || !et2) return null;
    const ek = `${et.route.from}|${et.route.to}`;
    const ewp = (window.ROUTE_WAYPOINTS || {})[ek] || [];
    const epts = [ef, ...ewp, et2].map(s => lngLatToSvg(s.lng, s.lat, W, H));
    const epoly = epts.map(p => `${p.x},${p.y}`).join(' ');
    return (
      <g key={'extra-' + idx} className="map-extra">
        <polyline points={epoly} fill="none" stroke="#9B7DD0" strokeWidth="2" strokeDasharray="6 4" opacity="0.7" />
        {epts.map((p, i) => (
          <circle key={i} cx={p.x} cy={p.y} r={i === 0 || i === epts.length - 1 ? 5 : 3} fill="#5A3FB8" opacity="0.8" />
        ))}
      </g>
    );
  };

  return (
    <div className="route-map">
      <svg viewBox={`0 0 ${W} ${H}`} width="100%" height={H} className="route-map__svg">
        <defs>
          <linearGradient id="rmRouteGrad" x1="0" y1="0" x2="1" y2="0">
            <stop offset="0%"  stopColor="#2F7A4A" />
            <stop offset="60%" stopColor="#E8A93C" />
            <stop offset="100%" stopColor="#C13333" />
          </linearGradient>
          <filter id="rmShadow" x="-20%" y="-20%" width="140%" height="140%">
            <feGaussianBlur stdDeviation="2" result="b" />
            <feOffset dy="1" />
            <feComponentTransfer><feFuncA type="linear" slope="0.25"/></feComponentTransfer>
            <feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>
          </filter>
        </defs>

        {/* Background grid (latitude lines) */}
        {[30, 35, 40, 45].map(lat => {
          const { y } = lngLatToSvg(-95, lat, W, H);
          return <line key={lat} x1="0" x2={W} y1={y} y2={y} stroke="#E8E5DA" strokeWidth="0.5" strokeDasharray="2 4" />;
        })}
        {[-120, -110, -100, -90, -80, -70].map(lng => {
          const { x } = lngLatToSvg(lng, 35, W, H);
          return <line key={lng} y1="0" y2={H} x1={x} x2={x} stroke="#E8E5DA" strokeWidth="0.5" strokeDasharray="2 4" />;
        })}

        {/* US outline */}
        <path d={outlineSvgPath} fill="#F5F3EC" stroke="#C9C5B5" strokeWidth="1" />

        {/* Context cities */}
        {contextCities.map((c, i) => {
          const p = lngLatToSvg(c.lng, c.lat, W, H);
          return (
            <g key={i} opacity="0.45">
              <circle cx={p.x} cy={p.y} r="2.5" fill="#A8A498" />
              <text x={p.x + 6} y={p.y + 4} fontSize="9" fontFamily="JetBrains Mono, monospace" fill="#8E8B7E">{c.n}</text>
            </g>
          );
        })}

        {/* Route polyline — primary */}
        <polyline
          points={polyline}
          fill="none"
          stroke="url(#rmRouteGrad)"
          strokeWidth="3.5"
          strokeLinecap="round"
          strokeLinejoin="round"
          filter="url(#rmShadow)"
        />

        {/* Extra trips (for move-drops preview etc.) */}
        {extraTrips && extraTrips.map(renderExtraTrip)}

        {/* Stops */}
        {stops.map((s, i) => {
          const p = points[i];
          const isFirst = i === 0;
          const isLast = i === stops.length - 1;
          const color = isFirst ? '#2F7A4A' : isLast ? '#C13333' : '#E8893C';
          const ring  = isFirst ? '#1F5A35' : isLast ? '#6B1A1A' : '#A8631F';
          const r     = isFirst || isLast ? 8 : 5.5;
          const labelDx = isLast ? -8 : 12;
          const anchor = isLast ? 'end' : 'start';
          return (
            <g key={i}>
              <circle cx={p.x} cy={p.y} r={r + 3} fill={color} opacity="0.15" />
              <circle cx={p.x} cy={p.y} r={r} fill={color} stroke={ring} strokeWidth="1.5" />
              {(isFirst || isLast) && <text x={p.x} y={p.y + 4} fontSize="9" fontWeight="700" textAnchor="middle" fill="white">{isFirst ? 'P' : 'D'}</text>}
              <text x={p.x + labelDx} y={p.y - 6} fontSize="11" fontFamily="Source Serif 4, serif" fontWeight="600" textAnchor={anchor} fill="#1B1A14">
                {s.label}
              </text>
              {s.sub && (
                <text x={p.x + labelDx} y={p.y + 12} fontSize="9.5" fontFamily="JetBrains Mono, monospace" textAnchor={anchor} fill="#5A584D">
                  {s.sub}
                </text>
              )}
            </g>
          );
        })}

        {/* Trip metadata pinned bottom-left */}
        <g transform={`translate(12, ${H - 40})`}>
          <rect x="0" y="-12" width="200" height="40" rx="4" fill="white" stroke="#E8E5DA" />
          <text x="10" y="2" fontSize="9" fontFamily="JetBrains Mono, monospace" fontWeight="700" letterSpacing="0.6" fill="#8E8B7E">{trip.id} · {trip.mode || 'FTL'}</text>
          <text x="10" y="15" fontSize="11" fontFamily="Source Serif 4, serif" fontWeight="600" fill="#1B1A14">
            {Math.round(haversine(from, to))} mi · {trip.routing?.hos?.drive || '—'}
          </text>
          <text x="10" y="26" fontSize="9.5" fontFamily="JetBrains Mono, monospace" fill="#5A584D">
            {stops.length - 2} swap{stops.length - 2 === 1 ? '' : 's'} · {trip.fleetLabel}
          </text>
        </g>
      </svg>

      {showLegend && (
        <div className="route-map__legend">
          <span className="rml-item"><span className="rml-dot" style={{ background: '#2F7A4A' }}></span> Pickup</span>
          <span className="rml-item"><span className="rml-dot" style={{ background: '#E8893C' }}></span> Driver swap / fuel</span>
          <span className="rml-item"><span className="rml-dot" style={{ background: '#C13333' }}></span> Delivery</span>
          {extraTrips && <span className="rml-item"><span className="rml-dot" style={{ background: '#5A3FB8' }}></span> Adjacent / preview</span>}
        </div>
      )}
    </div>
  );
}

// great-circle distance, miles
function haversine(a, b) {
  if (!a || !b) return 0;
  const toRad = (d) => d * Math.PI / 180;
  const R = 3959; // miles
  const dLat = toRad(b.lat - a.lat);
  const dLng = toRad(b.lng - a.lng);
  const h = Math.sin(dLat / 2) ** 2 + Math.cos(toRad(a.lat)) * Math.cos(toRad(b.lat)) * Math.sin(dLng / 2) ** 2;
  return 2 * R * Math.asin(Math.sqrt(h));
}

Object.assign(window, { RouteMap });
