import {
  __decorateClass,
  __privateAdd,
  __privateGet,
  __privateMethod,
  __privateSet
} from "../../chunks/chunk.QU3DSPNU.js";
var _value, _GdsSegmentedControl_instances, handleSlotChange_fn, _scrollLeft, _scrollRight, _updateScrollBtnState, _updateScrollBtnStateDebounced, _updateIndicator, _handleSegmentClick, _updateSelectedFromValue;
import { localized, msg } from "@lit/localize";
import { property, query, state } from "lit/decorators.js";
import { GdsElement } from "../../gds-element.js";
import { gdsCustomElement, html } from "../../scoping.js";
import { tokens } from "../../tokens.style.js";
import { TransitionalStyles } from "../../transitional-styles.js";
import { resizeObserver } from "../../utils/decorators/resize-observer.js";
import { watch } from "../../utils/decorators/watch.js";
import {
  withLayoutChildProps,
  withMarginProps,
  withSizeXProps
} from "../../utils/mixins/declarative-layout-mixins.js";
import { IconChevronLeft } from "../icon/icons/chevron-left.component.js";
import { IconChevronRight } from "../icon/icons/chevron-right.component.js";
import { GdsSegment } from "./segment/segment.component.js";
import SegmentedControlStyles from "./segmented-control.styles.js";
const debounce = (fn, delay) => {
  let timeoutId;
  return () => {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(fn, delay);
  };
};
let GdsSegmentedControl = class extends withLayoutChildProps(
  withSizeXProps(withMarginProps(GdsElement))
) {
  constructor() {
    super(...arguments);
    __privateAdd(this, _GdsSegmentedControl_instances);
    this.size = "medium";
    __privateAdd(this, _value);
    this._showPrevButton = false;
    this._showNextButton = false;
    this.intersectionObserver = null;
    __privateAdd(this, _scrollLeft, () => {
      const nextLeftOutOfView = this.segments.filter(
        (s, i, arr) => arr[i + 1]?.isVisible && !s.isVisible
      )[0];
      if (!nextLeftOutOfView) return;
      this._elTrack.scrollLeft -= nextLeftOutOfView.offsetWidth;
    });
    __privateAdd(this, _scrollRight, () => {
      const nextRightOutOfView = this.segments.filter((s, i, arr) => arr[i - 1]?.isVisible && !s.isVisible).reverse()[0];
      if (!nextRightOutOfView) return;
      this._elTrack.scrollLeft += nextRightOutOfView.offsetWidth;
    });
    // Updates the visibility of the scroll buttons
    __privateAdd(this, _updateScrollBtnState, () => {
      if (this.segments.every((s) => !s.isVisible)) return;
      this._showPrevButton = !this.segments[0].isVisible;
      this._showNextButton = !this.segments[this.segments.length - 1].isVisible;
    });
    __privateAdd(this, _updateScrollBtnStateDebounced, debounce(__privateGet(this, _updateScrollBtnState), 50));
    // Updates the selection indicator position
    __privateAdd(this, _updateIndicator, () => {
      const segment = this.segments.find((s) => s.selected);
      if (segment) {
        const segmentWidth = segment.offsetWidth;
        const segmentLeft = segment.offsetLeft;
        this._elIndicator.style.transform = `translateX(${segmentLeft}px)`;
        this._elIndicator.style.width = `${segmentWidth}px`;
      } else {
        this._elIndicator.style.transform = `translateX(-100%)`;
        this._elIndicator.style.width = `0px`;
      }
    });
    __privateAdd(this, _handleSegmentClick, (event) => {
      const selectedSegment = this.segments.find(
        (s) => s === event.target || s.contains(event.target)
      );
      if (selectedSegment) {
        this.segments.forEach((s) => s.selected = false);
        selectedSegment.selected = true;
        __privateSet(this, _value, selectedSegment.value);
        __privateGet(this, _updateIndicator).call(this);
        this.dispatchCustomEvent("change", {
          detail: { segment: selectedSegment },
          bubbles: true,
          composed: true
        });
      }
    });
    __privateAdd(this, _updateSelectedFromValue, () => {
      if (!__privateGet(this, _value)) return;
      this.updateComplete.then(() => {
        const selectedSegment = this.segments.find((s) => s.value === __privateGet(this, _value));
        if (selectedSegment) {
          this.segments.forEach((s) => s.selected = false);
          selectedSegment.selected = true;
          selectedSegment.scrollIntoView({
            block: "nearest",
            inline: "nearest"
          });
        }
      });
    });
  }
  get value() {
    return __privateGet(this, _value);
  }
  set value(val) {
    __privateSet(this, _value, val);
    __privateGet(this, _updateSelectedFromValue).call(this);
  }
  /**
   * Returns the segments in the control
   * @readonly
   */
  get segments() {
    return this._elSlot ? this._elSlot.assignedElements() : [];
  }
  connectedCallback() {
    super.connectedCallback();
    TransitionalStyles.instance.apply(this, "gds-segmented-control");
    this.updateComplete.then(() => {
      this._elTrack.addEventListener("scroll", () => {
        __privateGet(this, _updateScrollBtnStateDebounced).call(this);
      });
    });
  }
  render() {
    return html`<button
        aria-hidden=${!this._showPrevButton}
        ?inert=${!this._showPrevButton}
        id="btn-prev"
        @click=${__privateGet(this, _scrollLeft)}
        aria-label=${msg("Scroll right")}
      >
        <gds-icon-chevron-left />
      </button>
      <div id="track" role="list">
        <slot
          @click=${__privateGet(this, _handleSegmentClick)}
          @slotchange=${__privateMethod(this, _GdsSegmentedControl_instances, handleSlotChange_fn)}
          role="none"
        ></slot>
        <div id="indicator" role="none"></div>
      </div>
      <button
        aria-hidden=${!this._showNextButton}
        ?inert=${!this._showNextButton}
        id="btn-next"
        @click=${__privateGet(this, _scrollRight)}
        aria-label=${msg("Scroll right")}
      >
        <gds-icon-chevron-right />
      </button>`;
  }
  _recalculateMinWidth() {
    this.updateComplete.then(() => {
      __privateGet(this, _updateScrollBtnStateDebounced).call(this);
      __privateGet(this, _updateIndicator).call(this);
    });
  }
};
_value = new WeakMap();
_GdsSegmentedControl_instances = new WeakSet();
handleSlotChange_fn = function() {
  const selSegmentValue = this.segments.find((s) => s.selected)?.value;
  if (selSegmentValue) {
    __privateSet(this, _value, selSegmentValue);
  }
  this.intersectionObserver?.disconnect();
  this.intersectionObserver = new IntersectionObserver(
    (entries) => {
      entries.forEach((entry) => {
        const segment = entry.target;
        segment._isVisible = entry.intersectionRatio > 0.99;
        __privateGet(this, _updateScrollBtnStateDebounced).call(this);
      });
    },
    {
      root: this._elTrack,
      threshold: [0, 0.01, 0.5, 0.99, 1]
    }
  );
  this.segments.forEach((s) => {
    this.intersectionObserver?.observe(s);
  });
};
_scrollLeft = new WeakMap();
_scrollRight = new WeakMap();
_updateScrollBtnState = new WeakMap();
_updateScrollBtnStateDebounced = new WeakMap();
_updateIndicator = new WeakMap();
_handleSegmentClick = new WeakMap();
_updateSelectedFromValue = new WeakMap();
GdsSegmentedControl.styles = [tokens, SegmentedControlStyles];
__decorateClass([
  property({ reflect: true })
], GdsSegmentedControl.prototype, "size", 2);
__decorateClass([
  property()
], GdsSegmentedControl.prototype, "value", 1);
__decorateClass([
  query("slot")
], GdsSegmentedControl.prototype, "_elSlot", 2);
__decorateClass([
  query("#indicator")
], GdsSegmentedControl.prototype, "_elIndicator", 2);
__decorateClass([
  query("#track")
], GdsSegmentedControl.prototype, "_elTrack", 2);
__decorateClass([
  state()
], GdsSegmentedControl.prototype, "_showPrevButton", 2);
__decorateClass([
  state()
], GdsSegmentedControl.prototype, "_showNextButton", 2);
__decorateClass([
  resizeObserver(),
  watch("value")
], GdsSegmentedControl.prototype, "_recalculateMinWidth", 1);
GdsSegmentedControl = __decorateClass([
  gdsCustomElement("gds-segmented-control", {
    dependsOn: [GdsSegment, IconChevronLeft, IconChevronRight]
  }),
  localized()
], GdsSegmentedControl);
export {
  GdsSegmentedControl
};
