import { unsafeCSS, LitElement, nothing, html } from "lit";
import { property } from "lit/decorators.js";
import { classMap } from "lit/directives/class-map.js";
import { styleMap } from "lit/directives/style-map.js";
import componentStyle from "./poi.css.js";
import { ObcPoiButtonType, PoiButtonVisualState, ObcPoiButtonState } from "../poi-button/poi-button.js";
import { ObcPoiHeaderState } from "../poi-header/poi-header.js";
import { POIStyle } from "../poi-graphic-line/poi-graphic-line.js";
import { poiArrow } from "./arrow.js";
import "../poi-line/poi-line.js";
import { ObcPoiPointerType, ObcPoiPointerState } from "../poi-pointer/poi-pointer.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 PoiDataVisualRectPreference = /* @__PURE__ */ ((PoiDataVisualRectPreference2) => {
  PoiDataVisualRectPreference2["Largest"] = "largest";
  PoiDataVisualRectPreference2["Group"] = "group";
  PoiDataVisualRectPreference2["Anchor"] = "anchor";
  PoiDataVisualRectPreference2["Size"] = "size";
  return PoiDataVisualRectPreference2;
})(PoiDataVisualRectPreference || {});
const POI_ATTR = "data-poi-target";
function isPoi(el) {
  return el.hasAttribute(POI_ATTR);
}
var ObcPoiType = /* @__PURE__ */ ((ObcPoiType2) => {
  ObcPoiType2["Line"] = "line";
  ObcPoiType2["Offset"] = "offset";
  ObcPoiType2["Point"] = "point";
  ObcPoiType2["Outside"] = "outside";
  return ObcPoiType2;
})(ObcPoiType || {});
var ObcPoiValue = /* @__PURE__ */ ((ObcPoiValue2) => {
  ObcPoiValue2["Unchecked"] = "unchecked";
  ObcPoiValue2["Checked"] = "checked";
  ObcPoiValue2["Activated"] = "activated";
  ObcPoiValue2["Overlapped"] = "overlapped";
  return ObcPoiValue2;
})(ObcPoiValue || {});
var ObcPoiState = /* @__PURE__ */ ((ObcPoiState2) => {
  ObcPoiState2["Enabled"] = "enabled";
  ObcPoiState2["Caution"] = "caution";
  ObcPoiState2["Warning"] = "warning";
  ObcPoiState2["Alarm"] = "alarm";
  return ObcPoiState2;
})(ObcPoiState || {});
const DEFAULT_LINE_LENGTH_PX = 96;
const POINTER_BOX_BASE_SIZE_PX = 32;
const POINT_POINTER_OFFSET_PX = 12;
let ObcPoi = class extends LitElement {
  constructor() {
    super(...arguments);
    this.type = "line";
    this.value = "unchecked";
    this.state = "enabled";
    this.selected = false;
    this.buttonType = ObcPoiButtonType.Button;
    this.overlapOpaque = false;
    this.data = [];
    this.hasHeader = false;
    this.headerContent = "";
    this.hasPointer = false;
    this.pointerType = null;
    this.pointerState = null;
    this.relativeDirection = 0;
    this.x = 0;
    this.y = DEFAULT_LINE_LENGTH_PX;
    this.buttonY = null;
    this.fixedTarget = false;
    this.buttonOffsetX = 0;
    this.targetOffsetX = 0;
    this.boxWidth = null;
    this.boxHeight = null;
    this.outsideAngle = 315;
    this.animatePosition = false;
    this.slottedButton = null;
  }
  connectedCallback() {
    super.connectedCallback();
    this.setupHeaderObserver();
  }
  disconnectedCallback() {
    super.disconnectedCallback();
    this.headerObserver?.disconnect();
    this.headerObserver = void 0;
  }
  setupHeaderObserver() {
    this.headerObserver?.disconnect();
    this.headerObserver = new MutationObserver((mutations) => {
      for (const mutation of mutations) {
        if (mutation.type === "childList") {
          this.syncFallbackButtonHeaderContent();
          this.syncAttachedHeaderState();
          return;
        }
        if (mutation.type === "attributes" && mutation.target instanceof HTMLElement && mutation.target.getAttribute("slot") === "header") {
          this.syncFallbackButtonHeaderContent();
          this.syncAttachedHeaderState();
          return;
        }
      }
    });
    this.headerObserver.observe(this, {
      childList: true,
      attributes: true,
      attributeFilter: ["slot"]
    });
  }
  updatePosition() {
    this.style.removeProperty("top");
    if (this.fixedTarget) {
      if (typeof this.buttonY === "number" && Number.isFinite(this.buttonY)) {
        const lineLength = Number.isFinite(this.y) ? this.y : 0;
        this.style.setProperty("--obc-poi-y", `${this.buttonY - lineLength}px`);
      } else {
        this.style.removeProperty("--obc-poi-y");
      }
    } else if (typeof this.buttonY === "number" && Number.isFinite(this.buttonY)) {
      this.style.setProperty("--obc-poi-y", `${this.buttonY}px`);
    } else {
      this.style.removeProperty("--obc-poi-y");
    }
  }
  get isCheckedLike() {
    return this.value === "checked" || this.value === "activated";
  }
  get buttonVisualState() {
    switch (this.value) {
      case "unchecked":
        return PoiButtonVisualState.Unchecked;
      case "checked":
        return PoiButtonVisualState.Checked;
      case "activated":
        return PoiButtonVisualState.Activated;
      case "overlapped":
        return PoiButtonVisualState.Overlapped;
      default:
        return PoiButtonVisualState.Unchecked;
    }
  }
  get buttonState() {
    switch (this.state) {
      case "caution":
        return ObcPoiButtonState.Caution;
      case "warning":
        return ObcPoiButtonState.Warning;
      case "alarm":
        return ObcPoiButtonState.Alarm;
      case "enabled":
      default:
        return ObcPoiButtonState.Enabled;
    }
  }
  get resolvedHeaderState() {
    switch (this.buttonState) {
      case ObcPoiButtonState.Caution:
        return ObcPoiHeaderState.Caution;
      case ObcPoiButtonState.Warning:
        return ObcPoiHeaderState.Warning;
      case ObcPoiButtonState.Alarm:
        return ObcPoiHeaderState.Alarm;
      case ObcPoiButtonState.Enabled:
      default:
        return this.selected ? ObcPoiHeaderState.Selected : ObcPoiHeaderState.Enabled;
    }
  }
  get lineStyle() {
    if (this.state === "alarm") {
      return POIStyle.Alarm;
    }
    if (this.state === "warning") {
      return POIStyle.Warning;
    }
    if (this.state === "caution") {
      return POIStyle.Caution;
    }
    if (this.selected) {
      return POIStyle.Selected;
    }
    return POIStyle.Regular;
  }
  get pointerSelected() {
    return this.isCheckedLike;
  }
  get lineOffset() {
    if (this.type === "point" || this.type === "outside") {
      return 0;
    }
    const targetOffsetX = Number.isFinite(this.targetOffsetX) ? this.targetOffsetX : 0;
    const buttonOffsetX = Number.isFinite(this.buttonOffsetX) ? this.buttonOffsetX : 0;
    const lineOffset = targetOffsetX - buttonOffsetX;
    return Number.isFinite(lineOffset) ? lineOffset : 0;
  }
  get hasInlinePointer() {
    if (this.isCheckedLike && this.type !== "outside") {
      return true;
    }
    if (!this.hasPointer) return false;
    return this.type === "line" || this.type === "offset" || this.type === "point";
  }
  get resolvedPointerType() {
    if (this.isCheckedLike || this.state === "enabled") {
      return ObcPoiPointerType.Point;
    }
    return this.pointerType ?? ObcPoiPointerType.Point;
  }
  get resolvedPointerState() {
    if (this.isCheckedLike && this.type !== "outside") {
      return ObcPoiPointerState.Selected;
    }
    if (this.pointerState) {
      return this.pointerState;
    }
    return ObcPoiPointerState.Regular;
  }
  get pointerBoxWidthExtra() {
    if (this.boxWidth === null) {
      return null;
    }
    const width = Number(this.boxWidth);
    if (!Number.isFinite(width)) {
      return null;
    }
    return Math.max(0, width - POINTER_BOX_BASE_SIZE_PX);
  }
  get pointerBoxHeightExtra() {
    if (this.boxHeight === null) {
      return null;
    }
    const height = Number(this.boxHeight);
    if (!Number.isFinite(height)) {
      return null;
    }
    return Math.max(0, height - POINTER_BOX_BASE_SIZE_PX);
  }
  renderLine() {
    if (this.type === "outside") {
      return nothing;
    }
    if (this.type === "point" && (this.isCheckedLike || this.state === "alarm")) {
      return nothing;
    }
    const height = this.type === "point" ? 0 : Number.isFinite(this.y) ? this.y : 0;
    return html`
      <obc-poi-line
        class="line"
        .poiStyle=${this.lineStyle}
        .height=${height}
        .offset=${this.lineOffset}
        .hasPointer=${false}
        .animatePosition=${this.animatePosition}
      ></obc-poi-line>
    `;
  }
  renderInlinePointer() {
    if (!this.hasInlinePointer) {
      return nothing;
    }
    const lineLength = this.type === "point" ? POINT_POINTER_OFFSET_PX : Number.isFinite(this.y) ? this.y : 0;
    return html`
      <obc-poi-pointer
        class="pointer"
        style="--obc-poi-pointer-x: ${this.lineOffset}px; --obc-poi-pointer-y: ${lineLength}px;"
        .type=${this.resolvedPointerType}
        .state=${this.resolvedPointerState}
        .boxWidth=${this.pointerBoxWidthExtra}
        .boxHeight=${this.pointerBoxHeightExtra}
      ></obc-poi-pointer>
    `;
  }
  renderOutsideArrow() {
    if (this.type !== "outside" || !this.hasPointer) {
      return nothing;
    }
    const touchTarget = this.buttonType === ObcPoiButtonType.Enhanced ? 64 : 48;
    const radius = touchTarget / Math.SQRT2;
    const baseCenterYOffset = -touchTarget / 2;
    const angle = this.outsideAngle * Math.PI / 180;
    const xOffset = Math.cos(angle) * radius;
    const yOffset = baseCenterYOffset + Math.sin(angle) * radius;
    const value = this.pointerSelected ? "checked" : "unchecked";
    return html`<div
      class="outside-arrow"
      style="--obc-poi-outside-arrow-x: ${xOffset}px; --obc-poi-outside-arrow-y: ${yOffset}px; --obc-poi-outside-arrow-angle: ${this.outsideAngle}deg;"
    >
      ${poiArrow(value)}
    </div>`;
  }
  handleButtonSlotChange(e) {
    const slot = e.target;
    const assigned = slot.assignedElements({ flatten: false });
    this.slottedButton = assigned.length > 0 ? assigned[0] : null;
    this.syncFallbackButtonHeaderContent();
    this.syncSlottedButtonProps();
  }
  syncFallbackButtonHeaderContent() {
    if (this.slottedButton) {
      return;
    }
    const button = this.renderRoot.querySelector(
      "obc-poi-button.poi-button"
    );
    if (!button) {
      return;
    }
    for (const child of Array.from(this.children)) {
      if (!(child instanceof HTMLElement) || child.getAttribute("slot") !== "header") {
        continue;
      }
      if (child.parentElement !== button) {
        button.appendChild(child);
      }
      this.applyHeaderState(child);
    }
  }
  applyHeaderState(root) {
    const headers = [
      ...root instanceof Element && root.matches("obc-poi-header") ? [root] : [],
      ...root.querySelectorAll("obc-poi-header")
    ];
    for (const header of headers) {
      header.state = this.resolvedHeaderState;
      header.setAttribute("state", this.resolvedHeaderState);
    }
  }
  syncAttachedHeaderState() {
    this.applyHeaderState(this.renderRoot);
  }
  syncSlottedButtonProps() {
    const btn = this.slottedButton;
    if (!btn) return;
    const exportParts = btn.getAttribute("exportparts")?.split(",").map((part) => part.trim()).filter(Boolean);
    if (!exportParts?.includes("icon")) {
      btn.setAttribute(
        "exportparts",
        exportParts?.length ? `${exportParts.join(",")},icon` : "icon"
      );
    }
    const props = btn;
    props.layout = "inline";
    props.relativeDirection = this.relativeDirection;
    props.selected = this.selected;
    props.hasHeader = this.hasHeader;
    props.headerContent = this.headerContent;
    props.state = this.buttonState;
    props.value = this.buttonVisualState;
    props.overlapOpaque = this.overlapOpaque;
    props.type = this.buttonType;
    props.data = this.data;
  }
  renderPoiButton() {
    return html`
      <slot name="button" @slotchange=${this.handleButtonSlotChange}>
        <obc-poi-button
          layout="inline"
          class=${classMap({
      "poi-button": true,
      overlapped: this.value === "overlapped"
      /* Overlapped */
    })}
          exportparts="icon"
          .relativeDirection=${this.relativeDirection}
          .selected=${this.selected}
          .hasHeader=${this.hasHeader}
          .headerContent=${this.headerContent}
          .state=${this.buttonState}
          .value=${this.buttonVisualState}
          .overlapOpaque=${this.overlapOpaque}
          .type=${this.buttonType}
          .data=${this.data}
        >
          <slot></slot>
        </obc-poi-button>
      </slot>
    `;
  }
  render() {
    const classes = {
      wrapper: true,
      [`type-${this.type}`]: true,
      [`button-${this.buttonType}`]: true,
      [`value-${this.value}`]: true,
      [`state-${this.state}`]: true,
      "has-data": this.data.length > 0,
      "no-motion": !this.animatePosition
    };
    const wrapperStyle = this.buttonOffsetX !== 0 ? { "--obc-poi-target-top-offset-x": `${this.buttonOffsetX}px` } : {};
    return html`
      <div class=${classMap(classes)} style=${styleMap(wrapperStyle)}>
        ${this.renderPoiButton()} ${this.renderLine()}
        ${this.renderInlinePointer()} ${this.renderOutsideArrow()}
      </div>
    `;
  }
  firstUpdated(_changedProperties) {
    this.syncFallbackButtonHeaderContent();
    this.syncAttachedHeaderState();
  }
  updated(changedProperties) {
    super.updated(changedProperties);
    if (changedProperties.has("x")) {
      this.style.removeProperty("left");
      this.style.setProperty("--obc-poi-x", `${this.x}px`);
    }
    if (changedProperties.has("buttonY") || changedProperties.has("y") || changedProperties.has("fixedTarget")) {
      this.updatePosition();
    }
    this.syncFallbackButtonHeaderContent();
    this.syncSlottedButtonProps();
    this.syncAttachedHeaderState();
  }
};
ObcPoi.styles = unsafeCSS(componentStyle);
__decorateClass([
  property({ type: String })
], ObcPoi.prototype, "type", 2);
__decorateClass([
  property({ type: String })
], ObcPoi.prototype, "value", 2);
__decorateClass([
  property({ type: String })
], ObcPoi.prototype, "state", 2);
__decorateClass([
  property({ type: Boolean })
], ObcPoi.prototype, "selected", 2);
__decorateClass([
  property({ type: String })
], ObcPoi.prototype, "buttonType", 2);
__decorateClass([
  property({ type: Boolean, attribute: "overlap-opaque" })
], ObcPoi.prototype, "overlapOpaque", 2);
__decorateClass([
  property({ type: Array, attribute: false })
], ObcPoi.prototype, "data", 2);
__decorateClass([
  property({ type: Boolean, attribute: "has-header" })
], ObcPoi.prototype, "hasHeader", 2);
__decorateClass([
  property({ type: String, attribute: "header-content" })
], ObcPoi.prototype, "headerContent", 2);
__decorateClass([
  property({ type: Boolean })
], ObcPoi.prototype, "hasPointer", 2);
__decorateClass([
  property({ type: String, attribute: "pointer-type" })
], ObcPoi.prototype, "pointerType", 2);
__decorateClass([
  property({ type: String, attribute: "pointer-state" })
], ObcPoi.prototype, "pointerState", 2);
__decorateClass([
  property({ type: Number })
], ObcPoi.prototype, "relativeDirection", 2);
__decorateClass([
  property({ type: Number })
], ObcPoi.prototype, "x", 2);
__decorateClass([
  property({ type: Number })
], ObcPoi.prototype, "y", 2);
__decorateClass([
  property({ type: Number, attribute: "button-y" })
], ObcPoi.prototype, "buttonY", 2);
__decorateClass([
  property({ type: Boolean, attribute: "fixed-target" })
], ObcPoi.prototype, "fixedTarget", 2);
__decorateClass([
  property({ type: Number, attribute: "button-offset-x" })
], ObcPoi.prototype, "buttonOffsetX", 2);
__decorateClass([
  property({ type: Number, attribute: "target-offset-x" })
], ObcPoi.prototype, "targetOffsetX", 2);
__decorateClass([
  property({ type: Number, attribute: "box-width" })
], ObcPoi.prototype, "boxWidth", 2);
__decorateClass([
  property({ type: Number, attribute: "box-height" })
], ObcPoi.prototype, "boxHeight", 2);
__decorateClass([
  property({ type: Number, attribute: "outside-angle" })
], ObcPoi.prototype, "outsideAngle", 2);
__decorateClass([
  property({ type: Boolean, attribute: "animate-position" })
], ObcPoi.prototype, "animatePosition", 2);
ObcPoi = __decorateClass([
  customElement("obc-poi")
], ObcPoi);
export {
  ObcPoi,
  ObcPoiState,
  ObcPoiType,
  ObcPoiValue,
  POI_ATTR,
  PoiDataVisualRectPreference,
  isPoi
};
//# sourceMappingURL=poi.js.map
