import { defineTrait } from '../define.js';
import { prefersReducedMotion } from '../motion.js';
import { getStage, viewportCenterOf, spawnParticle, SHARED_COLORS } from './confetti-stage.js';

/**
 * `confetti` — falling-shower particle burst on connect.
 *
 * Particles are pushed into the singleton body-level
 * `<div popover="manual" id="adia-confetti-stage">`, anchored to the
 * host's viewport position at fire-time. The Popover API auto-promotes
 * the stage to the browser's top-layer, so the shower escapes
 * `overflow: hidden` ancestors and renders above modals, drawers, and
 * any z-stacking context.
 *
 * Anchor model: viewport-fixed at fire-time. If the user scrolls
 * during the 1.5s shower, the particles continue from their original
 * viewport position — same UX as standard web-confetti libraries.
 */
export const confetti = defineTrait({
  name: 'confetti',
  category: 'interaction-delight',
  description: 'Radial particle burst on press',
  attributes: ['data-confetti-active'],
  events: [],
  config: [],
  setup({ host }) {
    // Reduced-motion: skip particles entirely (purely decorative).
    if (prefersReducedMotion()) {
      host.setAttribute('data-confetti-active', '');
      return () => host.removeAttribute('data-confetti-active');
    }

    const stage = getStage();
    const center = viewportCenterOf(host);

    host.setAttribute('data-confetti-active', '');

    // Fire one shower of ~60 particles. They fall from a band centered
    // on the host's top edge, drift sideways under wind, and fade out.
    if (center) {
      const rect = host.getBoundingClientRect();
      const halfW = Math.max(rect.width, 80) / 2;
      // Band starts a hair above the host so the first frame lands
      // visibly inside the host's bounds, then drifts down.
      const startY = center.y - rect.height / 2 - 8;

      for (let i = 0; i < 60; i++) {
        const x = center.x + (Math.random() - 0.5) * halfW * 2;
        const y = startY + Math.random() * 12;
        const dx = (Math.random() - 0.5) * 80;
        const dy = 200 + Math.random() * 240;
        const rot = (Math.random() - 0.5) * 540;
        const size = Math.random() * 4 + 2;
        const color = SHARED_COLORS[Math.floor(Math.random() * SHARED_COLORS.length)];
        const delay = Math.random() * 600;
        const dur = 900 + Math.random() * 700;

        const p = spawnParticle(stage, x, y, { size, color });
        p.style.setProperty('--dx', `${dx}px`);
        p.style.setProperty('--dy', `${dy}px`);
        p.style.setProperty('--rot', `${rot}deg`);
        p.style.animation = `adia-confetti-fall ${dur}ms ${delay}ms ease-in forwards`;
      }
    }

    return () => {
      host.removeAttribute('data-confetti-active');
      // In-flight particles self-remove on animationend; nothing to
      // tear down on the stage (it's a session-long singleton).
    };
  },
});
