import { __decorate } from '../node_modules/.pnpm/@rollup_plugin-typescript@12.3.0_rollup@4.60.1_tslib@2.8.1_typescript@6.0.2/node_modules/tslib/tslib.es6.js';
import { css, LitElement, nothing, html } from 'lit';
import { property, state, query, customElement } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';
import { PlayerControllerHost } from '../controllers/player-controller-host.js';
import { sharedStyles } from '../styles/shared-styles.js';
import { utilityStyles } from '../styles/utility-styles.js';
import { closeIcon, statsIcon, settingsIcon, pictureInPictureIcon, loopIcon } from '../icons/index.js';
import { clearTheme, applyTheme, applyThemeOverrides } from '@livepeer-frameworks/player-core';

let FwPlayer = class FwPlayer extends LitElement {
    constructor() {
        super(...arguments);
        // ---- Public attributes (reflected) ----
        this.contentId = "";
        this.autoplay = true;
        this.muted = false;
        // React/Svelte use `stockControls` for native controls. Keep `controls` as a
        // compatibility no-op so WC parity does not hide custom controls/seekbar.
        this.controls = false;
        this.noControls = false;
        this.stockControls = false;
        this.nativeControls = false;
        this.animatePreroll = false;
        this.debug = false;
        this.devMode = false;
        this.playbackMode = "auto";
        // ---- Internal state ----
        this._isStatsOpen = false;
        this._isDevPanelOpen = false;
        this._skipDirection = null;
        this._contextMenuOpen = false;
        this._contextMenuMounted = false;
        // Error fade-out
        this._displayedError = null;
        this._displayedIsPassive = false;
        this._isErrorDismissing = false;
        this._errorDismissTimer = null;
        this._contextMenuState = "closed";
        this._contextMenuSide = "bottom";
        this._contextMenuX = 0;
        this._contextMenuY = 0;
        // ---- Controller ----
        this.pc = new PlayerControllerHost(this);
        this._contextMenuTypeahead = "";
        this._resetContextMenuTypeahead = () => {
            this._contextMenuTypeahead = "";
            if (this._contextMenuTypeaheadTimer) {
                clearTimeout(this._contextMenuTypeaheadTimer);
                this._contextMenuTypeaheadTimer = undefined;
            }
        };
        this._resolveContextMenuSide = (rawX, rawY, clampedX, clampedY) => {
            const deltaX = Math.abs(rawX - clampedX);
            const deltaY = Math.abs(rawY - clampedY);
            if (deltaX === 0 && deltaY === 0) {
                return "bottom";
            }
            if (deltaY >= deltaX) {
                return rawY > clampedY ? "top" : "bottom";
            }
            return rawX > clampedX ? "left" : "right";
        };
        this._closeContextMenu = (restoreFocus = false) => {
            this._contextMenuOpen = false;
            this._contextMenuState = "closed";
            this._resetContextMenuTypeahead();
            if (this._contextMenuCloseTimer) {
                clearTimeout(this._contextMenuCloseTimer);
            }
            this._contextMenuCloseTimer = setTimeout(() => {
                if (!this._contextMenuOpen) {
                    this._contextMenuMounted = false;
                }
            }, 170);
            if (restoreFocus) {
                const root = this.shadowRoot?.querySelector('[part="root"]');
                root?.focus();
            }
        };
        this._getQueryRoot = () => {
            return (this.shadowRoot ?? this.renderRoot ?? null);
        };
        this._getContextMenuElement = () => this._getQueryRoot()?.querySelector('[data-context-menu="true"]') ?? null;
        this._getContextMenuBounds = () => {
            const root = this._getQueryRoot()?.querySelector('[part="root"]');
            const rect = root?.getBoundingClientRect() ?? this.getBoundingClientRect();
            const width = rect.width > 0 ? rect.width : window.innerWidth;
            const height = rect.height > 0 ? rect.height : window.innerHeight;
            return {
                left: rect.left,
                top: rect.top,
                right: rect.left + width,
                bottom: rect.top + height,
                width,
                height,
            };
        };
        this._toLocalContextMenuPoint = (clientX, clientY) => {
            const bounds = this._getContextMenuBounds();
            return {
                x: clientX - bounds.left,
                y: clientY - bounds.top,
            };
        };
        this._getContextMenuItems = () => Array.from(this._getQueryRoot()?.querySelectorAll('[data-context-menu-item="true"][data-context-menu-level="root"]:not([data-disabled="true"])') ?? []);
        this._focusFirstContextMenuItem = () => {
            const [firstItem] = this._getContextMenuItems();
            firstItem?.focus();
        };
        this._clampContextMenuPosition = (x, y, width, height) => {
            const viewportPadding = 8;
            const bounds = this._getContextMenuBounds();
            const maxX = Math.max(viewportPadding, bounds.width - width - viewportPadding);
            const maxY = Math.max(viewportPadding, bounds.height - height - viewportPadding);
            return {
                x: Math.max(viewportPadding, Math.min(x, maxX)),
                y: Math.max(viewportPadding, Math.min(y, maxY)),
            };
        };
        this._syncContextMenuPosition = () => {
            if (!this._contextMenuMounted)
                return;
            const menu = this._getContextMenuElement();
            if (!menu)
                return;
            const rect = menu.getBoundingClientRect();
            const next = this._clampContextMenuPosition(this._contextMenuX, this._contextMenuY, rect.width, rect.height);
            this._contextMenuSide = this._resolveContextMenuSide(this._contextMenuX, this._contextMenuY, next.x, next.y);
            if (next.x !== this._contextMenuX || next.y !== this._contextMenuY) {
                this._contextMenuX = next.x;
                this._contextMenuY = next.y;
            }
        };
        this._openContextMenu = (clientX, clientY) => {
            const local = this._toLocalContextMenuPoint(clientX, clientY);
            const next = this._clampContextMenuPosition(local.x, local.y, 220, 200);
            this._contextMenuSide = this._resolveContextMenuSide(local.x, local.y, next.x, next.y);
            this._contextMenuX = next.x;
            this._contextMenuY = next.y;
            this._contextMenuMounted = true;
            this._contextMenuState = "open";
            if (this._contextMenuCloseTimer) {
                clearTimeout(this._contextMenuCloseTimer);
                this._contextMenuCloseTimer = undefined;
            }
            this._resetContextMenuTypeahead();
            this._contextMenuOpen = true;
        };
        this._handleContextMenu = (e) => {
            const target = e.target;
            if (target?.closest('[data-context-menu="true"]')) {
                e.preventDefault();
                return;
            }
            e.preventDefault();
            this._openContextMenu(e.clientX, e.clientY);
        };
        this._handleContextMenuShortcut = (e) => {
            const isContextMenuKey = e.key === "ContextMenu";
            const isShiftF10 = e.key === "F10" && e.shiftKey;
            if (!isContextMenuKey && !isShiftF10)
                return;
            e.preventDefault();
            const rect = this.getBoundingClientRect();
            const x = rect.left + rect.width / 2;
            const y = rect.top + rect.height / 2;
            this._openContextMenu(x, y);
        };
        this._handleDocumentPointerDown = (e) => {
            if (!this._contextMenuOpen)
                return;
            const menu = this._getContextMenuElement();
            const composedPath = e.composedPath();
            if (menu && composedPath.includes(menu))
                return;
            this._closeContextMenu();
        };
        this._handleDocumentContextMenu = (e) => {
            if (!this._contextMenuOpen)
                return;
            if (!this.contains(e.target)) {
                this._closeContextMenu();
            }
        };
        this._handleDocumentKeyDown = (e) => {
            if (e.key === "Escape" && this._contextMenuOpen) {
                e.preventDefault();
                this._closeContextMenu(true);
            }
        };
        this._handleContextMenuKeyDown = (e) => {
            if (!this._contextMenuOpen)
                return;
            const activeElement = this.shadowRoot?.activeElement;
            if (e.key === "Escape") {
                e.preventDefault();
                this._closeContextMenu(true);
                return;
            }
            if (e.key === "Tab") {
                this._closeContextMenu();
                return;
            }
            const items = this._getContextMenuItems();
            if (items.length === 0)
                return;
            const activeIndex = items.findIndex((item) => item === activeElement);
            if (e.key === "Home") {
                e.preventDefault();
                this._focusFirstContextMenuItem();
                return;
            }
            if (e.key === "End") {
                e.preventDefault();
                items[items.length - 1]?.focus();
                return;
            }
            if (e.key === "ArrowDown" || e.key === "ArrowUp") {
                e.preventDefault();
                const direction = e.key === "ArrowDown" ? 1 : -1;
                const startIndex = activeIndex === -1 ? (direction === 1 ? 0 : items.length - 1) : activeIndex;
                const nextIndex = (startIndex + direction + items.length) % items.length;
                items[nextIndex]?.focus();
                return;
            }
            if (e.key === "Enter" || e.key === " ") {
                if (activeElement) {
                    e.preventDefault();
                    activeElement.click();
                }
                return;
            }
            if (e.key.length === 1 && !e.metaKey && !e.ctrlKey && !e.altKey) {
                e.preventDefault();
                this._contextMenuTypeahead += e.key.toLowerCase();
                if (this._contextMenuTypeaheadTimer) {
                    clearTimeout(this._contextMenuTypeaheadTimer);
                }
                this._contextMenuTypeaheadTimer = setTimeout(() => {
                    this._resetContextMenuTypeahead();
                }, 700);
                const startIndex = activeIndex === -1 ? 0 : activeIndex + 1;
                const orderedItems = [...items.slice(startIndex), ...items.slice(0, startIndex)];
                const match = orderedItems.find((item) => item.textContent?.trim().toLowerCase().startsWith(this._contextMenuTypeahead));
                match?.focus();
            }
        };
    }
    // ---- Lifecycle ----
    willUpdate(changed) {
        if (changed.has("locale") || changed.has("translations")) {
            this.pc.updateTranslator({ locale: this.locale ?? "en", translations: this.translations });
        }
        // Error fade-out: sync displayed error from controller state
        const es = this.pc.s;
        if (es.error) {
            if (this._errorDismissTimer) {
                clearTimeout(this._errorDismissTimer);
                this._errorDismissTimer = null;
            }
            this._displayedError = es.error;
            this._displayedIsPassive = es.isPassiveError;
            this._isErrorDismissing = false;
        }
        else if (this._displayedError && !this._isErrorDismissing) {
            this._isErrorDismissing = true;
            this._errorDismissTimer = setTimeout(() => {
                this._displayedError = null;
                this._displayedIsPassive = false;
                this._isErrorDismissing = false;
                this._errorDismissTimer = null;
            }, 300);
        }
        if (changed.has("contentId") ||
            changed.has("contentType") ||
            changed.has("gatewayUrl") ||
            changed.has("mistUrl") ||
            changed.has("authToken") ||
            changed.has("playbackToken") ||
            changed.has("playbackTokenTransport") ||
            changed.has("autoplay") ||
            changed.has("muted") ||
            changed.has("noControls") ||
            changed.has("stockControls") ||
            changed.has("nativeControls") ||
            changed.has("animatePreroll") ||
            changed.has("debug") ||
            changed.has("thumbnailUrl") ||
            changed.has("playbackMode") ||
            changed.has("forcePlayer") ||
            changed.has("forceType") ||
            changed.has("forceSource") ||
            changed.has("endpoints") ||
            changed.has("locale") ||
            changed.has("translations")) {
            this.pc.configure({
                contentId: this.contentId,
                contentType: this.contentType,
                endpoints: this.endpoints,
                gatewayUrl: this.gatewayUrl,
                mistUrl: this.mistUrl,
                authToken: this.authToken,
                playbackAuth: this.playbackToken
                    ? { token: this.playbackToken, transport: this.playbackTokenTransport }
                    : undefined,
                autoplay: this.autoplay,
                muted: this.muted,
                controls: this._useStockControls,
                poster: this.thumbnailUrl,
                animatePreroll: this.animatePreroll,
                debug: this.debug,
                forcePlayer: this.forcePlayer,
                forceType: this.forceType,
                forceSource: this.forceSource,
                playbackMode: this.playbackMode,
                locale: this.locale,
                translations: this.translations,
            });
        }
    }
    firstUpdated() {
        this.pc.attach(this._containerEl);
        // Close context menu on outside click
        document.addEventListener("pointerdown", this._handleDocumentPointerDown);
        document.addEventListener("contextmenu", this._handleDocumentContextMenu);
        document.addEventListener("keydown", this._handleDocumentKeyDown);
    }
    disconnectedCallback() {
        super.disconnectedCallback();
        document.removeEventListener("pointerdown", this._handleDocumentPointerDown);
        document.removeEventListener("contextmenu", this._handleDocumentContextMenu);
        document.removeEventListener("keydown", this._handleDocumentKeyDown);
        if (this._contextMenuCloseTimer) {
            clearTimeout(this._contextMenuCloseTimer);
            this._contextMenuCloseTimer = undefined;
        }
        if (this._errorDismissTimer) {
            clearTimeout(this._errorDismissTimer);
            this._errorDismissTimer = null;
        }
        this._resetContextMenuTypeahead();
    }
    updated(changed) {
        // Apply theme changes (preset or overrides) via JS custom properties
        if (changed.has("theme") || changed.has("themeOverrides")) {
            const root = this.shadowRoot?.querySelector('[part="root"]');
            if (root) {
                clearTheme(root);
                if (this.theme && this.theme !== "default") {
                    applyTheme(root, this.theme);
                }
                if (this.themeOverrides)
                    applyThemeOverrides(root, this.themeOverrides);
            }
        }
        if (this.pc.s.toast) {
            clearTimeout(this._toastTimer);
            this._toastTimer = setTimeout(() => this.pc.dismissToast(), 3000);
        }
        if ((changed.has("_contextMenuOpen") || changed.has("_contextMenuMounted")) &&
            this._contextMenuOpen) {
            queueMicrotask(() => {
                this._syncContextMenuPosition();
                this._focusFirstContextMenuItem();
            });
        }
    }
    // ---- Derived state ----
    get _showTitleOverlay() {
        const s = this.pc.s;
        return (s.isHovering || s.isPaused) && !s.shouldShowIdleScreen && !s.isBuffering && !s.error;
    }
    get _showBufferingSpinner() {
        const s = this.pc.s;
        return !s.shouldShowIdleScreen && s.isBuffering && !s.error && s.hasPlaybackStarted;
    }
    get _showWaitingForEndpoint() {
        const s = this.pc.s;
        return !s.endpoints?.primary && s.state !== "booting";
    }
    get _showLoadingPosterOverlay() {
        // Controller owns the visibility decision (PlayerController.getShouldShowLoadingPoster).
        // Wrapper masks with its local displayedError fade lifecycle.
        return this.pc.s.shouldShowLoadingPoster && !this._displayedError;
    }
    get _waitingMessage() {
        const s = this.pc.s;
        if (s.state === "gateway_loading") {
            return this.pc.t("resolvingEndpoint");
        }
        return this.pc.t("waitingForStream");
    }
    get _controlsEnabled() {
        return !this.noControls;
    }
    get _useStockControls() {
        return (this._controlsEnabled &&
            (this.stockControls ||
                this.nativeControls ||
                this.pc.s.currentPlayerInfo?.shortname === "mist-legacy"));
    }
    /** Expose the PlayerControllerHost for composable controls */
    get controller() {
        return this.pc;
    }
    // ---- Public API methods ----
    async play() {
        await this.pc.play();
    }
    pause() {
        this.pc.pause();
    }
    togglePlay() {
        this.pc.togglePlay();
    }
    seek(time) {
        this.pc.seek(time);
    }
    seekBy(delta) {
        this.pc.seekBy(delta);
    }
    jumpToLive() {
        this.pc.jumpToLive();
    }
    setVolume(volume) {
        this.pc.setVolume(volume);
    }
    toggleMute() {
        this.pc.toggleMute();
    }
    toggleLoop() {
        this.pc.toggleLoop();
    }
    async toggleFullscreen() {
        await this.pc.toggleFullscreen();
    }
    async togglePiP() {
        await this.pc.togglePiP();
    }
    toggleSubtitles() {
        this.pc.toggleSubtitles();
    }
    async retry() {
        await this.pc.retry();
    }
    async reload() {
        await this.pc.reload();
    }
    getQualities() {
        return this.pc.getQualities();
    }
    selectQuality(id) {
        this.pc.selectQuality(id);
    }
    destroy() {
        this.pc.hostDisconnected();
    }
    // ---- Render ----
    render() {
        const s = this.pc.s;
        return html `
      <div
        part="root"
        class=${classMap({
            "fw-player-surface": true,
            "fw-player-root": true,
            "w-full": true,
            "h-full": true,
            "overflow-hidden": true,
            flex: this.devMode,
        })}
        data-player-container="true"
        data-theme=${this.theme && this.theme !== "default" ? this.theme : nothing}
        tabindex="0"
        @mouseenter=${() => this.pc.handleMouseEnter()}
        @mouseleave=${() => this.pc.handleMouseLeave()}
        @mousemove=${() => this.pc.handleMouseMove()}
        @touchstart=${() => this.pc.handleTouchStart()}
        @keydown=${this._handleContextMenuShortcut}
        @contextmenu=${this._handleContextMenu}
      >
        <!-- Player area -->
        <div
          class=${classMap({
            "player-area": true,
            "player-area--dev": this.devMode,
        })}
        >
          <!-- Video container -->
          <div id="container" part="video-container" class="fw-player-container"></div>

          ${this._showLoadingPosterOverlay
            ? html `
                <fw-loading-poster
                  style="position:absolute; inset:0; z-index:4;"
                  .loadingPoster=${s.loadingPoster}
                ></fw-loading-poster>
              `
            : nothing}

          <!-- Subtitle renderer -->
          ${s.subtitlesEnabled
            ? html `
                <fw-subtitle-renderer
                  .currentTime=${s.currentTime}
                  .enabled=${s.subtitlesEnabled}
                ></fw-subtitle-renderer>
              `
            : nothing}

          <!-- Title overlay -->
          ${this._showTitleOverlay
            ? html `
                <fw-title-overlay
                  .title=${s.metadata?.title ?? null}
                  .description=${s.metadata?.description ?? null}
                ></fw-title-overlay>
              `
            : nothing}

          <!-- Stats panel -->
          ${this._isStatsOpen
            ? html `
                <fw-stats-panel
                  part="stats-panel"
                  .pc=${this.pc}
                  @fw-close=${() => {
                this._isStatsOpen = false;
            }}
                ></fw-stats-panel>
              `
            : nothing}

          <!-- Speed indicator -->
          ${s.isHoldingSpeed
            ? html ` <fw-speed-indicator .speed=${s.holdSpeed}></fw-speed-indicator> `
            : nothing}

          <!-- Skip indicator -->
          <fw-skip-indicator
            .direction=${this._skipDirection}
            @fw-hide=${() => {
            this._skipDirection = null;
        }}
          ></fw-skip-indicator>

          <!-- Waiting for endpoint -->
          ${this._showWaitingForEndpoint && !this._showLoadingPosterOverlay
            ? html `
                <fw-idle-screen
                  status="OFFLINE"
                  .message=${this._waitingMessage}
                  @fw-retry=${() => {
                this.pc.clearError();
                this.pc.retry();
            }}
                ></fw-idle-screen>
              `
            : nothing}

          <!-- Idle screen -->
          ${!this._showWaitingForEndpoint &&
            s.shouldShowIdleScreen &&
            !this._showLoadingPosterOverlay
            ? html `
                <fw-idle-screen
                  .status=${s.isEffectivelyLive ? s.streamState?.status : undefined}
                  .message=${s.isEffectivelyLive ? s.streamState?.message : this.pc.t("loading")}
                  .percentage=${s.isEffectivelyLive ? s.streamState?.percentage : undefined}
                  @fw-retry=${() => {
                this.pc.clearError();
                this.pc.retry();
            }}
                ></fw-idle-screen>
              `
            : nothing}

          <!-- Buffering spinner -->
          ${this._showBufferingSpinner
            ? html `
                <div role="status" aria-live="polite" class="fw-buffering-overlay">
                  <div class="fw-buffering-pill">
                    <div class="fw-buffering-spinner"></div>
                    <span>${this.pc.t("buffering")}</span>
                  </div>
                </div>
              `
            : nothing}

          <!-- Passive error toast (non-blocking) -->
          ${!s.shouldShowIdleScreen && this._displayedError && this._displayedIsPassive
            ? html `
                <div
                  class="absolute bottom-20 left-1/2 -translate-x-1/2 z-30"
                  style="transition:opacity 300ms;opacity:${this._isErrorDismissing ? "0" : "1"}"
                  role="status"
                  aria-live="polite"
                >
                  <div
                    class="flex items-center gap-2 rounded-lg border border-yellow-500/30 bg-black/80 px-4 py-2 text-sm text-white shadow-lg backdrop-blur-sm"
                  >
                    <span class="text-yellow-400 text-xs font-semibold uppercase"
                      >${this.pc.t("warning")}</span
                    >
                    <span>${this._displayedError}</span>
                    <button
                      type="button"
                      @click=${() => this.pc.clearError()}
                      class="ml-0.5 text-white/60 hover\\:text-white cursor-pointer"
                      aria-label=${this.pc.t("dismiss")}
                    >
                      ${closeIcon()}
                    </button>
                  </div>
                </div>
              `
            : nothing}

          <!-- Fatal error overlay (blocking) — auto-dismisses on playback resume -->
          ${!s.shouldShowIdleScreen && this._displayedError && !this._displayedIsPassive
            ? html `
                <div
                  role="alert"
                  aria-live="assertive"
                  class="fw-error-overlay fw-error-overlay--fullscreen"
                  style="transition:opacity 300ms;opacity:${this._isErrorDismissing ? "0" : "1"}"
                >
                  <div class="fw-error-popup fw-error-popup--fullscreen">
                    <div class="fw-error-header fw-error-header--error">
                      <span class="fw-error-title fw-error-title--error"
                        >${this.pc.t("error")}</span
                      >
                      <button
                        type="button"
                        class="fw-error-close"
                        @click=${() => this.pc.clearError()}
                        aria-label=${this.pc.t("dismiss")}
                      >
                        ${closeIcon()}
                      </button>
                    </div>
                    <div class="fw-error-body">
                      <p class="fw-error-message">${this._displayedError}</p>
                    </div>
                    <div class="fw-error-actions">
                      <button
                        type="button"
                        class="fw-error-btn"
                        aria-label=${this.pc.t("retry")}
                        @click=${() => {
                this.pc.clearError();
                this.pc.retry();
            }}
                      >
                        ${this.pc.t("retry")}
                      </button>
                      ${this.devMode && this.pc.canAttemptFallback()
                ? html `
                            <button
                              type="button"
                              class="fw-error-btn fw-error-btn--secondary"
                              aria-label=${this.pc.t("tryNext")}
                              @click=${() => {
                    this.pc.clearError();
                    this.pc.tryNextSource();
                }}
                            >
                              ${this.pc.t("tryNext")}
                            </button>
                          `
                : nothing}
                      ${this.devMode
                ? html `
                            <button
                              type="button"
                              class="fw-error-btn fw-error-btn--secondary"
                              aria-label=${this.pc.t("reloadPlayer")}
                              @click=${() => {
                    this.pc.clearError();
                    this.pc.reload();
                }}
                            >
                              ${this.pc.t("reloadPlayer")}
                            </button>
                          `
                : nothing}
                    </div>
                  </div>
                </div>
              `
            : nothing}

          <!-- Toast notification -->
          ${s.toast
            ? html `
                <div
                  class="absolute bottom-20 left-1/2 -translate-x-1/2 z-30"
                  role="status"
                  aria-live="polite"
                >
                  <div
                    class="flex items-center gap-2 rounded-lg border border-white/10 bg-black/80 px-4 py-2 text-sm text-white shadow-lg backdrop-blur-sm"
                  >
                    <span>${s.toast.message}</span>
                    <button
                      type="button"
                      @click=${() => this.pc.dismissToast()}
                      class="ml-0.5 text-white/60 hover\\:text-white cursor-pointer"
                      aria-label=${this.pc.t("dismiss")}
                    >
                      ${closeIcon()}
                    </button>
                  </div>
                </div>
              `
            : nothing}

          <!-- Player controls: slot allows custom controls, fallback renders defaults -->
          ${this._controlsEnabled && !this._useStockControls
            ? html `
                <slot name="controls">
                  <fw-player-controls
                    part="controls"
                    .pc=${this.pc}
                    .playbackMode=${this.playbackMode}
                    .isContentLive=${s.isEffectivelyLive}
                    .devMode=${this.devMode}
                    .isStatsOpen=${this._isStatsOpen}
                    .activeLocale=${this.locale ?? "en"}
                    @fw-stats-toggle=${() => {
                this._isStatsOpen = !this._isStatsOpen;
            }}
                    @fw-mode-change=${(event) => {
                this.playbackMode = event.detail.mode;
            }}
                    @fw-locale-change=${(e) => {
                this.locale = e.detail.locale;
            }}
                  ></fw-player-controls>
                </slot>
              `
            : nothing}
        </div>

        <!-- Dev mode side panel -->
        ${this.devMode && this._isDevPanelOpen
            ? html `
              <fw-dev-mode-panel
                .pc=${this.pc}
                .playbackMode=${this.playbackMode}
                @fw-close=${() => {
                this._isDevPanelOpen = false;
            }}
                @fw-playback-mode-change=${(event) => {
                this.playbackMode = event.detail.mode;
            }}
              ></fw-dev-mode-panel>
            `
            : nothing}
      </div>

      <!-- Context menu -->
      <!-- Keep menu in-shadow (no document portal) to preserve host-scoped styling and avoid a global overlay manager. -->
      ${this._contextMenuMounted
            ? html `
            <div
              data-context-menu="true"
              data-state=${this._contextMenuState}
              data-side=${this._contextMenuSide}
              class="fw-context-menu"
              role="menu"
              aria-label="Player options"
              tabindex="-1"
              style="position: absolute; left: ${this._contextMenuX}px; top: ${this
                ._contextMenuY}px;"
              @contextmenu=${(e) => e.preventDefault()}
              @keydown=${this._handleContextMenuKeyDown}
            >
              <button
                type="button"
                role="menuitem"
                tabindex="-1"
                data-context-menu-item="true"
                data-context-menu-level="root"
                class="fw-context-menu-item gap-2"
                @click=${() => {
                this._isStatsOpen = !this._isStatsOpen;
                this._closeContextMenu();
            }}
              >
                <span class="opacity-70 shrink-0">${statsIcon(14)}</span>
                <span>${this._isStatsOpen ? this.pc.t("hideStats") : this.pc.t("showStats")}</span>
              </button>
              ${this.devMode
                ? html `
                    <div class="fw-context-menu-separator"></div>
                    <button
                      type="button"
                      role="menuitem"
                      tabindex="-1"
                      data-context-menu-item="true"
                      data-context-menu-level="root"
                      class="fw-context-menu-item gap-2"
                      @click=${() => {
                    this._isDevPanelOpen = !this._isDevPanelOpen;
                    this._closeContextMenu();
                }}
                    >
                      <span class="opacity-70 shrink-0">${settingsIcon(14)}</span>
                      <span
                        >${this._isDevPanelOpen
                    ? this.pc.t("hideSettings")
                    : this.pc.t("settings")}</span
                      >
                    </button>
                  `
                : nothing}
              <div class="fw-context-menu-separator"></div>
              <button
                type="button"
                role="menuitemcheckbox"
                aria-checked=${String(s.isPiPActive)}
                tabindex="-1"
                data-context-menu-item="true"
                data-context-menu-level="root"
                class="fw-context-menu-item gap-2"
                @click=${() => {
                this.pc.togglePiP();
                this._closeContextMenu();
            }}
              >
                <span class="opacity-70 shrink-0">${pictureInPictureIcon(14)}</span>
                <span>${this.pc.t("pictureInPicture")}</span>
              </button>
              <button
                type="button"
                role="menuitemcheckbox"
                aria-checked=${String(s.isLoopEnabled)}
                tabindex="-1"
                data-context-menu-item="true"
                data-context-menu-level="root"
                class="fw-context-menu-item gap-2"
                @click=${() => {
                this.pc.toggleLoop();
                this._closeContextMenu();
            }}
              >
                <span class="opacity-70 shrink-0">${loopIcon(14)}</span>
                <span>${s.isLoopEnabled ? this.pc.t("disableLoop") : this.pc.t("enableLoop")}</span>
              </button>
            </div>
          `
            : nothing}
    `;
    }
};
FwPlayer.styles = [
    sharedStyles,
    utilityStyles,
    css `
      :host {
        display: block;
        position: relative;
        width: 100%;
        height: 100%;
        min-height: 0;
        overflow: hidden;
        contain: layout style;
      }
      :host([hidden]) {
        display: none;
      }
      .player-area {
        position: relative;
        width: 100%;
        height: 100%;
      }
      .player-area--dev {
        flex: 1;
        min-width: 0;
        min-height: 0;
      }
    `,
];
__decorate([
    property({ attribute: "content-id" })
], FwPlayer.prototype, "contentId", void 0);
__decorate([
    property({ attribute: "content-type" })
], FwPlayer.prototype, "contentType", void 0);
__decorate([
    property({ attribute: "gateway-url" })
], FwPlayer.prototype, "gatewayUrl", void 0);
__decorate([
    property({ attribute: "mist-url" })
], FwPlayer.prototype, "mistUrl", void 0);
__decorate([
    property({ attribute: "auth-token" })
], FwPlayer.prototype, "authToken", void 0);
__decorate([
    property({ attribute: "playback-token" })
], FwPlayer.prototype, "playbackToken", void 0);
__decorate([
    property({ attribute: "playback-token-transport" })
], FwPlayer.prototype, "playbackTokenTransport", void 0);
__decorate([
    property({ type: Boolean })
], FwPlayer.prototype, "autoplay", void 0);
__decorate([
    property({ type: Boolean })
], FwPlayer.prototype, "muted", void 0);
__decorate([
    property({ type: Boolean })
], FwPlayer.prototype, "controls", void 0);
__decorate([
    property({ type: Boolean, attribute: "no-controls" })
], FwPlayer.prototype, "noControls", void 0);
__decorate([
    property({ type: Boolean, attribute: "stock-controls" })
], FwPlayer.prototype, "stockControls", void 0);
__decorate([
    property({ type: Boolean, attribute: "native-controls" })
], FwPlayer.prototype, "nativeControls", void 0);
__decorate([
    property({ type: Boolean, attribute: "animate-preroll" })
], FwPlayer.prototype, "animatePreroll", void 0);
__decorate([
    property({ type: Boolean })
], FwPlayer.prototype, "debug", void 0);
__decorate([
    property({ type: Boolean, attribute: "dev-mode" })
], FwPlayer.prototype, "devMode", void 0);
__decorate([
    property({ attribute: "thumbnail-url" })
], FwPlayer.prototype, "thumbnailUrl", void 0);
__decorate([
    property({ attribute: "playback-mode" })
], FwPlayer.prototype, "playbackMode", void 0);
__decorate([
    property({ attribute: "force-player" })
], FwPlayer.prototype, "forcePlayer", void 0);
__decorate([
    property({ attribute: "force-type" })
], FwPlayer.prototype, "forceType", void 0);
__decorate([
    property({ type: Number, attribute: "force-source" })
], FwPlayer.prototype, "forceSource", void 0);
__decorate([
    property({ attribute: "theme" })
], FwPlayer.prototype, "theme", void 0);
__decorate([
    property({ attribute: false })
], FwPlayer.prototype, "themeOverrides", void 0);
__decorate([
    property({ attribute: "locale" })
], FwPlayer.prototype, "locale", void 0);
__decorate([
    property({ attribute: false })
], FwPlayer.prototype, "translations", void 0);
__decorate([
    property({ attribute: false })
], FwPlayer.prototype, "endpoints", void 0);
__decorate([
    state()
], FwPlayer.prototype, "_isStatsOpen", void 0);
__decorate([
    state()
], FwPlayer.prototype, "_isDevPanelOpen", void 0);
__decorate([
    state()
], FwPlayer.prototype, "_skipDirection", void 0);
__decorate([
    state()
], FwPlayer.prototype, "_contextMenuOpen", void 0);
__decorate([
    state()
], FwPlayer.prototype, "_contextMenuMounted", void 0);
__decorate([
    state()
], FwPlayer.prototype, "_displayedError", void 0);
__decorate([
    state()
], FwPlayer.prototype, "_displayedIsPassive", void 0);
__decorate([
    state()
], FwPlayer.prototype, "_isErrorDismissing", void 0);
__decorate([
    state()
], FwPlayer.prototype, "_contextMenuState", void 0);
__decorate([
    state()
], FwPlayer.prototype, "_contextMenuSide", void 0);
__decorate([
    state()
], FwPlayer.prototype, "_contextMenuX", void 0);
__decorate([
    state()
], FwPlayer.prototype, "_contextMenuY", void 0);
__decorate([
    query("#container")
], FwPlayer.prototype, "_containerEl", void 0);
FwPlayer = __decorate([
    customElement("fw-player")
], FwPlayer);

export { FwPlayer };
//# sourceMappingURL=fw-player.js.map
