import { html, nothing } from 'lit';
import { state, query, property } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';
import { boolean } from '../../internal/boolean.mjs';
import FlowRdfElement from '../../internal/flow-ui-rdf-element.mjs';
import { HasSlotController } from '../../internal/slot.mjs';
import { watch } from '../../internal/watch.mjs';
import styles from './list-item.styles.mjs';
import { ifDefined } from 'lit/directives/if-defined.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;
};
class FlowUiListItem extends FlowRdfElement {
  constructor() {
    super();
    this.hasSlotController = new HasSlotController(this, "prefix", "suffix", "menu");
    this.hasFocus = false;
    this.editMenuName = "Edit";
    this.checked = false;
    this.editable = false;
    this.reorder = false;
    this.removable = false;
    this.disabled = false;
    this.selectable = false;
    this.handleDragStart = (ev) => {
      ev.stopPropagation();
      ev.dataTransfer.setData("application/flow-ui-list-item", this.value);
      ev.dataTransfer.effectAllowed = "move";
      this.emit("flow-ui-drag-start");
    };
    this.handleDragStart = this.handleDragStart.bind(this);
    this.handleDragOver = this.handleDragOver.bind(this);
    this.handleDrop = this.handleDrop.bind(this);
    this.handleDragEnd = this.handleDragEnd.bind(this);
    this.handleBlur = this.handleBlur.bind(this);
    this.handleFocus = this.handleFocus.bind(this);
  }
  connectedCallback() {
    super.connectedCallback();
    this.editable = boolean(this.editable, true);
    this.reorder = boolean(this.reorder, true);
    this.removable = boolean(this.removable, true);
    this.checked = boolean(this.checked, true);
    this.disabled = boolean(this.disabled, true);
    this.setAttribute("tabindex", "-1");
    this.addEventListeners();
  }
  disconnectedCallback() {
    super.disconnectedCallback();
    this.removeEventListeners();
  }
  /** @deprecated Use `edit` instead */
  rename() {
    this.input.focus();
  }
  edit() {
    this.input.focus();
  }
  handleCheckedChange() {
    this.setAttribute("aria-checked", this.checked ? "true" : "false");
    this.setAttribute("tabindex", this.checked ? "0" : "-1");
  }
  addEventListeners() {
    this.addEventListener("blur", this.handleBlur);
    this.addEventListener("focus", this.handleFocus);
    this.addEventListener("dragover", this.handleDragOver);
    this.addEventListener("drop", this.handleDrop);
  }
  removeEventListeners() {
    this.removeEventListener("blur", this.handleBlur);
    this.removeEventListener("focus", this.handleFocus);
    this.removeEventListener("dragover", this.handleDragOver);
    this.removeEventListener("drop", this.handleDrop);
  }
  handleBlur() {
    this.hasFocus = false;
    this.emit("flow-ui-blur");
  }
  handleFocus() {
    this.hasFocus = true;
    this.emit("flow-ui-focus");
  }
  handleMenuSelect(ev) {
    const menuItem = ev.detail.item;
    if (menuItem.value === "edit") {
      this.updateComplete.then(() => this.edit());
    } else if (menuItem.value === "remove") {
      const requestRemove = this.emit("flow-ui-remove", { cancelable: true });
      if (!requestRemove.defaultPrevented) {
        this.remove();
      }
    }
  }
  handleInputEvents(ev) {
    if (ev.type === "flow-ui-change") {
      this.label = this.input.value;
      this.input.blur();
    } else {
      ev.stopPropagation();
    }
  }
  handleReorderPointerDown(_ev) {
    this.addEventListener("dragstart", this.handleDragStart);
    this.addEventListener("dragend", this.handleDragEnd);
    this.setAttribute("draggable", "true");
  }
  handleReorderPointerUp(_ev) {
    this.removeEventListener("dragstart", this.handleDragStart);
    this.removeEventListener("dragend", this.handleDragEnd);
    this.removeAttribute("draggable");
  }
  handleDragOver(ev) {
    ev.stopPropagation();
    ev.preventDefault();
    if (ev.dataTransfer?.types.includes("application/flow-ui-list-item")) {
      ev.dataTransfer.dropEffect = "move";
      this.emit("flow-ui-drag-over");
    }
  }
  handleDragEnd(ev) {
    ev.stopPropagation();
    this.removeEventListener("dragstart", this.handleDragStart);
    this.removeEventListener("dragend", this.handleDragEnd);
    this.removeAttribute("draggable");
    this.emit("flow-ui-drag-end");
  }
  handleDrop(ev) {
    ev.preventDefault();
    ev.stopPropagation();
    this.emit("flow-ui-drag-drop");
  }
  renderMenu() {
    const hasCustomMenuDivider = (this.editable || this.removable) && this.hasSlotController.test("menu");
    return html`
      <flow-ui-dropdown placement="bottom-end" class="list-item__menu-dropdown">
        <flow-ui-icon-button
          part="menu-button"
          class="list-item__menu-button"
          slot="trigger"
          name="ellipsis-vertical"
          library="system"
        ></flow-ui-icon-button>
        <flow-ui-menu @flow-ui-select=${this.handleMenuSelect}>
          ${this.editable ? html`
                <flow-ui-menu-item value="edit">${this.editMenuName}</flow-ui-menu-item>
              ` : nothing}
          ${this.removable ? html`
                <flow-ui-menu-item value="remove">Delete</flow-ui-menu-item>
              ` : nothing}
          ${hasCustomMenuDivider ? html`
                <flow-ui-divider></flow-ui-divider>
              ` : nothing}
          ${this.hasSlotController.test("menu") ? html`
                <slot name="menu"></slot>
              ` : nothing}
        </flow-ui-menu>
        <slot name="menu"></slot>
      </flow-ui-dropdown>
    `;
  }
  render() {
    const hasMenu = this.editable || this.removable || this.hasSlotController.test("menu");
    return html`
      <div
        part="base"
        class=${classMap({
      "list-item": true,
      "list-item--checked": this.checked,
      "list-item--has-prefix": this.hasSlotController.test("prefix"),
      "list-item--has-suffix": this.hasSlotController.test("suffix"),
      "list-item--has-menu": this.hasSlotController.test("menu"),
      "list-item--editable": this.editable,
      "list-item--selectable": this.selectable,
      "list-item--focused": this.hasFocus,
      "list-item--disabled": this.disabled
    })}
      >
        ${this.reorder ? html`
              <flow-ui-icon
                part="reorder-icon"
                name="bars"
                library="system"
                class="list-item__reorder-icon"
                @pointerdown=${this.handleReorderPointerDown}
                @pointerup=${this.handleReorderPointerUp}
              ></flow-ui-icon>
            ` : nothing}
        <slot name="prefix" part="prefix" class="list-item__prefix"></slot>

        <flow-ui-input
          exportparts="input"
          filled
          class="list-item__input"
          .value=${this.label}
          .readonly=${!this.editable}
          placeholder=${ifDefined(this.placeholder)}
          tabindex=${this.editable ? "0" : "-1"}
          @flow-ui-change=${this.handleInputEvents}
          @flow-ui-input=${this.handleInputEvents}
        ></flow-ui-input>
        <!--<div class="list-item__spacer"></div>-->
        <slot name="suffix" part="suffix" class="list-item__suffix"></slot>

        ${hasMenu ? this.renderMenu() : nothing}
      </div>
    `;
  }
}
FlowUiListItem.styles = styles;
__decorateClass([
  state()
], FlowUiListItem.prototype, "hasFocus", 2);
__decorateClass([
  query(".list-item__input")
], FlowUiListItem.prototype, "input", 2);
__decorateClass([
  property({ reflect: true })
], FlowUiListItem.prototype, "label", 2);
__decorateClass([
  property({ attribute: "edit-menu-name" })
], FlowUiListItem.prototype, "editMenuName", 2);
__decorateClass([
  property()
], FlowUiListItem.prototype, "placeholder", 2);
__decorateClass([
  property({ reflect: true })
], FlowUiListItem.prototype, "value", 2);
__decorateClass([
  property({ type: Boolean, reflect: true })
], FlowUiListItem.prototype, "checked", 2);
__decorateClass([
  property({ type: Boolean, reflect: true })
], FlowUiListItem.prototype, "editable", 2);
__decorateClass([
  property({ type: Boolean, reflect: true })
], FlowUiListItem.prototype, "reorder", 2);
__decorateClass([
  property({ type: Boolean, reflect: true })
], FlowUiListItem.prototype, "removable", 2);
__decorateClass([
  property({ type: Boolean, reflect: true })
], FlowUiListItem.prototype, "disabled", 2);
__decorateClass([
  property({ type: Boolean, reflect: true })
], FlowUiListItem.prototype, "selectable", 2);
__decorateClass([
  watch("checked")
], FlowUiListItem.prototype, "handleCheckedChange", 1);

export { FlowUiListItem as default };
