/**
 * Non-side-effect class export for `<toast-ui>`.
 *
 * Importing this file gives you the class(es) without auto-registering the tag.
 * Useful for test isolation, subclassing with tag-name override, or selective
 * composition.
 *
 * The auto-register path stays at `@adia-ai/web-components/components/toast`
 * (which imports this file + calls `defineIfFree()`).
 *
 * @see ../../USAGE.md#registration--auto-vs-explicit
 */

/**
 * <toast-ui> — Thin facade over `<feed-ui>` / `UIFeed.post()`.
 *
 * Phase 4 of `docs/specs/feed-channel.md` (SPEC-FEED-CHANNEL-001) —
 * toast-ui no longer owns its own per-position container. Both
 * declarative `<toast-ui>` and imperative `UIToast.show()` paths
 * route through `UIFeed`. The element exists for back-compat:
 * authoring `<toast-ui text="…">` still produces a feed item.
 *
 *     // Imperative API (delegates to UIFeed.post)
 *     UIToast.show({ text: 'Saved!', variant: 'success' });
 *
 *     // Global event channel — same shape, same delegation.
 *     window.dispatchEvent(new CustomEvent('toast', {
 *       detail: { text: 'Saved!', variant: 'success' }
 *     }));
 *
 *     // Declarative — auto-posts and removes self on connect.
 *     <toast-ui text="Saved!" variant="success"></toast-ui>
 *
 * The legacy `[data-toast-container]` per-position-Map plumbing was
 * retired in this migration; the lane infrastructure now lives in
 * `<feed-ui>` (see ../feed/feed.js).
 */

import { UIElement, html } from '../../core/element.js';
import { UIFeed } from '../feed/feed.js';

export class UIToast extends UIElement {
  static properties = {
    text:     { type: String,  default: '', reflect: true },
    variant:  { type: String,  default: 'info', reflect: true },
    duration: { type: Number,  default: 4000, reflect: true },
    position: { type: String,  default: 'bottom-right', reflect: true },
  };

  static template = () => html``;

  connected() {
    /* Declarative path: post into UIFeed and remove self. The
       element is fire-and-forget — its only job is to forward the
       authored attributes to the feed, then dissolve. Re-entrant
       guard keeps this safe under HMR / dev-mode re-attachment. */
    if (this.__routedToFeed) return;
    this.__routedToFeed = true;
    UIFeed.post({
      text:     this.text,
      variant:  this.variant === 'error' ? 'danger' : this.variant,
      duration: this.duration,
      position: this.position,
    });
    /* Schedule removal so the calling code can read the attributes
       if it inspected this element on the same microtask. */
    queueMicrotask(() => { try { this.remove(); } catch { /* noop */ } });
  }

  /**
   * Static facade — delegates to UIFeed.post(). Kept for back-compat
   * with consumer code shaped like `customElements.get('toast-ui').show(...)`
   * or `UIToast.show(...)`. New code should call UIFeed.post()
   * directly.
   *
   * @param {Object} opts
   * @param {string} opts.text
   * @param {string} [opts.variant='info']  — `error` aliases to `danger`.
   * @param {number} [opts.duration=4000]
   * @param {string} [opts.position='bottom-right']
   * @param {boolean} [opts.dismissible]  Force-show the close button on auto-
   *                                fade toasts (sticky toasts always show it).
   * @param {string} [opts.action]  Optional action button label (e.g. 'Undo').
   * @param {function} [opts.onAction]  Action button click handler.
   * @returns {{id:string|null, dismiss:function, update:function}}  FeedHandle.
   */
  static show(opts = {}) {
    const { text, variant = 'info', position = 'bottom-right', action, onAction } = opts;
    // §224 (v0.5.9, FEEDBACK-10 §2): mark the spawned feed container so
    // DOM-query consumers (Playwright, devtools, instrumentation) can
    // distinguish toast-spawned <feed-ui> from user-authored ones. The marker
    // is set once at container-creation time; subsequent posts to the same
    // container don't re-stamp (idempotent).
    const container = UIFeed.get(position);
    if (container && !container.hasAttribute('data-spawned-by')) {
      container.setAttribute('data-spawned-by', 'toast');
    }
    const payload = {
      text,
      variant: variant === 'error' ? 'danger' : variant,
      position,
    };
    if ('duration' in opts) payload.duration = opts.duration;
    if ('dismissible' in opts) payload.dismissible = !!opts.dismissible;
    if (action) payload.action = action;
    if (typeof onAction === 'function') payload.onAction = onAction;
    return UIFeed.post(payload);
  }
}
