/* FlightPlannerMap — SVG map canvas with interactive drawing */

const { useState: useStateFPM, useEffect: useEffectFPM, useRef: useRefFPM, useMemo: useMemoFPM } = React;

function FPMap({
  mode, areaPoly, lawn,
  waypoints, wpSelected, onSelectWp,
  takeoff,
  drawingArea, drawingWp,
  draftPoly, cursor, setCursor,
  onMapClick, onDoubleClick,
  showPositions, showCoverage, showHeatmap, heatmapMode, fov, altitude,
  wpPath, wpShowDistances, droneOverlay, gimbalAngle, photoMode,
  settingTakeoff, metrics,
}) {
  const { VIEW_W, VIEW_H, AOI_POLYGON, PV_ARRAYS, PRIORITY_ZONES } = window.FP_DATA;
  const svgRef = useRefFPM(null);

  const toSvg = (e) => {
    const s = svgRef.current;
    const pt = s.createSVGPoint();
    pt.x = e.clientX; pt.y = e.clientY;
    const { x, y } = pt.matrixTransform(s.getScreenCTM().inverse());
    return [Math.round(x), Math.round(y)];
  };

  const handleClick = (e) => {
    if (e.target.getAttribute && e.target.getAttribute("data-wp") != null) return;
    onMapClick(toSvg(e));
  };
  const handleMove = (e) => setCursor(toSvg(e));

  // Waypoint route path
  const routePath = useMemoFPM(() => {
    if (waypoints.length < 2) return "";
    if (wpPath === "straight") {
      return "M " + waypoints.map(w => w.xy.join(" ")).join(" L ");
    }
    if (wpPath === "rounded") {
      const pts = waypoints.map(w => w.xy);
      let d = `M ${pts[0].join(" ")}`;
      for (let i = 1; i < pts.length; i++) {
        const prev = pts[i-1], cur = pts[i], next = pts[i+1];
        if (!next) { d += ` L ${cur.join(" ")}`; continue; }
        // shortened segment endpoints
        const v1 = [cur[0]-prev[0], cur[1]-prev[1]], v2 = [next[0]-cur[0], next[1]-cur[1]];
        const l1 = Math.hypot(...v1), l2 = Math.hypot(...v2);
        const off = Math.min(l1, l2) * 0.3;
        const p1 = [cur[0] - v1[0]/l1*off, cur[1] - v1[1]/l1*off];
        const p2 = [cur[0] + v2[0]/l2*off, cur[1] + v2[1]/l2*off];
        d += ` L ${p1.join(" ")} Q ${cur.join(" ")} ${p2.join(" ")}`;
      }
      return d;
    }
    // catmull-rom centripetal (curved)
    const pts = waypoints.map(w => w.xy);
    let d = `M ${pts[0].join(" ")}`;
    for (let i = 0; i < pts.length - 1; i++) {
      const p0 = pts[i-1] || pts[i];
      const p1 = pts[i], p2 = pts[i+1], p3 = pts[i+2] || pts[i+1];
      const c1 = [p1[0] + (p2[0]-p0[0])/6, p1[1] + (p2[1]-p0[1])/6];
      const c2 = [p2[0] - (p3[0]-p1[0])/6, p2[1] - (p3[1]-p1[1])/6];
      d += ` C ${c1.join(" ")} ${c2.join(" ")} ${p2.join(" ")}`;
    }
    return d;
  }, [waypoints, wpPath]);

  // Lawnmower SVG path
  const lawnPath = useMemoFPM(() => {
    if (!lawn.path.length) return "";
    return "M " + lawn.path.map(p => p.join(" ")).join(" L ");
  }, [lawn]);

  const areaPath = useMemoFPM(() => {
    if (!areaPoly.length) return "";
    return "M " + areaPoly.map(p => p.join(" ")).join(" L ") + " Z";
  }, [areaPoly]);

  const draftPath = useMemoFPM(() => {
    if (!draftPoly.length) return "";
    let d = "M " + draftPoly.map(p => p.join(" ")).join(" L ");
    if (cursor) d += ` L ${cursor.join(" ")}`;
    return d;
  }, [draftPoly, cursor]);

  // Coverage footprints (rectangles centered on lawn waypoints)
  const footprintW = 2 * altitude * Math.tan((fov/2) * Math.PI / 180); // meters
  const footprintH = footprintW * 0.75;

  // Minimap (gimbal view)
  const selWp = wpSelected != null && waypoints[wpSelected];

  const cursorClass = drawingArea || drawingWp || settingTakeoff ? "drawing" : "";

  return (
    <div className={`fp-mapwrap ${cursorClass}`}>
      <svg
        ref={svgRef}
        viewBox={`0 0 ${VIEW_W} ${VIEW_H}`}
        preserveAspectRatio="xMidYMid slice"
        onClick={handleClick}
        onMouseMove={handleMove}
        onDoubleClick={onDoubleClick}
        className="fp-map-svg"
      >
        <defs>
          <pattern id="fp-grid" width="40" height="40" patternUnits="userSpaceOnUse">
            <path d="M 40 0 L 0 0 0 40" fill="none" stroke="rgba(148,163,184,0.08)" strokeWidth="0.6"/>
          </pattern>
          <pattern id="fp-hatch" width="6" height="6" patternUnits="userSpaceOnUse" patternTransform="rotate(45)">
            <line x1="0" y1="0" x2="0" y2="6" stroke="#ef4444" strokeWidth="1.2" opacity="0.55"/>
          </pattern>
          <pattern id="fp-panel" width="6" height="28" patternUnits="userSpaceOnUse">
            <rect width="5" height="28" fill="rgba(74,144,217,0.35)"/>
          </pattern>
          <linearGradient id="fp-heat" x1="0" y1="0" x2="1" y2="0">
            <stop offset="0" stopColor="rgba(0,0,255,0.55)"/>
            <stop offset="0.25" stopColor="rgba(0,255,255,0.55)"/>
            <stop offset="0.5" stopColor="rgba(0,255,0,0.55)"/>
            <stop offset="0.75" stopColor="rgba(255,255,0,0.55)"/>
            <stop offset="1" stopColor="rgba(255,0,0,0.55)"/>
          </linearGradient>
          <filter id="fp-glow"><feGaussianBlur stdDeviation="2.4"/></filter>
        </defs>

        {/* terrain */}
        <rect width={VIEW_W} height={VIEW_H} fill="#0a0f1a"/>
        <rect width={VIEW_W} height={VIEW_H} fill="url(#fp-grid)"/>

        {/* site AOI hull */}
        <polygon
          points={AOI_POLYGON.map(p => p.join(",")).join(" ")}
          fill="rgba(15,23,42,0.55)"
          stroke="rgba(148,163,184,0.4)"
          strokeWidth="0.8"
          strokeDasharray="2 3"
        />

        {/* PV panel arrays */}
        {PV_ARRAYS.map(a => (
          <g key={a.id}>
            <rect x={a.x} y={a.y} width={a.w} height={a.h} fill="url(#fp-panel)" stroke="rgba(74,144,217,0.5)" strokeWidth="0.4"/>
          </g>
        ))}

        {/* Priority zones (inherited) */}
        {PRIORITY_ZONES.map(z => (
          <g key={z.id}>
            <rect
              x={z.rect[0]} y={z.rect[1]} width={z.rect[2]} height={z.rect[3]}
              fill={z.hatch ? "url(#fp-hatch)" : z.color==="red" ? "rgba(239,68,68,0.12)" : "rgba(212,145,12,0.12)"}
              stroke={z.color === "red" ? "#ef4444" : "#d4910c"}
              strokeWidth="1" strokeDasharray={z.hatch ? "4 2" : "3 3"}
            />
            <text x={z.rect[0] + 4} y={z.rect[1] - 4} fontSize="9" fill={z.color === "red" ? "#ef4444" : "#d4910c"}
                  fontFamily="ui-monospace, Menlo, monospace">
              {z.name}
            </text>
          </g>
        ))}

        {/* Heatmap (area mode) */}
        {mode === "area" && showHeatmap && areaPoly.length > 0 && (
          <g opacity="0.55">
            <clipPath id="fp-heatclip">
              <polygon points={areaPoly.map(p => p.join(",")).join(" ")}/>
            </clipPath>
            <g clipPath="url(#fp-heatclip)">
              {heatmapMode === "overlap" ? (
                <>
                  <rect x="0" y="0" width={VIEW_W} height={VIEW_H} fill="url(#fp-heat)"/>
                  {/* simulated coverage noise */}
                  <circle cx="800" cy="220" r="120" fill="rgba(239,68,68,0.45)"/>
                  <circle cx="400" cy="180" r="90" fill="rgba(0,255,255,0.35)"/>
                </>
              ) : (
                <rect x="0" y="0" width={VIEW_W} height={VIEW_H} fill="rgba(0,255,0,0.35)"/>
              )}
            </g>
          </g>
        )}

        {/* Area polygon */}
        {mode === "area" && areaPoly.length > 0 && (
          <path d={areaPath} fill="rgba(52,211,153,0.08)" stroke="#34d399" strokeWidth="1.5" strokeOpacity="0.85"/>
        )}

        {/* Area polygon vertices */}
        {mode === "area" && areaPoly.length > 0 && areaPoly.map((p, i) => (
          <circle key={i} cx={p[0]} cy={p[1]} r="4" fill="#0a0f1a" stroke="#34d399" strokeWidth="1.6"/>
        ))}

        {/* Draft polygon while drawing */}
        {drawingArea && draftPoly.length > 0 && (
          <>
            <path d={draftPath} fill="rgba(52,211,153,0.06)" stroke="#34d399" strokeWidth="1.2" strokeDasharray="4 3"/>
            {draftPoly.map((p, i) => (
              <circle key={i} cx={p[0]} cy={p[1]} r="3.5" fill="#34d399"/>
            ))}
          </>
        )}

        {/* Coverage footprints */}
        {mode === "area" && showCoverage && lawn.waypoints.map((w, i) => {
          // Rotate footprint to pass angle — approximate
          return (
            <rect key={i}
              x={w[0] - footprintW/2} y={w[1] - footprintH/2}
              width={footprintW} height={footprintH}
              fill="rgba(52,211,153,0.05)"
              stroke="rgba(52,211,153,0.8)"
              strokeWidth="0.4"
            />
          );
        })}

        {/* Lawnmower path */}
        {mode === "area" && lawn.path.length > 0 && (
          <path d={lawnPath} fill="none" stroke="#ef4444" strokeWidth="1.6" strokeOpacity="0.95"/>
        )}

        {/* Lawnmower waypoint dots */}
        {mode === "area" && showPositions && lawn.waypoints.map((w, i) => (
          <circle key={i} cx={w[0]} cy={w[1]} r="2.2" fill="#ef4444"/>
        ))}

        {/* Takeoff line (area) */}
        {mode === "area" && takeoff && lawn.waypoints[0] && (
          <>
            <line x1={takeoff[0]} y1={takeoff[1]} x2={lawn.waypoints[0][0]} y2={lawn.waypoints[0][1]}
                  stroke="#60a5fa" strokeWidth="1.2" strokeDasharray="6 4" strokeOpacity="0.7"/>
          </>
        )}

        {/* Waypoint route */}
        {mode === "waypoint" && waypoints.length >= 2 && (
          <>
            {droneOverlay && (
              <path d={routePath} fill="none" stroke="#60a5fa" strokeWidth="8" strokeOpacity="0.12"
                    strokeLinecap="round" strokeLinejoin="round" filter="url(#fp-glow)"/>
            )}
            <path d={routePath} fill="none" stroke="#60a5fa" strokeWidth="2"
                  strokeLinecap="round" strokeLinejoin="round"/>
          </>
        )}

        {/* Waypoint drone arrows (direction) */}
        {mode === "waypoint" && droneOverlay && waypoints.slice(0, -1).map((w, i) => {
          const n = waypoints[i+1];
          const ang = Math.atan2(n.xy[1]-w.xy[1], n.xy[0]-w.xy[0]) * 180 / Math.PI;
          const mx = (w.xy[0]+n.xy[0])/2, my = (w.xy[1]+n.xy[1])/2;
          return (
            <g key={i} transform={`translate(${mx} ${my}) rotate(${ang})`} opacity="0.7">
              <path d="M -5 -3 L 5 0 L -5 3 Z" fill="#60a5fa"/>
            </g>
          );
        })}

        {/* Waypoint distance labels */}
        {mode === "waypoint" && wpShowDistances && waypoints.slice(0, -1).map((w, i) => {
          const n = waypoints[i+1];
          const d = Math.round(window.FP_HELPERS.dist(w.xy, n.xy));
          const mx = (w.xy[0]+n.xy[0])/2, my = (w.xy[1]+n.xy[1])/2;
          return (
            <g key={i} transform={`translate(${mx} ${my - 10})`}>
              <rect x="-18" y="-7" width="36" height="14" rx="3" fill="rgba(15,23,42,0.9)" stroke="rgba(96,165,250,0.4)"/>
              <text x="0" y="3" fontSize="9" fill="#9ab1cc" textAnchor="middle" fontFamily="ui-monospace, Menlo, monospace">{d}m</text>
            </g>
          );
        })}

        {/* Waypoint FOV footprints (when selected) */}
        {mode === "waypoint" && droneOverlay && selWp && (
          <rect
            x={selWp.xy[0] - 40} y={selWp.xy[1] - 30}
            width="80" height="60"
            fill="rgba(52,211,153,0.06)" stroke="#34d399" strokeWidth="0.8" strokeDasharray="3 2"
          />
        )}

        {/* Waypoint markers */}
        {mode === "waypoint" && waypoints.map((w, i) => {
          const sel = wpSelected === i;
          const isFirst = i === 0, isLast = i === waypoints.length - 1;
          return (
            <g key={i} data-wp={i} style={{ cursor: "pointer" }}
               onClick={(e) => { e.stopPropagation(); onSelectWp(i); }}>
              {sel && (
                <>
                  <circle cx={w.xy[0]} cy={w.xy[1]} r="16" fill="none" stroke="#34d399" strokeWidth="1" opacity="0.5">
                    <animate attributeName="r" values="12;22;12" dur="1.8s" repeatCount="indefinite"/>
                    <animate attributeName="opacity" values="0.5;0;0.5" dur="1.8s" repeatCount="indefinite"/>
                  </circle>
                </>
              )}
              <circle cx={w.xy[0]} cy={w.xy[1]} r="9" fill={sel ? "#34d399" : "#1e293b"} stroke="#34d399" strokeWidth="1.6"/>
              <text x={w.xy[0]} y={w.xy[1]+3} fontSize="9" textAnchor="middle" fill={sel ? "#0a0f1a" : "#34d399"} fontWeight="700">
                {i+1}
              </text>
              {isFirst && <g transform={`translate(${w.xy[0]+11} ${w.xy[1]-14})`}>
                <rect width="22" height="11" rx="2" fill="#34d399"/>
                <text x="11" y="8" fontSize="7" textAnchor="middle" fill="#0a0f1a" fontWeight="700">START</text>
              </g>}
              {isLast && waypoints.length > 1 && <g transform={`translate(${w.xy[0]+11} ${w.xy[1]-14})`}>
                <rect width="20" height="11" rx="2" fill="#60a5fa"/>
                <text x="10" y="8" fontSize="7" textAnchor="middle" fill="#0a0f1a" fontWeight="700">END</text>
              </g>}
            </g>
          );
        })}

        {/* Takeoff marker */}
        {takeoff && (
          <g transform={`translate(${takeoff[0]} ${takeoff[1]})`}>
            <circle r="10" fill="none" stroke="#60a5fa" strokeWidth="1.2" strokeDasharray="3 2"/>
            <circle r="5" fill="#60a5fa"/>
            <path d="M 0 -5 L 0 5 M -5 0 L 5 0" stroke="#0a0f1a" strokeWidth="1"/>
            <text x="12" y="4" fontSize="9" fill="#60a5fa" fontFamily="ui-monospace, Menlo, monospace">HOME</text>
          </g>
        )}

        {/* Cursor crosshair while drawing */}
        {(drawingArea || drawingWp || settingTakeoff) && cursor && (
          <g transform={`translate(${cursor[0]} ${cursor[1]})`} pointerEvents="none">
            <circle r="9" fill="none" stroke={drawingArea ? "#34d399" : drawingWp ? "#60a5fa" : "#60a5fa"} strokeWidth="1.2"/>
            <path d="M -14 0 L -3 0 M 3 0 L 14 0 M 0 -14 L 0 -3 M 0 3 L 0 14"
                  stroke={drawingArea ? "#34d399" : "#60a5fa"} strokeWidth="1"/>
          </g>
        )}
      </svg>

      {/* Coordinate HUD */}
      <div className="fp-hud-tl">
        {(() => { const s = (window.SITES || []).find(x => x.id === localStorage.getItem("skyops_site")) || {}; const pr = window.siteProfile && s.id ? window.siteProfile(s) : null;
          return <><div><Icon name="satellite" size={11}/> {pr ? pr.crs.split(" · ")[0] : "EPSG:25829"} · lat {pr ? pr.lat : "—"} · lng {pr ? pr.lng : "—"}</div>
          <div className="mono">{s.name || "—"} · {(s.id || "").toUpperCase()}</div></>; })()}
      </div>

      {/* Metric HUD */}
      <div className="fp-hud-tr">
        {mode === "area" ? (
          <>
            <div className="fp-hud-m"><span>Area</span><b>{(metrics.area/10000).toFixed(1)} ha</b></div>
            <div className="fp-hud-m"><span>Distance</span><b>{metrics.distance<1000?`${metrics.distance.toFixed(0)} m`:`${(metrics.distance/1000).toFixed(2)} km`}</b></div>
            <div className="fp-hud-m"><span>Flight</span><b>{Math.floor(metrics.time/60)}m {Math.round(metrics.time%60)}s</b></div>
            <div className="fp-hud-m"><span>Waypoints</span><b>{metrics.count}</b></div>
            <div className="fp-hud-m"><span>Photos</span><b>{metrics.photos}</b></div>
          </>
        ) : (
          <>
            <div className="fp-hud-m"><span>Waypoints</span><b>{metrics.count}</b></div>
            <div className="fp-hud-m"><span>Distance</span><b>{metrics.distance<1000?`${metrics.distance.toFixed(0)} m`:`${(metrics.distance/1000).toFixed(2)} km`}</b></div>
            <div className="fp-hud-m"><span>ETA</span><b>{Math.floor(metrics.time/60)}m {Math.round(metrics.time%60)}s</b></div>
            <div className="fp-hud-m"><span>Actions</span><b>{waypoints.reduce((s,w)=>s+(w.actions?.length||0),0)}</b></div>
          </>
        )}
      </div>

      {/* Drawing instructions banner */}
      {(drawingArea || drawingWp || settingTakeoff) && (
        <div className="fp-hud-banner">
          {settingTakeoff && <><Icon name="pin" size={12}/> Click to set home / takeoff point</>}
          {drawingArea && <><Icon name="grid" size={12}/> Click to add polygon vertices · double-click or press Finish to close</>}
          {drawingWp && <><Icon name="crosshair" size={12}/> Click to drop waypoints · double-click to finish</>}
        </div>
      )}

      {/* Legend */}
      <div className="fp-hud-bl">
        {mode === "area" ? (
          <>
            <span><i style={{background:"#34d399"}}/>Survey area</span>
            <span><i style={{background:"#ef4444"}}/>Lawnmower path</span>
            {showCoverage && <span><i style={{background:"rgba(52,211,153,0.4)", border:"1px solid #34d399"}}/>Coverage</span>}
            {showHeatmap && <span><i className="grad"/>Heatmap · {heatmapMode}</span>}
          </>
        ) : (
          <>
            <span><i style={{background:"#60a5fa"}}/>Route</span>
            <span><i style={{background:"#34d399"}}/>Waypoint</span>
            {droneOverlay && <span><i style={{background:"rgba(52,211,153,0.3)", border:"1px solid #34d399"}}/>Drone FOV</span>}
          </>
        )}
      </div>

      {/* Gimbal minimap (waypoint, only when selected) */}
      {mode === "waypoint" && selWp && (
        <GimbalMiniMap wp={selWp} idx={wpSelected} />
      )}
    </div>
  );
}

function GimbalMiniMap({ wp, idx }) {
  // Find last gimbal_tilt / fov action
  let gAngle = -45, fovVal = 84;
  for (const a of wp.actions || []) {
    if (a.type === "gimbal_tilt") gAngle = a.params.angle;
    if (a.type === "take_photo_fixed") gAngle = a.params.angle;
    if (a.type === "set_fov") fovVal = a.params.fov;
  }
  return (
    <div className="fp-minimap">
      <div className="fp-minimap-hd">
        <span>Gimbal view · WP{String(idx+1).padStart(2,"0")}</span>
      </div>
      <svg viewBox="0 0 160 110" className="fp-minimap-svg">
        <defs>
          <linearGradient id="gm-grad" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0" stopColor="#1a2540"/>
            <stop offset="1" stopColor="#0a0f1a"/>
          </linearGradient>
        </defs>
        <rect width="160" height="110" fill="url(#gm-grad)"/>
        {/* Horizon */}
        <line x1="0" y1={55 + gAngle*0.3} x2="160" y2={55 + gAngle*0.3} stroke="rgba(96,165,250,0.4)" strokeWidth="0.6" strokeDasharray="2 2"/>
        {/* FOV cone on ground */}
        <polygon points={`80,${55 + gAngle*0.3} ${80 - fovVal*0.5},110 ${80 + fovVal*0.5},110`}
                 fill="rgba(52,211,153,0.25)" stroke="#34d399" strokeWidth="0.8"/>
        {/* reticle */}
        <circle cx="80" cy="90" r="4" fill="none" stroke="#34d399" strokeWidth="0.8"/>
        <path d="M 80 84 L 80 96 M 74 90 L 86 90" stroke="#34d399" strokeWidth="0.6"/>
      </svg>
      <div className="fp-minimap-ft">
        <span>PITCH {gAngle}°</span>
        <span>FOV {fovVal}°</span>
      </div>
    </div>
  );
}

window.FPMap = FPMap;
