import { unsafeCSS, LitElement, nothing, html } from "lit";
import { property } from "lit/decorators.js";
import compentStyle from "./context-menu-input.css.js";
import "../../icons/icon-arrow-flyout-google.js";
import "../../icons/icon-close-google.js";
import "../checkbox-item/checkbox-item.js";
import "../navigation-item/navigation-item.js";
import { ObcNavigationMenuVariant } from "../navigation-menu/navigation-menu.js";
import { customElement } from "../../decorator.js";
import { classMap } from "lit/directives/class-map.js";
import "../icon-button/icon-button.js";
import "../navigation-item-group/navigation-item-group.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 ContextMenuType = /* @__PURE__ */ ((ContextMenuType2) => {
  ContextMenuType2["Regular"] = "regular";
  ContextMenuType2["Checkboxes"] = "checkboxes";
  ContextMenuType2["NestedCheckboxes"] = "nested-checkboxes";
  ContextMenuType2["Flyout"] = "flyout";
  ContextMenuType2["Multi"] = "multi";
  ContextMenuType2["MultiWithSubtitles"] = "multi-with-subtitles";
  return ContextMenuType2;
})(ContextMenuType || {});
let ObcContextMenuInput = class extends LitElement {
  constructor() {
    super(...arguments);
    this.type = "regular";
    this.options = [];
    this.selectedValues = [];
    this.hasTitleBar = false;
    this.title = "";
    this.columnGroups = [];
    this.itemsPerColumn = 5;
  }
  get isMultiSelect() {
    if (this.multiSelect !== void 0) return this.multiSelect;
    return [
      "checkboxes",
      "nested-checkboxes",
      "multi",
      "multi-with-subtitles"
      /* MultiWithSubtitles */
    ].includes(this.type);
  }
  get isPerGroupSingleSelect() {
    if (this.isMultiSelect) return false;
    if (this.selectPerGroup !== void 0) return this.selectPerGroup;
    return this.type === "flyout";
  }
  /**
   * Returns a unique group-key for each option:
   * - In multi-with-subtitles: group title + subcolumn index (each subcolumn is a group)
   * - In multi: column index (each column is a group)
   */
  getGroupForValue(value) {
    if (this.type === "multi-with-subtitles" && this.columnGroups.length) {
      for (const group of this.columnGroups) {
        const totalCols = Math.max(
          group.columns,
          Math.ceil(group.options.length / this.itemsPerColumn)
        );
        const distributed = this.chunkArray(
          group.options,
          this.itemsPerColumn,
          totalCols
        );
        for (let subColIdx = 0; subColIdx < distributed.length; ++subColIdx) {
          if (distributed[subColIdx].some((opt) => opt.value === value)) {
            return `${group.title}___${subColIdx}`;
          }
        }
      }
      return void 0;
    }
    if (this.type === "multi" && this.itemsPerColumn > 0) {
      const columns = this.chunkArray(this.options, this.itemsPerColumn);
      for (let colIdx = 0; colIdx < columns.length; ++colIdx) {
        if (columns[colIdx].some((opt) => opt.value === value)) {
          return `column-${colIdx}`;
        }
      }
      return void 0;
    }
    if (this.type === "flyout" && this.options.length) {
      for (const group of this.options) {
        if (group.children?.some((child) => child.value === value)) {
          return group.value;
        }
        if (group.value === value) return group.value;
      }
      return void 0;
    }
    return void 0;
  }
  handleCheckboxChange(option, e) {
    const { status } = e.detail;
    let next;
    if (this.selectPerGroup && (this.type === "multi" || this.type === "multi-with-subtitles")) {
      const groupKey = this.getGroupForValue(option.value);
      next = [
        ...this.selectedValues.filter(
          (val) => this.getGroupForValue(val) !== groupKey
        ),
        ...status === "checked" ? [option.value] : []
      ];
    } else {
      next = status === "checked" ? [...this.selectedValues, option.value] : this.selectedValues.filter((v) => v !== option.value);
    }
    if (!arraysEqual(this.selectedValues, next)) this.updateSelection(next);
  }
  handleMenuItemClick(option, event) {
    event.preventDefault();
    this.dispatchEvent(
      new CustomEvent(
        "item-click",
        {
          detail: { value: option.value, option }
        }
      )
    );
    if (option.children?.length) return;
    let newSelectedValues;
    if (this.isPerGroupSingleSelect) {
      const groupKey = this.getGroupForValue ? this.getGroupForValue(option.value) : void 0;
      const selectedInGroup = this.selectedValues.find(
        (val) => this.getGroupForValue(val) === groupKey
      );
      if (selectedInGroup === option.value) {
        newSelectedValues = this.selectedValues.filter(
          (val) => val !== option.value
        );
      } else {
        newSelectedValues = [
          ...this.selectedValues.filter(
            (val) => this.getGroupForValue(val) !== groupKey
          ),
          option.value
        ];
      }
    } else {
      if (this.selectedValues.includes(option.value)) {
        newSelectedValues = [];
      } else {
        newSelectedValues = [option.value];
      }
    }
    if (!arraysEqual(this.selectedValues, newSelectedValues))
      this.updateSelection(newSelectedValues);
  }
  updateSelection(vals) {
    this.selectedValues = vals;
    const selectedOptions = [];
    const collect = (arr) => arr.forEach((o) => {
      if (vals.includes(o.value)) selectedOptions.push(o);
      if (o.children) collect(o.children);
    });
    collect(this.options);
    this.dispatchEvent(
      new CustomEvent("change", {
        detail: { selectedValues: vals, selectedOptions }
      })
    );
  }
  handleCloseClick(e) {
    e.preventDefault();
    this.dispatchEvent(new CustomEvent("close"));
  }
  isOptionSelected(v) {
    return this.selectedValues.includes(v);
  }
  renderTitleBar() {
    if (!this.hasTitleBar) return nothing;
    return html`
      <div class="title-container">
        <div class="title-content">
          <div class="title-text">${this.title}</div>
        </div>
        <obc-icon-button
          variant="flat"
          @click=${this.handleCloseClick}
          aria-label="Close menu"
        >
          <obi-close-google></obi-close-google>
        </obc-icon-button>
      </div>
    `;
  }
  renderRegularItems() {
    return this.options.map((o) => this.renderNavItem(o));
  }
  renderCheckboxItems() {
    return this.options.map((o) => {
      const isSelected = this.isOptionSelected(o.value);
      const isNested = this.type === "nested-checkboxes" && o.level && o.level > 1;
      const indent = isNested ? (o.level - 1) * 16 : 0;
      return html`<div
        class="menu-item checkbox-item-wrapper"
        style=${indent ? `padding-left:${indent}px` : ""}
      >
        <obc-checkbox-item
          .label=${o.label}
          .status=${isSelected ? "checked" : "unchecked"}
          @change=${(e) => this.handleCheckboxChange(o, e)}
        ></obc-checkbox-item>
      </div>`;
    });
  }
  renderNavItem(o) {
    const isSelected = this.isOptionSelected(o.value);
    const indent = o.level ? (o.level - 1) * 16 : 0;
    return html`<div
      class="menu-item navigation-item-wrapper"
      style=${indent ? `padding-left:${indent}px` : ""}
    >
      <obc-navigation-item
        .label=${o.label}
        .checked=${isSelected}
        .variant=${ObcNavigationMenuVariant.Full}
        @click=${(e) => this.handleMenuItemClick(o, e)}
        role="menuitem"
        aria-selected=${isSelected}
        ?hasIcon=${!!o.icon}
      >
        ${o.icon ? html`<div slot="icon">${o.icon}</div>` : nothing}
      </obc-navigation-item>
    </div>`;
  }
  // Renders checkboxes for children if multi, otherwise navigation items
  renderFlyoutChildren(children) {
    if (this.isMultiSelect) {
      return children.map((c) => {
        const isSelected = this.isOptionSelected(c.value);
        return html`<div class="menu-item checkbox-item-wrapper">
          <obc-checkbox-item
            .label=${c.label}
            .status=${isSelected ? "checked" : "unchecked"}
            @change=${(e) => this.handleCheckboxChange(c, e)}
          ></obc-checkbox-item>
        </div>`;
      });
    }
    return children.map((c) => {
      const isSelected = this.isOptionSelected(c.value);
      return html`<obc-navigation-item
        .label=${c.label}
        .checked=${isSelected}
        .variant=${ObcNavigationMenuVariant.Full}
        @click=${(e) => this.handleMenuItemClick(c, e)}
        role="menuitem"
        aria-selected=${isSelected}
        ?hasIcon=${!!c.icon}
      >
        ${c.icon ? html`<div slot="icon">${c.icon}</div>` : nothing}
      </obc-navigation-item>`;
    });
  }
  handleFlyoutGroupClick(option, event) {
    event.preventDefault();
    this.dispatchEvent(
      new CustomEvent(
        "item-click",
        {
          detail: { value: option.value, option }
        }
      )
    );
  }
  renderFlyoutItems() {
    return this.options.map((o) => {
      const isSelected = this.isOptionSelected(o.value);
      if (o.children?.length) {
        return html`<obc-navigation-item-group
          .label=${o.label}
          .checked=${isSelected}
          .variant=${ObcNavigationMenuVariant.Full}
          .hug=${true}
          .hasIcon=${!!o.icon}
          @click=${(e) => this.handleFlyoutGroupClick(o, e)}
          @open=${() => {
          this.shadowRoot?.querySelectorAll("obc-navigation-item-group").forEach((g) => {
            const group = g;
            if (group.label !== o.label) group.close();
          });
        }}
        >
          ${o.icon ? html`<div slot="icon">${o.icon}</div>` : nothing}
          ${this.renderFlyoutChildren(o.children)}
        </obc-navigation-item-group>`;
      }
      return this.renderNavItem(o);
    });
  }
  // --------- MULTI COLUMN ---------
  renderMultiColumnItems() {
    const renderColumn = (columnOptions) => {
      if (!columnOptions.length) return nothing;
      if (this.isMultiSelect && !this.selectPerGroup) {
        return columnOptions.map((o) => {
          const isSelected = this.isOptionSelected(o.value);
          return html`<div class="menu-item checkbox-item-wrapper">
            <obc-checkbox-item
              .label=${o.label}
              .status=${isSelected ? "checked" : "unchecked"}
              @change=${(e) => this.handleCheckboxChange(o, e)}
            ></obc-checkbox-item>
          </div>`;
        });
      }
      return columnOptions.map((opt) => this.renderNavItem(opt));
    };
    if (this.type === "multi-with-subtitles") {
      if (!this.columnGroups.length) {
        const cols = this.chunkArray(this.options, this.itemsPerColumn);
        return html`<div class="multi-content">
          <div class="multi-columns">
            <div class="columns-container">
              ${cols.map(
          (col, idx) => html`<div
                    class="column-with-header ${idx ? "column-divider" : ""}"
                  >
                    <div class="column-header">
                      <div class="subtitle-container">
                        <div class="subtitle-text">Group ${idx + 1}</div>
                      </div>
                    </div>
                    <div class="column-content">${renderColumn(col)}</div>
                  </div>`
        )}
            </div>
          </div>
        </div>`;
      }
      const allCols = [];
      this.columnGroups.forEach((g, gIdx) => {
        const calculatedCols = Math.ceil(
          g.options.length / this.itemsPerColumn
        );
        const actualCols = Math.max(g.columns, calculatedCols);
        const distributed = this.chunkArray(
          g.options,
          this.itemsPerColumn,
          actualCols
        );
        distributed.forEach((opts, idx) => {
          allCols.push({
            options: opts,
            groupTitle: g.title,
            isFirstInGroup: idx === 0,
            isFirstGroup: gIdx === 0,
            colIdx: idx
          });
        });
      });
      return html`<div class="multi-content">
        <div class="multi-columns">
          <div class="columns-container">
            ${allCols.map(
        (c) => html`<div
                  class="column-with-header ${!c.isFirstGroup && c.isFirstInGroup ? "column-divider" : ""}"
                >
                  ${c.isFirstInGroup ? html`<div class="column-header">
                        <div class="subtitle-container">
                          <div class="subtitle-text">${c.groupTitle}</div>
                        </div>
                      </div>` : html`<div class="column-header-spacer"></div>`}
                  <div class="column-content">${renderColumn(c.options)}</div>
                </div>`
      )}
          </div>
        </div>
      </div>`;
    }
    const columns = this.chunkArray(this.options, this.itemsPerColumn);
    return html`<div class="multi-content">
      <div class="multi-columns">
        ${columns.map(
      (col, idx) => html`<div class="column ${idx ? "column-divider" : ""}">
              ${renderColumn(col)}
            </div>`
    )}
      </div>
    </div>`;
  }
  chunkArray(arr, size, forcedColumns) {
    if (forcedColumns) {
      const out = Array.from({ length: forcedColumns }, () => []);
      arr.forEach((item, idx) => out[Math.floor(idx / size)].push(item));
      return out;
    }
    const result = [];
    for (let i = 0; i < arr.length; i += size)
      result.push(arr.slice(i + 0, i + size));
    return result;
  }
  renderMenuContent() {
    switch (this.type) {
      case "checkboxes":
      case "nested-checkboxes":
        return this.renderCheckboxItems();
      case "flyout":
        return this.renderFlyoutItems();
      case "multi":
      case "multi-with-subtitles":
        return this.renderMultiColumnItems();
      default:
        return this.renderRegularItems();
    }
  }
  render() {
    return html`<div
      class=${classMap({
      "context-menu": true,
      [`type-${this.type}`]: true,
      "has-title": this.hasTitleBar
    })}
      role="menu"
      aria-label=${this.hasTitleBar ? this.title : "Context menu"}
    >
      ${this.renderTitleBar()}
      <div class="menu-content">${this.renderMenuContent()}</div>
    </div>`;
  }
};
ObcContextMenuInput.styles = unsafeCSS(compentStyle);
__decorateClass([
  property({ type: String })
], ObcContextMenuInput.prototype, "type", 2);
__decorateClass([
  property({ type: Array })
], ObcContextMenuInput.prototype, "options", 2);
__decorateClass([
  property({ type: Array })
], ObcContextMenuInput.prototype, "selectedValues", 2);
__decorateClass([
  property({ type: Boolean })
], ObcContextMenuInput.prototype, "hasTitleBar", 2);
__decorateClass([
  property({ type: String })
], ObcContextMenuInput.prototype, "title", 2);
__decorateClass([
  property({ type: Array })
], ObcContextMenuInput.prototype, "columnGroups", 2);
__decorateClass([
  property({ type: Number })
], ObcContextMenuInput.prototype, "itemsPerColumn", 2);
__decorateClass([
  property({ type: Boolean })
], ObcContextMenuInput.prototype, "multiSelect", 2);
__decorateClass([
  property({ type: Boolean, reflect: true })
], ObcContextMenuInput.prototype, "selectPerGroup", 2);
ObcContextMenuInput = __decorateClass([
  customElement("obc-context-menu-input")
], ObcContextMenuInput);
function arraysEqual(a, b) {
  if (a.length !== b.length) return false;
  const setA = new Set(a);
  return b.every((v) => setA.has(v));
}
export {
  ContextMenuType,
  ObcContextMenuInput
};
//# sourceMappingURL=context-menu-input.js.map
