---
import type { UserPublic } from '../lib/db';
import { getLitQuarters } from '../lib/db';

interface Props {
  member: UserPublic;
  size?: 'sm' | 'md' | 'lg';
}

const { member, size = 'md' } = Astro.props;

const SIZES = { sm: 48, md: 100, lg: 200 } as const;
const px = SIZES[size];

// 12 positions on a circle, i=0 = current quarter at 12 o'clock, going clockwise
// into the past. A position is "lit" iff the member has a roadmap_attribution
// to an item with shipped_at falling in that quarter. Pulse votes do NOT light.
const lit = getLitQuarters(member.id);
const litArr = [...lit].sort((a, b) => a - b);

const CENTER = 60;
const RADIUS = 42;
function pointAt(i: number) {
  const angle = -Math.PI / 2 + (i * Math.PI * 2) / 12;
  return { x: CENTER + RADIUS * Math.cos(angle), y: CENTER + RADIUS * Math.sin(angle) };
}

const litPoints = litArr.map(pointAt);
const polygonPoints = litPoints.length >= 3
  ? litPoints.map(p => `${p.x.toFixed(2)},${p.y.toFixed(2)}`).join(' ')
  : null;

function initials(name: string): string {
  const parts = name.trim().split(/\s+/);
  if (parts.length === 1) return (parts[0][0] ?? '').toUpperCase();
  return ((parts[0][0] ?? '') + (parts[parts.length - 1][0] ?? '')).toUpperCase();
}
---
<svg
  class:list={['council-mark', `cm-${size}`]}
  width={px}
  height={px}
  viewBox="0 0 120 120"
  role="img"
  aria-label={`${member.name} — council mark`}
>
  <g class="cm-ring">
    <circle cx="60" cy="60" r="54" fill="none" stroke="currentColor"
            stroke-width="0.5" stroke-dasharray="1 4" stroke-linecap="round"
            opacity="0.35" />
  </g>

  {Array.from({ length: 12 }).map((_, i) => {
    if (lit.has(i)) return null;
    const p = pointAt(i);
    return <circle cx={p.x} cy={p.y} r="1.5" fill="var(--on-surface-muted)" opacity="0.45" />;
  })}

  {polygonPoints && (
    <polygon
      points={polygonPoints}
      fill="var(--pigment-terracotta)"
      fill-opacity="0.15"
      stroke="var(--pigment-terracotta)"
      stroke-width="0.8"
      stroke-opacity="0.6"
      class="cm-polygon"
    />
  )}

  {litArr.map((i, idx) => {
    const p = pointAt(i);
    return (
      <circle
        cx={p.x} cy={p.y} r="3.5"
        fill="var(--pigment-terracotta)"
        class="cm-dot"
        style={`animation-delay: ${(idx * 0.4).toFixed(2)}s`}
      />
    );
  })}

  <text
    x="60" y="60"
    text-anchor="middle"
    dominant-baseline="central"
    class="cm-initials"
  >{initials(member.name)}</text>
</svg>

<style>
  .council-mark {
    display: block;
    color: var(--on-surface-muted);
  }

  .cm-ring {
    transform-origin: 60px 60px;
    transform-box: view-box;
    animation: cm-ring-spin 90s linear infinite;
  }

  @keyframes cm-ring-spin {
    from { transform: rotate(0deg);   }
    to   { transform: rotate(360deg); }
  }

  .cm-polygon {
    stroke-dasharray: 2000;
    stroke-dashoffset: 2000;
    animation: cm-polygon-draw 1.6s var(--ease-standard) forwards;
  }

  @keyframes cm-polygon-draw {
    to { stroke-dashoffset: 0; }
  }

  .cm-dot {
    animation: cm-dot-breathe 2.4s ease-in-out infinite;
  }

  @keyframes cm-dot-breathe {
    0%, 100% { opacity: 1;   }
    50%      { opacity: 0.5; }
  }

  .cm-initials {
    font-family: var(--font-serif);
    font-style: italic;
    font-weight: 400;
    fill: var(--secondary);
  }

  .cm-sm .cm-initials { font-size: 12px; }
  .cm-md .cm-initials { font-size: 16px; }
  .cm-lg .cm-initials { font-size: 24px; }

  /* sm scale: drop the polygon — too dense at 48px and dots speak for themselves */
  .cm-sm .cm-polygon { display: none; }

  @media (prefers-reduced-motion: reduce) {
    .cm-ring, .cm-polygon, .cm-dot { animation: none; }
    .cm-polygon { stroke-dashoffset: 0; }
  }
</style>
