/**
 * `<feed-ui>` — Shared top-layer feed channel. Per docs/specs/feed-channel.md
 * (SPEC-FEED-CHANNEL-001). Per-position singletons mounted lazily into
 * document.body via Popover API; consumers post via the static API
 * (`UIFeed.post()`) or the global 'feed' CustomEvent.
 *
 * @see https://ui-kit.exe.xyz/site/components/feed
 *
 * HAND-AUTHORED (not codegen'd) per §247 (v0.5.10, FB-24) — the
 * sibling-yaml codegen walk (v0.5.9 §228) catches the two element classes
 * (`UIFeedContainer` + `UIFeedItem`) but misses the ambient `UIFeed`
 * static-API class because it has no tag-registered yaml. Hand-authored
 * .d.ts adds the static-API + supporting types. `dts-codegen.mjs` keeps
 * this file in its `HAND_AUTHORED_DTS` skip list.
 */

import { UIElement } from '../../core/element.js';

/** Lane positions where `<feed-ui>` containers mount. */
export type FeedPosition =
  | 'top-left' | 'top-center' | 'top-right'
  | 'bottom-left' | 'bottom-center' | 'bottom-right'
  | 'inline';

/**
 * Options for `UIFeed.post()` — the imperative one-shot path. Mirrors
 * `UIFeedItem`'s reflected props plus `position` (which container lane).
 */
export interface UIFeedPostOptions {
  /** Body copy for the feed item. */
  text: string;
  /** Optional emphasis line above text. */
  heading?: string;
  /** Optional leading icon name (Phosphor). */
  icon?: string;
  /** Semantic variant. */
  variant?: 'default' | 'info' | 'success' | 'warning' | 'danger';
  /** Auto-fade timer in ms; `null` / `0` = sticky (requires user input). */
  duration?: number;
  /** Render an `x` close button (default `true` for sticky, `false` for auto-fade). */
  dismissible?: boolean;
  /** Lane to render into. Defaults to `'bottom-right'`. */
  position?: FeedPosition;
  /**
   * Phase 2 action-required policy: when set, the item carries an action
   * button. Per `feed-channel.md` §2.3, sets `role="alertdialog"` + focus
   * is trapped until the action fires (or the item dismisses).
   */
  action?: string;
}

/** Imperative handle returned by `UIFeed.post()` — dismiss / update. */
export interface FeedHandle {
  /** Stable id assigned by `<feed-ui>`. `null` if the post failed. */
  id: string | null;
  /** Dismiss the item programmatically (triggers exit animation). */
  dismiss(): void;
  /** Mutate the item's content in-place (e.g. promote loading→done). */
  update(patch: Partial<UIFeedPostOptions>): void;
}

export type FeedContainerCloseEvent = CustomEvent<unknown>;

export class UIFeedContainer extends UIElement {
  /** Cap on simultaneously visible items per lane. */
  max: number;
  /** Lane the feed renders into. */
  position: FeedPosition;

  addEventListener<K extends keyof HTMLElementEventMap>(
    type: K,
    listener: (this: UIFeedContainer, ev: HTMLElementEventMap[K]) => unknown,
    options?: boolean | AddEventListenerOptions,
  ): void;
  addEventListener(type: 'close', listener: (ev: FeedContainerCloseEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
}

export type FeedItemCloseEvent = CustomEvent<unknown>;

export class UIFeedItem extends UIElement {
  /** Render an `x` close button (default `true` for sticky, `false` for auto-fade). */
  dismissible: boolean;
  /** Auto-fade timer in ms; `null` / `0` = sticky (requires user input). */
  duration: number;
  /** Optional emphasis line above text. */
  heading: string;
  /** Optional leading icon name. */
  icon: string;
  /** Body copy. */
  text: string;
  /** Semantic variant. */
  variant: 'default' | 'info' | 'success' | 'warning' | 'danger';

  addEventListener<K extends keyof HTMLElementEventMap>(
    type: K,
    listener: (this: UIFeedItem, ev: HTMLElementEventMap[K]) => unknown,
    options?: boolean | AddEventListenerOptions,
  ): void;
  addEventListener(type: 'close', listener: (ev: FeedItemCloseEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
}

/**
 * Static API for posting `<feed-item-ui>` rows without instantiating
 * `<feed-ui>` declaratively. Per-position lanes auto-mount into
 * `document.body` on first call. Use this in place of declarative
 * `<feed-ui>` for one-shot programmatic messages (toast-style API).
 *
 * The class is NOT a custom element — it's a singleton namespace. Don't
 * try to `new UIFeed()` or extend it; use the static methods only.
 */
export class UIFeed {
  /** Get (or lazily create + mount) the per-position lane container. */
  static get(position?: FeedPosition): UIFeedContainer;
  /** Post a feed item. Returns a handle for programmatic dismiss / update. */
  static post(opts: UIFeedPostOptions): FeedHandle;
  /** Clear all items in the lane at the given position. */
  static clear(position?: FeedPosition): void;
  /** Purge all lanes; tear down DOM containers. */
  static purge(): void;
  /** Internal: drop empty container after the last item dismisses. */
  static releaseContainerIfEmpty(container: UIFeedContainer): void;
}
