// Map canvas — SVG India map w/ all vector layers
const { useState, useRef, useEffect, useMemo } = React;

const STATE_ID_TO_ABBR = {
  'an':'A&N','ap':'AP','ar':'AR','as':'AS','br':'BR','ch':'CH','ct':'CG','dn':'D&N','dd':'DD','dl':'DL',
  'ga':'GA','gj':'GJ','hp':'HP','hr':'HR','jh':'JH','jk':'JK','ka':'KA','kl':'KL','ld':'LD','ml':'ML',
  'mn':'MN','mh':'MH','mz':'MZ','mp':'MP','na':'NL','or':'OD','pb':'PB','py':'PY','rj':'RJ','sk':'SK',
  'tg':'TG','tn':'TN','tr':'TR','up':'UP','ua':'UK','wb':'WB'
};

// Helper: normalize a state id to work with our data
function stateFill(basemap, isSelected, isHovered) {
  if (basemap === 'satellite') return isSelected ? '#3d5570' : (isHovered ? '#33475a' : '#2a3f4d');
  if (basemap === 'terrain')   return isSelected ? '#d4c4a0' : (isHovered ? '#cdbe98' : '#c8b892');
  if (basemap === 'topo')      return isSelected ? '#f5ebd0' : (isHovered ? '#f2e8ce' : '#f0e6d0');
  // streets (default)
  return isSelected ? '#dfe3d0' : (isHovered ? '#e5e8d6' : '#eaecd8');
}

function MapCanvas({
  basemap, viewMode, layers,
  selectedId, hoveredId, onSelectFeature, onHoverFeature,
  onCursorMove, activeTool
}) {
  const [dims, setDims] = useState({ w: 0, h: 0 });
  const wrapRef = useRef(null);

  useEffect(() => {
    if (!wrapRef.current) return;
    const ro = new ResizeObserver(() => {
      const r = wrapRef.current.getBoundingClientRect();
      setDims({ w: r.width, h: r.height });
    });
    ro.observe(wrapRef.current);
    return () => ro.disconnect();
  }, []);

  const states = window.INDIA_STATES || [];
  const cities = window.CITIES || [];
  const rivers = window.RIVERS || [];
  const detections = window.AI_DETECTIONS || [];
  const assets = window.ASSETS || [];
  const analysis = window.ANALYSIS || {};
  const routes = window.ROUTES || [];

  // viewBox for the map. We frame India tightly.
  const vb = "80 60 480 640"; // crop viewBox

  // 3D perspective tilt
  const tiltStyle = viewMode === '3d'
    ? { transform: 'perspective(1400px) rotateX(52deg) rotateZ(-8deg) scale(0.92)', transformOrigin: '50% 60%' }
    : viewMode === 'globe'
    ? { transform: 'scale(0.85)', transformOrigin: '50% 50%', clipPath: 'circle(48% at 50% 52%)' }
    : {};

  // Handle mouse move on canvas → cursor coord readout (lat/lon approx)
  const handleMove = (e) => {
    const svg = e.currentTarget;
    const pt = svg.createSVGPoint();
    pt.x = e.clientX; pt.y = e.clientY;
    const cur = pt.matrixTransform(svg.getScreenCTM().inverse());
    // Approx map SVG (612x696) to India lat/lon (68-97 E, 8-37 N)
    const lon = 68 + (cur.x / 612) * (97 - 68);
    const lat = 37 - (cur.y / 696) * (37 - 8);
    onCursorMove?.({ lat, lon, x: cur.x, y: cur.y });
  };

  // -- Layer sub-groups (rendered based on layers.<id>.on) --
  const showStates    = layers.states?.on ?? true;
  const showDistricts = layers.districts?.on ?? true;
  const showRivers    = layers.rivers?.on ?? true;
  const showCities    = layers.cities?.on ?? true;
  const showRoads     = layers.roads?.on ?? true;
  const showAssets    = layers.assets?.on ?? true;
  const showAI        = layers.ai?.on ?? true;
  const showBuffer    = layers.buffer?.on ?? true;
  const showRoutes    = layers.routes?.on ?? true;
  const showGraticule = layers.graticule?.on ?? true;
  const showHeat      = layers.heatmap?.on ?? false;
  const showLabels    = layers.labels?.on ?? true;

  // Graticule lines
  const graticule = useMemo(() => {
    const lines = [];
    for (let x = 100; x <= 560; x += 40) lines.push({ k: 'v'+x, x1: x, y1: 80, x2: x, y2: 680 });
    for (let y = 100; y <= 680; y += 40) lines.push({ k: 'h'+y, x1: 80, y1: y, x2: 560, y2: y });
    return lines;
  }, []);

  return (
    <div className={`canvas basemap-${basemap}`} ref={wrapRef}>
      <svg
        className="map-svg"
        viewBox={vb}
        preserveAspectRatio="xMidYMid meet"
        style={tiltStyle}
        onMouseMove={handleMove}
      >
        {/* Sea gradient rect covering behind, especially for satellite/topo */}
        <defs>
          <linearGradient id="sea-grad" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0" stopColor={basemap === 'satellite' ? '#0d1a24' : '#c8d8e6'} />
            <stop offset="1" stopColor={basemap === 'satellite' ? '#050b13' : '#a8c0d4'} />
          </linearGradient>
          <radialGradient id="heat-grad">
            <stop offset="0%"  stopColor="rgba(217,119,6,0.75)" />
            <stop offset="60%" stopColor="rgba(217,119,6,0.20)" />
            <stop offset="100%" stopColor="rgba(217,119,6,0)" />
          </radialGradient>
          <pattern id="hatch" width="4" height="4" patternUnits="userSpaceOnUse" patternTransform="rotate(45)">
            <line x1="0" y1="0" x2="0" y2="4" stroke="rgba(217,119,6,0.55)" strokeWidth="1.5"/>
          </pattern>
        </defs>

        <rect x="80" y="60" width="480" height="640" fill="url(#sea-grad)" />

        {/* Graticule */}
        {showGraticule && (
          <g opacity="0.35">
            {graticule.map(l => (
              <line key={l.k} x1={l.x1} y1={l.y1} x2={l.x2} y2={l.y2}
                stroke={basemap === 'satellite' ? '#3a5060' : '#a8b8c8'} strokeWidth="0.3" strokeDasharray="1 2"/>
            ))}
          </g>
        )}

        {/* States */}
        {showStates && states.map(s => {
          const isSel = selectedId === 'state:'+s.id;
          const isHov = hoveredId === 'state:'+s.id;
          return (
            <path
              key={s.id}
              d={s.d}
              fill={stateFill(basemap, isSel, isHov)}
              stroke={basemap === 'satellite' ? '#4a6070' : '#8a9a70'}
              strokeWidth={isSel ? 1 : 0.35}
              className="state-fill"
              style={{ cursor: activeTool === 'select' ? 'pointer' : 'default' }}
              onMouseEnter={() => onHoverFeature?.('state:'+s.id)}
              onMouseLeave={() => onHoverFeature?.(null)}
              onClick={(e) => {
                e.stopPropagation();
                if (activeTool === 'select') onSelectFeature?.({ kind: 'state', id: s.id, name: s.name });
              }}
            />
          );
        })}

        {/* District-like inner boundaries: draw thinner strokes as inset outlines */}
        {showDistricts && showStates && (
          <g opacity="0.35" pointerEvents="none">
            {states.map(s => (
              <path key={'d'+s.id} d={s.d} fill="none" stroke={basemap === 'satellite' ? '#5a7080' : '#7a8a68'} strokeWidth="0.2" strokeDasharray="0.5 1"/>
            ))}
          </g>
        )}

        {/* Heatmap layer (density) */}
        {showHeat && (
          <g pointerEvents="none">
            {cities.filter(c => c.tier === 'metro').map(c => (
              <circle key={'h'+c.id} cx={c.x} cy={c.y} r="35" fill="url(#heat-grad)" />
            ))}
          </g>
        )}

        {/* Rivers */}
        {showRivers && (
          <g pointerEvents="none">
            {rivers.map(r => (
              <polyline
                key={r.id}
                points={r.points}
                fill="none"
                stroke={basemap === 'satellite' ? '#5aaadd' : '#4a90c8'}
                strokeWidth="1.4"
                strokeLinecap="round"
                strokeLinejoin="round"
                opacity="0.85"
              />
            ))}
          </g>
        )}

        {/* Roads: draw thin lines between metro cities (national highways proxy) */}
        {showRoads && (
          <g pointerEvents="none" opacity="0.7">
            {[
              ['del','mum'],['del','kol'],['del','che'],['del','blr'],
              ['mum','blr'],['mum','che'],['blr','che'],['blr','hyd'],
              ['mum','ahm'],['del','jai'],['del','luk'],['kol','che'],
              ['hyd','che'],['mum','pun'],['del','ptn']
            ].map((pair, i) => {
              const a = cities.find(c => c.id === pair[0]);
              const b = cities.find(c => c.id === pair[1]);
              if (!a || !b) return null;
              return (
                <line key={i} x1={a.x} y1={a.y} x2={b.x} y2={b.y}
                  stroke={basemap === 'satellite' ? '#c94a3a' : '#c94a3a'}
                  strokeWidth="0.6" strokeDasharray="2 1.5"/>
              );
            })}
          </g>
        )}

        {/* Route optimization */}
        {showRoutes && (
          <g pointerEvents="none">
            {routes.map((r, i) => (
              <polyline key={i} points={r.points} fill="none"
                stroke="#d97706" strokeWidth="1.6" strokeLinecap="round" strokeDasharray="4 2"/>
            ))}
          </g>
        )}

        {/* Buffer analysis rings */}
        {showBuffer && analysis.buffer && (
          <g pointerEvents="none">
            {analysis.buffer.radii.map((r, i) => (
              <circle key={i} cx={analysis.buffer.cx} cy={analysis.buffer.cy} r={r}
                fill="rgba(217,119,6,0.05)" stroke="#d97706" strokeWidth="0.5" strokeDasharray="1.5 1.5"/>
            ))}
            <circle cx={analysis.buffer.cx} cy={analysis.buffer.cy} r="1.5" fill="#d97706"/>
          </g>
        )}

        {/* AI Detections */}
        {showAI && (
          <g>
            {detections.map(d => {
              const isSel = selectedId === 'ai:'+d.id;
              return (
                <g key={d.id} className="feature-marker"
                  onMouseEnter={() => onHoverFeature?.('ai:'+d.id)}
                  onMouseLeave={() => onHoverFeature?.(null)}
                  onClick={(e) => {
                    e.stopPropagation();
                    if (activeTool === 'select') onSelectFeature?.({ kind: 'ai', id: d.id, name: d.kind, data: d });
                  }}>
                  <rect x={d.x - d.w/2} y={d.y - d.h/2} width={d.w} height={d.h}
                    fill={isSel ? "url(#hatch)" : "rgba(217,119,6,0.14)"}
                    stroke="#d97706" strokeWidth={isSel ? 1.2 : 0.7} strokeDasharray="1.5 1"/>
                </g>
              );
            })}
          </g>
        )}

        {/* Assets */}
        {showAssets && (
          <g>
            {assets.map(a => {
              const color = a.status === 'ok' ? '#2f7d4f' : a.status === 'warn' ? '#d97706' : '#b83a3a';
              const isSel = selectedId === 'asset:'+a.id;
              return (
                <g key={a.id} className="feature-marker"
                  onMouseEnter={() => onHoverFeature?.('asset:'+a.id)}
                  onMouseLeave={() => onHoverFeature?.(null)}
                  onClick={(e) => {
                    e.stopPropagation();
                    if (activeTool === 'select') onSelectFeature?.({ kind: 'asset', id: a.id, name: a.kind, data: a });
                  }}>
                  <rect x={a.x - 2} y={a.y - 2} width="4" height="4"
                    fill={color} stroke={isSel ? "#0a1a35" : "white"} strokeWidth="0.5" />
                </g>
              );
            })}
          </g>
        )}

        {/* Cities */}
        {showCities && (
          <g>
            {cities.map(c => {
              const isMetro = c.tier === 'metro';
              const r = isMetro ? 3 : 2;
              const isSel = selectedId === 'city:'+c.id;
              return (
                <g key={c.id} className="feature-marker"
                  onMouseEnter={() => onHoverFeature?.('city:'+c.id)}
                  onMouseLeave={() => onHoverFeature?.(null)}
                  onClick={(e) => {
                    e.stopPropagation();
                    if (activeTool === 'select') onSelectFeature?.({ kind: 'city', id: c.id, name: c.name, data: c });
                  }}>
                  <circle cx={c.x} cy={c.y} r={r+1.5} fill="white" opacity={isSel ? 0.8 : 0.5}/>
                  <circle cx={c.x} cy={c.y} r={r} fill={isMetro ? '#0a1a35' : '#2d5aa0'} stroke="white" strokeWidth="0.5"/>
                  {showLabels && (
                    <text x={c.x + r + 2} y={c.y + 2} fontSize={isMetro ? 6 : 5} fill={basemap === 'satellite' ? '#f5f1e8' : '#0a1a35'}
                      style={{ paintOrder: 'stroke', stroke: basemap === 'satellite' ? '#0a1a35' : 'white', strokeWidth: 1.5 }}>
                      {c.name}
                    </text>
                  )}
                </g>
              );
            })}
          </g>
        )}

        {/* Cursor coord tooltip on hover */}
        {hoveredId && hoveredId.startsWith('city:') && (() => {
          const c = cities.find(x => 'city:'+x.id === hoveredId);
          if (!c) return null;
          return (
            <g pointerEvents="none">
              <circle cx={c.x} cy={c.y} r="8" fill="none" stroke="#d97706" strokeWidth="0.8" strokeDasharray="1.5 1"/>
            </g>
          );
        })()}
      </svg>
    </div>
  );
}

window.MapCanvas = MapCanvas;
