// Fleet Dashboard — World Map (Acme Bank light theme)
// Light map bg, white cluster cards, green brand accents

/* --- Cluster Card (HTML-rendered, light theme) --- */

function ClusterCard({ cluster, mode, placementData, upgradeData }) {
  let borderColor = '#059669';
  let dimmed = false;
  let glowColor = null;
  let badge = null;
  let extraInfo = null;
  const healthColor = cluster.health === 'healthy' ? '#059669'
    : cluster.health === 'degraded' ? '#D97706' : '#DC2626';

  if (mode === 'placement' && placementData) {
    const boundList = placementData.boundClusters || [placementData.boundCluster];
    if (boundList.includes(cluster.id)) {
      borderColor = '#059669';
      glowColor = '#059669';
      badge = { label: '✓  BOUND', color: '#065F46', bg: '#D1FAE5' };
      extraInfo = placementData.resources[0];
    } else if (placementData.rejectedClusters.includes(cluster.id)) {
      borderColor = '#DC2626';
      dimmed = true;
      badge = { label: '✗  NOT SELECTED', color: '#991B1B', bg: '#FEE2E2' };
      extraInfo = placementData.rejectReason;
    }
  }

  if (mode === 'upgrade' && upgradeData) {
    const stage = upgradeData.stages.find(s => s.cluster === cluster.id);
    if (stage) {
      if (stage.status === 'completed') {
        borderColor = '#059669';
        badge = { label: `✓  Stage ${stage.id} Complete · ${stage.duration}`, color: '#065F46', bg: '#D1FAE5' };
      } else if (stage.status === 'waiting-approval') {
        borderColor = '#D97706';
        glowColor = '#D97706';
        badge = { label: `⏸  Stage ${stage.id} · Awaiting Approval`, color: '#92400E', bg: '#FEF3C7' };
      } else if (stage.status === 'in-progress') {
        borderColor = '#1D4ED8';
        glowColor = '#3B82F6';
        badge = { label: `▶  Stage ${stage.id} · In Progress`, color: '#1D4ED8', bg: '#DBEAFE' };
      } else {
        borderColor = FC.chromeSubtle;
        dimmed = true;
        badge = { label: `⏳  Stage ${stage.id} · Queued`, color: FC.chromeSubtle, bg: '#F3F4F6' };
      }
    }
  }

  const cardStyles = {
    width: 178,
    padding: '14px 16px',
    background: dimmed ? 'rgba(255,255,255,0.75)' : '#FFFFFF',
    border: `1.5px ${dimmed ? 'dashed' : 'solid'} ${borderColor}${dimmed ? '88' : ''}`,
    borderRadius: 12,
    opacity: dimmed ? 0.55 : 1,
    transition: 'opacity 0.4s, box-shadow 0.4s',
    pointerEvents: 'auto',
    boxShadow: '0 1px 3px rgba(0,0,0,0.08), 0 2px 8px rgba(0,0,0,0.04)',
  };
  if (glowColor) {
    cardStyles.boxShadow = `0 1px 3px rgba(0,0,0,0.08), 0 0 20px ${glowColor}18, 0 0 40px ${glowColor}08`;
  }

  return (
    <div style={cardStyles}>
      {/* Region label */}
      <div style={{
        fontSize: 9.5, color: FC.chromeSubtle, fontFamily: FC.font,
        textTransform: 'uppercase', letterSpacing: 2, fontWeight: 600, marginBottom: 10,
      }}>
        {cluster.regionLabel}
      </div>

      {/* Cluster name + health */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 6 }}>
        <div className={dimmed ? '' : 'fleet-live-dot'} style={{
          width: 8, height: 8, borderRadius: '50%', background: healthColor,
          boxShadow: dimmed ? 'none' : `0 0 6px ${healthColor}40`,
          flexShrink: 0,
        }} />
        <span style={{
          fontFamily: FC.mono, fontSize: 13,
          fontWeight: 600, color: FC.chromeText, letterSpacing: -0.2,
        }}>
          {cluster.name}
        </span>
      </div>

      {/* Version + nodes */}
      <div style={{
        fontSize: 11.5, color: FC.chromeMuted,
        fontFamily: FC.font, marginBottom: 3, paddingLeft: 16,
      }}>
        v{cluster.k8sVersion} · {cluster.nodeCount} nodes
      </div>

      {/* Labels */}
      <div style={{
        fontSize: 10.5, color: FC.chromeSubtle,
        fontFamily: FC.mono, paddingLeft: 16,
      }}>
        {cluster.region}
      </div>

      {/* Badge */}
      {badge && (
        <div style={{
          marginTop: 12, padding: '6px 10px', borderRadius: 6,
          background: badge.bg, color: badge.color,
          fontFamily: FC.mono, fontSize: 10.5,
          fontWeight: 600, letterSpacing: 0.2,
        }}>
          {badge.label}
        </div>
      )}

      {/* Extra info */}
      {extraInfo && (
        <div style={{
          marginTop: 5, paddingLeft: 10, fontSize: 10,
          color: dimmed ? '#DC2626' : '#059669',
          fontFamily: FC.mono, opacity: 0.85,
        }}>
          ↳ {extraInfo}
        </div>
      )}
    </div>
  );
}

/* --- Fleet Hub Badge (HTML, light theme) --- */

function FleetHubBadge({ fleetHub = FLEET_HUB }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6, pointerEvents: 'auto' }}>
      <div style={{
        width: 50, height: 50,
        background: '#FFFFFF',
        border: `1.5px solid ${FC.primary}`,
        borderRadius: 10,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        boxShadow: `0 1px 3px rgba(0,0,0,0.08), 0 0 16px rgba(13,124,74,0.10)`,
        position: 'relative',
      }}>
        <span style={{ fontSize: 24, color: FC.primary, lineHeight: 1 }}>⬡</span>
        <div className="fleet-hub-ring" style={{
          position: 'absolute', inset: -10,
          border: `1px solid ${FC.primary}`,
          borderRadius: 14, opacity: 0.15,
        }} />
      </div>
      <div style={{ textAlign: 'center' }}>
        <div style={{ fontSize: 10.5, color: FC.primary, fontFamily: FC.mono, fontWeight: 500 }}>
          {fleetHub.name}
        </div>
        <div style={{ fontSize: 9, color: FC.chromeSubtle, fontFamily: FC.font, marginTop: 1 }}>
          Fleet Hub · Azure
        </div>
      </div>
    </div>
  );
}

/* --- World Map (composite, light theme) --- */

function WorldMap({ mode, placementData, upgradeData, clusters = CLUSTERS, fleetHub = FLEET_HUB, children }) {
  const outerRef = React.useRef(null);
  const [mapSize, setMapSize] = React.useState({ w: 0, h: 0 });

  React.useLayoutEffect(() => {
    const el = outerRef.current;
    if (!el) return;
    function measure() {
      const { width: cw, height: ch } = el.getBoundingClientRect();
      if (cw === 0 || ch === 0) return;
      const aspect = 2; // 1000:500
      let w, h;
      if (cw / ch > aspect) { h = ch; w = ch * aspect; }
      else { w = cw; h = cw / aspect; }
      setMapSize({ w, h });
    }
    measure();
    const ro = new ResizeObserver(measure);
    ro.observe(el);
    return () => ro.disconnect();
  }, []);

  const pct = (svgX, svgY) => ({
    left: `${(svgX / 1000) * 100}%`,
    top: `${(svgY / 500) * 100}%`,
  });

  function lineProps(cluster) {
    if (mode === 'placement' && placementData) {
      const boundList = placementData.boundClusters || [placementData.boundCluster];
      const bound = boundList.includes(cluster.id);
      return {
        stroke: bound ? '#059669' : FC.chromeSubtle,
        strokeWidth: bound ? 1.6 : 0.7,
        strokeDasharray: bound ? 'none' : '6 4',
        opacity: bound ? 0.5 : 0.2,
        isBound: bound,
      };
    }
    if (mode === 'upgrade' && upgradeData) {
      const stage = upgradeData.stages.find(s => s.cluster === cluster.id);
      const done = stage && stage.status === 'completed';
      return {
        stroke: done ? '#059669' : FC.chromeSubtle,
        strokeWidth: done ? 1.4 : 0.7,
        strokeDasharray: done ? 'none' : '6 4',
        opacity: done ? 0.45 : 0.2,
        isBound: false,
      };
    }
    return { stroke: FC.primary, strokeWidth: 0.6, strokeDasharray: '4 6', opacity: 0.2, isBound: false };
  }

  const hx = fleetHub.x, hy = fleetHub.y;

  return (
    <div ref={outerRef} style={{
      width: '100%', height: '100%',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      overflow: 'visible', position: 'relative',
    }}>
      {mapSize.w > 0 && (
        <div style={{ position: 'relative', width: mapSize.w, height: mapSize.h }}>

          {/* Layer 1: SVG Background */}
          <svg viewBox="0 0 1000 500" preserveAspectRatio="none"
            style={{ position: 'absolute', inset: 0, width: '100%', height: '100%' }}>
            <defs>
              {/* Dot pattern for continent masking */}
              <pattern id="landDotPat" x="0" y="0" width="13" height="13" patternUnits="userSpaceOnUse">
                <circle cx="6.5" cy="6.5" r="2.6" fill="white" />
              </pattern>
              <mask id="landDotMask">
                <rect width="1000" height="500" fill="url(#landDotPat)" />
              </mask>

              {/* Background radial glow */}
              <radialGradient id="mapGlow" cx="50%" cy="40%" r="60%">
                <stop offset="0%" stopColor="#0D7C4A" stopOpacity="0.03" />
                <stop offset="100%" stopColor={FC.chromeBg} stopOpacity="0" />
              </radialGradient>

              {/* Cluster region glows */}
              {clusters.map(c => {                let glowC = 'rgba(13,124,74,0.05)';
                if (mode === 'placement' && placementData) {
                  glowC = placementData.boundCluster === c.id
                    ? 'rgba(5,150,105,0.10)'
                    : 'rgba(13,124,74,0.03)';
                }
                if (mode === 'upgrade' && upgradeData) {
                  const st = upgradeData.stages.find(s => s.cluster === c.id);
                  glowC = st && st.status === 'waiting-approval'
                    ? 'rgba(217,119,6,0.08)' : 'rgba(13,124,74,0.03)';
                }
                return (
                  <radialGradient key={c.id} id={`glow-${c.id}`}
                    cx={c.x / 1000} cy={c.y / 500} r="0.12"
                    gradientUnits="objectBoundingBox">
                    <stop offset="0%" stopColor={glowC.replace(/[\d.]+\)$/, '1)')} stopOpacity={parseFloat(glowC.match(/[\d.]+\)$/)[0])} />
                    <stop offset="100%" stopColor={glowC.replace(/[\d.]+\)$/, '1)')} stopOpacity="0" />
                  </radialGradient>
                );
              })}
            </defs>

            {/* Background */}
            <rect width="1000" height="500" fill={FC.chromeBg} />
            <rect width="1000" height="500" fill="url(#mapGlow)" />

            {/* Subtle grid lines */}
            {[125, 250, 375].map(y => (
              <line key={`h${y}`} x1="0" y1={y} x2="1000" y2={y}
                stroke={FC.chromeBorder} strokeWidth="0.4" opacity="0.5" />
            ))}
            {[200, 400, 600, 800].map(x => (
              <line key={`v${x}`} x1={x} y1="0" x2={x} y2="500"
                stroke={FC.chromeBorder} strokeWidth="0.4" opacity="0.5" />
            ))}

            {/* Continent dot matrix */}
            <g mask="url(#landDotMask)">
              {CONTINENT_PATHS.map((d, i) => (
                <path key={i} d={d} fill="rgba(13,124,74,0.12)" />
              ))}
            </g>

            {/* Region glows */}
            {clusters.map(c => (
              <ellipse key={c.id} cx={c.x} cy={c.y}
                rx="100" ry="70" fill={`url(#glow-${c.id})`} />
            ))}

            {/* Connection lines */}
            {clusters.map(c => {
              const lp = lineProps(c);
              const pathD = `M${hx},${hy} L${c.x},${c.y}`;
              return (
                <g key={c.id}>
                  <line x1={hx} y1={hy} x2={c.x} y2={c.y}
                    stroke={lp.stroke} strokeWidth={lp.strokeWidth}
                    strokeDasharray={lp.strokeDasharray} opacity={lp.opacity} />
                  {lp.isBound && (
                    <>
                      <circle r="3" fill="#059669" opacity="0.8">
                        <animateMotion dur="2.4s" repeatCount="indefinite" path={pathD} />
                      </circle>
                      <circle r="3" fill="#059669" opacity="0.8">
                        <animateMotion dur="2.4s" repeatCount="indefinite" begin="1.2s" path={pathD} />
                      </circle>
                    </>
                  )}
                </g>
              );
            })}
          </svg>

          {/* Layer 2: HTML Cluster Cards */}
          <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }}>
            {/* Fleet Hub */}
            <div style={{
              position: 'absolute', ...pct(hx, hy),
              transform: 'translate(-50%, -50%)',
            }}>
              <FleetHubBadge fleetHub={fleetHub} />
            </div>

            {/* Cluster cards — offset horizontally to prevent overlap */}
            {clusters.map(c => {
              const xPct = c.x / 1000;
              const tx = xPct < 0.4 ? '-70%' : xPct > 0.6 ? '-30%' : '-50%';
              return (
                <div key={c.id} style={{
                  position: 'absolute', ...pct(c.x, c.y),
                  transform: `translate(${tx}, -50%)`,
                }}>
                  <ClusterCard cluster={c} mode={mode}
                    placementData={placementData} upgradeData={upgradeData} />
                </div>
              );
            })}
          </div>

          {/* Layer 3: View-specific overlays */}
          {children && (
            <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }}>
              {children}
            </div>
          )}
        </div>
      )}
    </div>
  );
}

Object.assign(window, { WorldMap, ClusterCard, FleetHubBadge });
