var AiHaloOverlay_1;
import { __decorate } from "tslib";
import { attr, css, customElement, GenesisElement, html } from '@genesislcap/web-core';
import { AI_COLOUR_AMBER, AI_COLOUR_CYAN, AI_COLOUR_PINK, AI_COLOUR_VIOLET, } from '../styles/ai-colours';
const HALO_DEFAULT_SPEED = 1.5;
const HALO_DEFAULT_BORDER_SIZE = 3;
const HALO_DEFAULT_GLOW_OPACITY = 0.35;
const HALO_DEFAULT_GLOW_SPREAD = 70;
/** Milliseconds in one second. */
const MS_PER_SECOND = 1000;
/** Baseline frame rate (fps) the `speed` (degrees/frame) is calibrated against. */
const BASELINE_FPS = 60;
/**
 * Frame duration (ms) at the baseline rate. Rotation advances by the elapsed
 * wall-clock time divided by this — not a fixed step per rAF callback — so it
 * holds a constant real-world speed regardless of the display's refresh rate or
 * dropped frames.
 */
const FRAME_MS = MS_PER_SECOND / BASELINE_FPS;
/**
 * Animated halo overlay — rotating conic-gradient border with an inward glow.
 *
 * Drop inside any `position: relative; overflow: hidden` container and toggle
 * the `active` attribute to show/hide the effect.
 *
 * @example
 * ```html
 * <ai-halo-overlay ?active="${(x) => x.isLoading}"></ai-halo-overlay>
 * ```
 *
 * @beta
 */
let AiHaloOverlay = AiHaloOverlay_1 = class AiHaloOverlay extends GenesisElement {
    constructor() {
        super(...arguments);
        this.active = false;
        /** Rotation speed in degrees per frame. Default: 1.5 (≈ 4 s per full revolution at 60 fps). */
        this.speed = HALO_DEFAULT_SPEED;
        /** Rotation direction. Default: 'cw' (clockwise). */
        this.direction = 'cw';
        /** Border thickness in px. Default: 3. */
        this.borderSize = HALO_DEFAULT_BORDER_SIZE;
        /** Glow layer opacity (0–1). Default: 0.35. */
        this.glowOpacity = HALO_DEFAULT_GLOW_OPACITY;
        /** Transparent stop of the radial glow mask as a percentage (0–100). Higher = less spread. Default: 70. */
        this.glowSpread = HALO_DEFAULT_GLOW_SPREAD;
        this.angle = 0;
    }
    borderSizeChanged() {
        this.style.setProperty('--halo-border-size', `${this.borderSize}px`);
    }
    glowOpacityChanged() {
        this.style.setProperty('--halo-glow-opacity', String(this.glowOpacity));
    }
    glowSpreadChanged() {
        this.style.setProperty('--halo-glow-spread', `${this.glowSpread}%`);
    }
    connectedCallback() {
        super.connectedCallback();
        this.tick();
    }
    disconnectedCallback() {
        super.disconnectedCallback();
        if (this.animFrame !== undefined) {
            cancelAnimationFrame(this.animFrame);
            this.animFrame = undefined;
        }
        // Reset the clock so a later reconnect doesn't apply one huge time delta.
        this.lastTime = undefined;
    }
    tick(now) {
        // Advance by elapsed wall-clock time (expressed in 60fps-equivalent frames)
        // rather than a fixed step per callback, so the rotation runs at a constant
        // real-world speed regardless of the display's refresh rate or dropped
        // frames. The first tick just seeds the clock (no delta yet).
        if (this.lastTime !== undefined && now !== undefined) {
            const frames = (now - this.lastTime) / FRAME_MS;
            const step = this.direction === 'ccw' ? -this.speed : this.speed;
            const raw = this.angle + step * frames;
            this.angle =
                ((raw % AiHaloOverlay_1.FULL_ROTATION_DEG) + AiHaloOverlay_1.FULL_ROTATION_DEG) %
                    AiHaloOverlay_1.FULL_ROTATION_DEG;
            this.style.setProperty('--halo-angle', `${this.angle}deg`);
        }
        this.lastTime = now;
        this.animFrame = requestAnimationFrame((t) => this.tick(t));
    }
};
// TODO: The rAF loop is fine for demos but has two drawbacks vs a pure CSS @property animation:
// 1. It runs on the main thread, so heavy JS work can cause the animation to stutter.
// 2. The loop ticks even when `active` is false (idle cost is negligible but non-zero).
// Once @property inside Shadow DOM has solid cross-browser support, consider switching back
// to a CSS @keyframes approach and removing connectedCallback/disconnectedCallback/tick().
AiHaloOverlay.FULL_ROTATION_DEG = 360;
__decorate([
    attr({ mode: 'boolean' })
], AiHaloOverlay.prototype, "active", void 0);
__decorate([
    attr({ converter: { fromView: Number, toView: String } })
], AiHaloOverlay.prototype, "speed", void 0);
__decorate([
    attr
], AiHaloOverlay.prototype, "direction", void 0);
__decorate([
    attr({ attribute: 'border-size', converter: { fromView: Number, toView: String } })
], AiHaloOverlay.prototype, "borderSize", void 0);
__decorate([
    attr({ attribute: 'glow-opacity', converter: { fromView: Number, toView: String } })
], AiHaloOverlay.prototype, "glowOpacity", void 0);
__decorate([
    attr({ attribute: 'glow-spread', converter: { fromView: Number, toView: String } })
], AiHaloOverlay.prototype, "glowSpread", void 0);
AiHaloOverlay = AiHaloOverlay_1 = __decorate([
    customElement({
        name: 'ai-halo-overlay',
        template: html `
    <slot></slot>
  `,
        styles: css `
    :host {
      display: block;
      position: absolute;
      inset: 0;
      border-radius: inherit;
      pointer-events: none;
      z-index: 1000;
      opacity: 0;
      transition: opacity 0.4s ease;
    }

    :host([active]) {
      opacity: 1;
    }

    /* Rotating solid border */
    :host::before {
      content: '';
      position: absolute;
      inset: 0;
      border-radius: inherit;
      padding: var(--halo-border-size, 3px);
      background: repeating-conic-gradient(
        from var(--halo-angle, 0deg),
        ${AI_COLOUR_AMBER},
        ${AI_COLOUR_PINK},
        ${AI_COLOUR_CYAN},
        ${AI_COLOUR_VIOLET},
        ${AI_COLOUR_AMBER}
      );
      -webkit-mask:
        linear-gradient(#000 0 0) content-box,
        linear-gradient(#000 0 0);
      mask:
        linear-gradient(#000 0 0) content-box,
        linear-gradient(#000 0 0);
      -webkit-mask-composite: destination-out;
      mask-composite: exclude;
    }

    /* Inward glow — radial mask makes centre transparent, edges coloured */
    :host::after {
      content: '';
      position: absolute;
      inset: 0;
      border-radius: inherit;
      background: repeating-conic-gradient(
        from var(--halo-angle, 0deg),
        ${AI_COLOUR_AMBER},
        ${AI_COLOUR_PINK},
        ${AI_COLOUR_CYAN},
        ${AI_COLOUR_VIOLET},
        ${AI_COLOUR_AMBER}
      );
      opacity: var(--halo-glow-opacity, 0.35);
      -webkit-mask-image: radial-gradient(
        ellipse at center,
        transparent var(--halo-glow-spread, 70%),
        black 100%
      );
      mask-image: radial-gradient(
        ellipse at center,
        transparent var(--halo-glow-spread, 70%),
        black 100%
      );
    }
  `,
    })
], AiHaloOverlay);
export { AiHaloOverlay };
