import { unsafeCSS, LitElement, html } from "lit";
import { property, state, query } from "lit/decorators.js";
import componentStyle from "./start-stop-switch.css.js";
import { classMap } from "lit/directives/class-map.js";
import "../../icons/icon-arrow-right-google.js";
import { customElement } from "../../decorator.js";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __decorateClass = (decorators, target, key, kind) => {
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
    if (decorator = decorators[i])
      result = (kind ? decorator(target, key, result) : decorator(result)) || result;
  if (kind && result) __defProp(target, key, result);
  return result;
};
var StartStopSwitchVariant = /* @__PURE__ */ ((StartStopSwitchVariant2) => {
  StartStopSwitchVariant2["normal"] = "normal";
  StartStopSwitchVariant2["running"] = "running";
  StartStopSwitchVariant2["loading"] = "loading";
  return StartStopSwitchVariant2;
})(StartStopSwitchVariant || {});
var StartStopSwitchSize = /* @__PURE__ */ ((StartStopSwitchSize2) => {
  StartStopSwitchSize2["regular"] = "regular";
  StartStopSwitchSize2["large"] = "large";
  return StartStopSwitchSize2;
})(StartStopSwitchSize || {});
const DRAG_COMPLETE_THRESHOLD = 0.9;
let ObcStartStopSwitch = class extends LitElement {
  constructor() {
    super(...arguments);
    this.checked = false;
    this.showUncheckedStateIcon = false;
    this.variant = "normal";
    this.showCheckedStateIcon = false;
    this.size = "regular";
    this.disabled = false;
    this.hasAlert = false;
    this.hasDescription = false;
    this.description = "Action description";
    this.dragging = false;
    this.tmpChecked = false;
    this.dragStartX = 0;
    this.dragCurrentX = 0;
    this.dragOffset = 0;
    this.trackWidth = 0;
    this.buttonWidth = 0;
    this.onDragStart = (e) => {
      this.dragging = true;
      if (e instanceof MouseEvent) {
        this.dragStartX = e.clientX;
      } else {
        this.dragStartX = e.touches[0].clientX;
      }
      this.dragCurrentX = this.dragStartX;
      const trackRect = this.trackRef?.getBoundingClientRect();
      const buttonRect = this.buttonRef?.getBoundingClientRect();
      if (trackRect && buttonRect) {
        this.trackWidth = trackRect.width;
        this.buttonWidth = buttonRect.width;
      } else {
        this.trackWidth = this.trackRef?.offsetWidth || 0;
        this.buttonWidth = this.buttonRef?.offsetWidth || 0;
      }
      window.addEventListener("mousemove", this.onDragMove);
      window.addEventListener("touchmove", this.onDragMove, { passive: false });
      window.addEventListener("mouseup", this.onDragEnd);
      window.addEventListener("touchend", this.onDragEnd);
    };
    this.onDragMove = (e) => {
      if (!this.dragging) return;
      let clientX;
      if (e instanceof MouseEvent) {
        clientX = e.clientX;
      } else {
        clientX = e.touches[0].clientX;
        e.preventDefault();
      }
      this.dragCurrentX = clientX;
      this.dragOffset = this.dragCurrentX - this.dragStartX;
      const percent = Math.abs(
        this.dragOffset / (this.trackWidth - this.buttonWidth)
      );
      this.tmpChecked = this.checked ? percent < 0.5 : percent > 0.5;
      this.requestUpdate();
    };
    this.onDragEnd = () => {
      if (!this.dragging) return;
      this.dragging = false;
      const maxOffset = this.trackWidth - this.buttonWidth;
      const startPosition = this.checked ? maxOffset : 0;
      const newPosition = startPosition + this.dragOffset;
      const percent = newPosition / maxOffset;
      if (!this.checked && percent > DRAG_COMPLETE_THRESHOLD) {
        this.checked = true;
        this.dispatchChangeEvent();
      } else if (this.checked && percent < 1 - DRAG_COMPLETE_THRESHOLD) {
        this.checked = false;
        this.dispatchChangeEvent();
      }
      this.tmpChecked = this.checked;
      this.dragOffset = 0;
      window.removeEventListener("mousemove", this.onDragMove);
      window.removeEventListener("touchmove", this.onDragMove);
      window.removeEventListener("mouseup", this.onDragEnd);
      window.removeEventListener("touchend", this.onDragEnd);
      this.requestUpdate();
    };
  }
  dispatchChangeEvent() {
    this.dispatchEvent(
      new CustomEvent("change", {
        detail: { checked: this.checked },
        bubbles: true,
        composed: true
      })
    );
  }
  getButtonStyle() {
    if (!this.dragging) return "";
    if (this.checked) {
      let right = -1 - this.dragOffset;
      const maxRight = this.trackWidth - this.buttonWidth + 1;
      right = Math.max(-1, Math.min(right, maxRight));
      return `right: ${right}px; left: auto; transition: none;`;
    } else {
      let left = -1 + this.dragOffset;
      const maxLeft = this.trackWidth - this.buttonWidth + 1;
      left = Math.max(-1, Math.min(left, maxLeft));
      return `left: ${left}px; right: auto; transition: none;`;
    }
  }
  firstUpdated() {
    this.resizeObserver = new ResizeObserver(() => {
      this.trackWidth = this.trackRef?.offsetWidth || 0;
      this.buttonWidth = this.buttonRef?.offsetWidth || 0;
    });
    if (this.trackRef) this.resizeObserver.observe(this.trackRef);
    if (this.buttonRef) this.resizeObserver.observe(this.buttonRef);
  }
  updated(changedProperties) {
    super.updated(changedProperties);
    if (changedProperties.has("checked") && !this.dragging) {
      const trackChecked = this.renderRoot.querySelector(
        ".button-track-checked"
      );
      const button = this.buttonRef;
      if (trackChecked && button) {
        const nudgeRepaint = () => {
          trackChecked.style.display = "none";
          void trackChecked.offsetHeight;
          trackChecked.style.display = "";
        };
        requestAnimationFrame(() => {
          const animations = button.getAnimations();
          if (animations.length > 0) {
            Promise.allSettled(animations.map((a) => a.finished)).then(
              nudgeRepaint
            );
          } else {
            nudgeRepaint();
          }
        });
      }
    }
  }
  disconnectedCallback() {
    super.disconnectedCallback();
    this.resizeObserver?.disconnect();
    window.removeEventListener("mousemove", this.onDragMove);
    window.removeEventListener("touchmove", this.onDragMove);
    window.removeEventListener("mouseup", this.onDragEnd);
    window.removeEventListener("touchend", this.onDragEnd);
  }
  render() {
    const isChecked = this.checked;
    return html`
              <div class="outer-container">
                <div
                  class=${classMap({
      wrapper: true,
      checked: isChecked,
      unchecked: !isChecked,
      dragging: this.dragging,
      "tmp-checked": this.tmpChecked && this.dragging,
      "tmp-unchecked": !this.tmpChecked && this.dragging,
      disabled: this.disabled,
      "has-alert": this.hasAlert,
      "size-regular": this.size === "regular",
      "size-large": this.size === "large",
      "variant-normal": this.variant === "normal",
      "variant-running": this.variant === "running",
      "variant-loading": this.variant === "loading"
    })}
                  tabindex=${this.disabled ? -1 : 0}
                >
                  <div class="button-track">
                    <button
                      class="button"
                      style=${this.getButtonStyle()}
                      @mousedown=${this.disabled ? void 0 : this.onDragStart}
                      @touchstart=${this.disabled ? void 0 : this.onDragStart}
                      ?disabled=${this.disabled}
                      tabindex="-1"
                      role="switch"
                      aria-checked=${isChecked ? "true" : "false"}
                      aria-disabled=${this.disabled ? "true" : "false"}
                    >
                      ${!this.disabled ? html`
                              <div class="button-visible">
                                <obi-arrow-right-google
                                  class="button-icon"
                                ></obi-arrow-right-google>
                                <div class="button-label">
                                  <slot
                                    name=${isChecked ? "to-unchecked-action-label" : "to-checked-action-label"}
                                  ></slot>
                                </div>
                              </div>
                            ` : ""}
                    </button>
                    ${!this.disabled ? html`<div class="button-track-checked"></div>` : ""}
                    <div class="checked state">
                      <slot name="checked-state-icon"></slot>
                      <div class="state-label">
                        <slot name="checked-state-label"></slot>
                      </div>
                    </div>
                    <div class="unchecked state">
                      <slot name="unchecked-state-icon"></slot>
                      <div class="state-label">
                        <slot name="unchecked-state-label"></slot>
                      </div>
                    </div>
                  </div>
                  ${this.hasAlert ? html`<div class="alert-frame"></div>` : ""}
                </div>
                ${this.hasDescription ? html`<div class="description">${this.description}</div>` : ""}
              </div>
            </div>
          </div>
        </div>
      </div>
    `;
  }
};
ObcStartStopSwitch.styles = unsafeCSS(componentStyle);
__decorateClass([
  property({ type: Boolean, reflect: true })
], ObcStartStopSwitch.prototype, "checked", 2);
__decorateClass([
  property({ type: Boolean })
], ObcStartStopSwitch.prototype, "showUncheckedStateIcon", 2);
__decorateClass([
  property({ type: String, reflect: true })
], ObcStartStopSwitch.prototype, "variant", 2);
__decorateClass([
  property({ type: Boolean })
], ObcStartStopSwitch.prototype, "showCheckedStateIcon", 2);
__decorateClass([
  property({ type: String, reflect: true })
], ObcStartStopSwitch.prototype, "size", 2);
__decorateClass([
  property({ type: Boolean, reflect: true })
], ObcStartStopSwitch.prototype, "disabled", 2);
__decorateClass([
  property({ type: Boolean })
], ObcStartStopSwitch.prototype, "hasAlert", 2);
__decorateClass([
  property({ type: Boolean })
], ObcStartStopSwitch.prototype, "hasDescription", 2);
__decorateClass([
  property({ type: String })
], ObcStartStopSwitch.prototype, "description", 2);
__decorateClass([
  state()
], ObcStartStopSwitch.prototype, "dragging", 2);
__decorateClass([
  state()
], ObcStartStopSwitch.prototype, "tmpChecked", 2);
__decorateClass([
  query(".button")
], ObcStartStopSwitch.prototype, "buttonRef", 2);
__decorateClass([
  query(".button-track")
], ObcStartStopSwitch.prototype, "trackRef", 2);
ObcStartStopSwitch = __decorateClass([
  customElement("obc-start-stop-switch")
], ObcStartStopSwitch);
export {
  ObcStartStopSwitch,
  StartStopSwitchSize,
  StartStopSwitchVariant
};
//# sourceMappingURL=start-stop-switch.js.map
