// ─────────────────────────────────────────────────────────────
// THE POLYGON MARK — the PAS-tier evolution of the Target device.
//
// Same grammar as target-mark.jsx (ink hairlines, ONE red ring +
// ONE red dot, crosshair, corner-bleed placement, three states) but
// the concentric circles become concentric regular POLYGONS. The
// platform pages use the circle Target; the complete-PAS pages use a
// faceted sibling. `sides` dials how hard/soft it reads:
//   8  = octagon (hard, angular)
//   10 = decagon (softer, closer to the circle)  ← PAS default
//   12 = dodecagon (softest, almost a circle)
//
// State drives meaning (identical to the Target):
//   'whole' · 'fragmented' · 'resolved'
// ─────────────────────────────────────────────────────────────

const PM_INK = '#37474F';
const PM_RED = '#EE4B46';

// Flat-top regular n-gon path at circumradius r (n even ⇒ flat top + bottom).
function polyPath(cx, cy, r, n) {
  let d = '';
  for (let k = 0; k < n; k++) {
    const a = -Math.PI / 2 + Math.PI / n + k * (2 * Math.PI / n);
    const x = cx + r * Math.cos(a);
    const y = cy + r * Math.sin(a);
    d += (k === 0 ? 'M' : 'L') + x.toFixed(2) + ' ' + y.toFixed(2) + ' ';
  }
  return d + 'Z';
}

function PolyMark({
  size = 720,
  place = {},
  sides = 10,
  rings = [0.94, 0.78, 0.62, 0.46],   // fractions of circumradius
  redRing = 0.30,
  redWidth = null,
  dot = true,
  dotR = 11,
  crosshair = false,
  inverse = false,
  state = 'whole',
  baseOpacity = 1,
  inkScale = 1,
  redColor = PM_RED,
}) {
  const stroke = inverse ? '#FFFFFF' : PM_INK;
  const c = size / 2;
  const R = size / 2;
  const fragmented = state === 'fragmented';
  const resolved = state === 'resolved';

  // exile vector — up-left, back toward where the owned centre belongs.
  const exile = { x: c - R * 0.34, y: c - R * 0.62 };

  return (
    <svg
      width={size} height={size} viewBox={`0 0 ${size} ${size}`}
      style={{ position: 'absolute', display: 'block', overflow: 'visible', opacity: baseOpacity, ...place }}
      aria-hidden="true"
    >
      {crosshair && (
        <g stroke={stroke} strokeWidth="0.5" opacity={(inverse ? 0.22 : 0.16) * inkScale}>
          <line x1={c - R} y1={c} x2={c + R} y2={c} />
          <line x1={c} y1={c - R} x2={c} y2={c + R} />
        </g>
      )}
      {rings.map((f, i) => {
        const broken = fragmented && i === 0; // outermost polygon breaks
        return (
          <path key={i} d={polyPath(c, c, R * f, sides)} fill="none"
            stroke={stroke}
            strokeWidth={resolved ? 0.9 : 0.75}
            strokeLinejoin="miter"
            strokeDasharray={broken ? '5 9' : undefined}
            opacity={((inverse ? 0.16 : 0.14) + (rings.length - i) * (resolved ? 0.07 : 0.05)) * inkScale} />
        );
      })}
      {redRing != null && !fragmented && (
        <path d={polyPath(c, c, R * redRing, sides)} fill="none" stroke={redColor}
          strokeLinejoin="miter"
          strokeWidth={redWidth != null ? redWidth : (resolved ? 2 : 1.5)} />
      )}
      {fragmented && (
        <line x1={c} y1={c} x2={exile.x} y2={exile.y} stroke={redColor} strokeWidth="0.75" opacity="0.5" />
      )}
      {dot && (
        fragmented
          ? <circle cx={exile.x} cy={exile.y} r={dotR} fill={redColor} />
          : <circle cx={c} cy={c} r={resolved ? dotR + 3 : dotR} fill={redColor} />
      )}
    </svg>
  );
}

Object.assign(window, { PolyMark, PM_INK, PM_RED });
