/* MY GENI — Phase 22 · Avatar System + Profile Card
 *
 * <Avatar name="…" size="xs|sm|md|lg|xl" portrait?="…" />
 *
 * Resolution order:
 *   1. Explicit `portrait` prop wins (backwards compat with any caller
 *      that still passes a photo path).
 *   2. Registry lookup via window.MYGENI_PEOPLE.get(name) → if the
 *      registry entry has a real portrait path (photo supplied later),
 *      render the photo.
 *   3. Otherwise render the deterministic stylized identity SVG for that
 *      person (per-person geometry family + color).
 *   4. Unknown name → neutral initials chip (preserves the current fallback
 *      behavior for any historical names still in scope).
 *
 * The stylized SVG is intentionally geometric — no attempt to render a
 * likeness of the real five people. When real photos are supplied later,
 * the SVG is silently replaced everywhere.
 */

(function () {

  const SIZES = {
    xs: 20, sm: 24, md: 40, lg: 64, xl: 96,
  };

  // Deterministic per-name hash for the unknown-name fallback.
  function hashName(s) {
    let h = 0;
    for (let i = 0; i < s.length; i++) h = ((h << 5) - h) + s.charCodeAt(i) | 0;
    return Math.abs(h);
  }

  // Neutral initials from a name string (works for Farsi + Latin).
  function initialsFor(name) {
    if (!name) return '?';
    const parts = String(name).trim().split(/\s+/);
    if (parts.length === 1) return parts[0].slice(0, 2);
    return (parts[0][0] || '') + (parts[parts.length - 1][0] || '');
  }

  // --- Per-geometry SVG identity marks. Each is a solid-square viewBox 100
  //     with a coherent premium composition (no rainbow, no sparkles).
  //     Rendered inline, no HTTP. --------------------------------------

  function Mark({ geometry, color, accent, size, initials }) {
    const s = size;
    const stroke = Math.max(1, Math.round(s / 32));
    const initialFontPx = Math.round(s * (initials.length <= 2 ? 0.36 : 0.30));
    const textShadow = size >= 40 ? '0 1px 2px rgba(0,0,0,0.20)' : 'none';

    // Common frame — soft interior background tint over the strong color
    // gives the mark visual depth without gradients.
    const inner = React.useMemo(() => {
      switch (geometry) {
        case 'orbit':
          return (
            <g>
              <circle cx="50" cy="50" r="46" fill={color} />
              <circle cx="50" cy="50" r="34" fill="none" stroke={accent} strokeOpacity="0.55" strokeWidth="1.6" />
              <circle cx="82" cy="30" r="6.5" fill={accent} />
            </g>
          );
        case 'grid':
          return (
            <g>
              <rect x="0" y="0" width="100" height="100" fill={color} />
              <g fill={accent} fillOpacity="0.55">
                <rect x="12" y="12" width="24" height="24" rx="4" />
                <rect x="40" y="12" width="24" height="24" rx="4" />
                <rect x="68" y="12" width="20" height="24" rx="4" />
                <rect x="12" y="40" width="24" height="24" rx="4" />
                <rect x="12" y="68" width="24" height="20" rx="4" />
              </g>
            </g>
          );
        case 'wave':
          return (
            <g>
              <rect x="0" y="0" width="100" height="100" fill={color} />
              <path d="M -5 66 Q 25 46, 50 66 T 105 66 L 105 105 L -5 105 Z" fill={accent} fillOpacity="0.55" />
              <path d="M -5 78 Q 25 58, 50 78 T 105 78 L 105 105 L -5 105 Z" fill={accent} fillOpacity="0.35" />
            </g>
          );
        case 'stack':
          return (
            <g>
              <rect x="0" y="0" width="100" height="100" fill={color} />
              <g fill={accent} fillOpacity="0.60">
                <rect x="16" y="20" width="68" height="14" rx="4" />
                <rect x="16" y="42" width="52" height="14" rx="4" />
                <rect x="16" y="64" width="60" height="14" rx="4" />
              </g>
            </g>
          );
        case 'ring':
          return (
            <g>
              <rect x="0" y="0" width="100" height="100" fill={color} />
              <circle cx="50" cy="50" r="30" fill="none" stroke={accent} strokeOpacity="0.65" strokeWidth="8" />
              <circle cx="50" cy="50" r="12" fill={accent} fillOpacity="0.75" />
            </g>
          );
        default:
          return <rect x="0" y="0" width="100" height="100" fill={color} />;
      }
    }, [geometry, color, accent]);

    return (
      <svg width={s} height={s} viewBox="0 0 100 100" role="img" aria-hidden="true" style={{ display: 'block' }}>
        {inner}
        <text
          x="50" y="54"
          textAnchor="middle" dominantBaseline="middle"
          fontFamily="Inter, system-ui, sans-serif"
          fontSize={initials.length <= 2 ? 34 : 28}
          fontWeight="700"
          fill="#ffffff"
          style={{ letterSpacing: '-0.02em' }}
        >
          {initials}
        </text>
      </svg>
    );
  }

  function AvatarV2({ name, size = 'md', portrait, title, onClick, style }) {
    const px = SIZES[size] || SIZES.md;
    const R = (typeof window !== 'undefined') && window.MYGENI_PEOPLE;
    const entry = (R && R.get(name)) || null;

    // 1. Explicit portrait prop wins.
    let resolvedPortrait = portrait || null;
    // 2. Fall back to registry-supplied real portrait (when supplied later).
    if (!resolvedPortrait && entry && entry.portrait) {
      resolvedPortrait = entry.portrait;
    }

    // Ignore *legacy* portrait paths pointing to now-archived JPGs.
    if (resolvedPortrait && /_archived\//.test(resolvedPortrait)) resolvedPortrait = null;
    if (resolvedPortrait && /assets\/portraits\/(priya|aya|marco|rachel|lucia|devon)\.jpg$/i.test(resolvedPortrait)) {
      resolvedPortrait = null; // old paths after Phase-22 sweep — silently fall through to identity mark
    }

    const clickable = typeof onClick === 'function';
    const wrapStyle = {
      width: px, height: px, borderRadius: '50%',
      overflow: 'hidden',
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
      flexShrink: 0,
      background: 'var(--bg-inset, #EBEBEB)',
      boxShadow: 'inset 0 0 0 1px rgba(15,15,18,0.06)',
      cursor: clickable ? 'pointer' : 'default',
      ...style,
    };

    // Render photo if present
    if (resolvedPortrait) {
      return (
        <span title={title || name || ''} onClick={onClick} style={wrapStyle}>
          <img
            src={resolvedPortrait}
            alt={name || ''}
            width={px} height={px}
            style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }}
            draggable={false}
          />
        </span>
      );
    }

    // Render registry stylized mark
    if (entry) {
      return (
        <span title={title || entry.name || name || ''} onClick={onClick} style={wrapStyle}>
          <Mark geometry={entry.geometry}
                color={entry.color}
                accent={entry.accent}
                size={px}
                initials={entry.shortInitials} />
        </span>
      );
    }

    // Unknown name: neutral initials chip on a low-saturation tone (kept for
    // Elena Marchetti-style historical placeholders and any unfamiliar names).
    const palette = ['#9AA6B2', '#8A93A0', '#7C8794', '#8B7E92', '#7D8E92'];
    const bg = palette[hashName(name || 'x') % palette.length];
    return (
      <span title={title || name || ''} onClick={onClick} style={wrapStyle}>
        <svg width={px} height={px} viewBox="0 0 100 100" role="img" aria-hidden="true" style={{ display: 'block' }}>
          <rect x="0" y="0" width="100" height="100" fill={bg} />
          <text x="50" y="54"
                textAnchor="middle" dominantBaseline="middle"
                fontFamily="Inter, system-ui, sans-serif"
                fontSize="34" fontWeight="700" fill="#ffffff"
                style={{ letterSpacing: '-0.02em' }}>
            {initialsFor(name).toUpperCase()}
          </text>
        </svg>
      </span>
    );
  }

  // --- <AvatarStack> — coalesces adjacent avatars with negative left-margin.
  function AvatarStackV2({ names = [], size = 'sm', max = 4, onOverflowClick }) {
    const list = names.filter(Boolean);
    const shown = list.slice(0, max);
    const overflow = list.length - shown.length;
    const px = SIZES[size] || SIZES.sm;
    return (
      <span style={{ display: 'inline-flex', alignItems: 'center' }}>
        {shown.map((n, i) => (
          <span key={i} style={{ marginLeft: i === 0 ? 0 : -Math.round(px * 0.30) }}>
            <AvatarV2 name={n} size={size} />
          </span>
        ))}
        {overflow > 0 && (
          <span
            onClick={onOverflowClick}
            style={{
              marginLeft: -Math.round(px * 0.30),
              width: px, height: px, borderRadius: '50%',
              background: 'var(--bg-inset)',
              display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
              fontSize: Math.max(9, Math.round(px * 0.32)),
              fontWeight: 600, color: 'var(--text-secondary)',
              boxShadow: 'inset 0 0 0 1px rgba(15,15,18,0.08)',
              cursor: onOverflowClick ? 'pointer' : 'default',
            }}
          >+{overflow}</span>
        )}
      </span>
    );
  }

  // --- <PersonPopover> — compact profile card that opens off any Avatar.
  // Kept purely local: mounted where used, no portal, closes on outside click.
  function PersonPopoverV2({ name, anchor, onClose }) {
    const R = window.MYGENI_PEOPLE;
    const entry = R && R.get(name);
    const rootRef = React.useRef(null);
    React.useEffect(() => {
      function onDown(e) {
        if (!rootRef.current) return;
        if (!rootRef.current.contains(e.target)) onClose && onClose();
      }
      function onKey(e) { if (e.key === 'Escape') onClose && onClose(); }
      document.addEventListener('mousedown', onDown);
      document.addEventListener('keydown', onKey);
      return () => {
        document.removeEventListener('mousedown', onDown);
        document.removeEventListener('keydown', onKey);
      };
    }, [onClose]);

    if (!entry) return null;
    const displayName = entry.displayName || entry.name;

    return (
      <div ref={rootRef}
           className="person-popover"
           style={{
             position: 'absolute', top: anchor?.top ?? 48, left: anchor?.left ?? 0,
             minWidth: 280, maxWidth: 320,
             background: 'var(--bg-surface)',
             borderRadius: 20,
             boxShadow: 'var(--shadow-depth, 0 24px 48px -12px rgba(15,15,18,0.20), 0 8px 16px -4px rgba(15,15,18,0.10))',
             padding: 16,
             zIndex: 400,
           }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
          <AvatarV2 name={displayName} size="lg" />
          <div style={{ minWidth: 0 }}>
            <div style={{ fontSize: 15, fontWeight: 600, lineHeight: 1.15, letterSpacing: '-0.01em' }}>{displayName}</div>
            <div style={{ fontSize: 12, color: 'var(--text-tertiary)', marginTop: 2 }}>{entry.functionalRole}</div>
          </div>
        </div>
        <div style={{ marginTop: 12, paddingTop: 12, borderTop: '1px solid var(--border-divider)' }}>
          <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
            {entry.isCurrentUser && (
              <span style={{ fontSize: 10, fontWeight: 600, letterSpacing: '0.08em', color: '#1F8A5B',
                             background: 'rgba(31,138,91,0.08)', border: '1px solid rgba(31,138,91,0.20)',
                             padding: '3px 8px', borderRadius: 999, textTransform: 'uppercase' }}>YOU</span>
            )}
            <span style={{ fontSize: 10, fontWeight: 600, letterSpacing: '0.08em', color: 'var(--text-secondary)',
                           background: 'var(--bg-inset)', padding: '3px 8px', borderRadius: 999, textTransform: 'uppercase' }}>
              MY GENI TEAM
            </span>
          </div>
        </div>
      </div>
    );
  }

  // Publish. We overwrite the components.jsx Avatar/AvatarStack after this
  // script loads (see wireup in Home - Command Center.html script order).
  window.Avatar = AvatarV2;
  window.AvatarStack = AvatarStackV2;
  window.PersonPopover = PersonPopoverV2;
  window.AVATAR_SIZES = SIZES;
})();
