import { createStyleMixin, draggableMixin, componentNameValidationMixin } from '../../mixins';
import { createBaseClass } from '../../baseClasses/createBaseClass';
import { compose } from '../../helpers';
import { getComponentName } from '../../helpers/componentHelpers';
import { TextClass } from '@descope-ui/descope-text/class';
import { ButtonClass } from '@descope-ui/descope-button/class';
import { BadgeClass } from '@descope-ui/descope-badge/class';
import { injectStyle } from '@descope-ui/common/components-helpers';
import deleteIcon from './delete.svg';
import editIcon from './edit.svg';

export const componentName = getComponentName('user-attribute');
class RawUserAttribute extends createBaseClass({
  componentName,
  baseSelector: ':host > .root',
}) {
  constructor() {
    super();

    this.attachShadow({ mode: 'open' }).innerHTML = `
      <div class="root">
        <descope-text st-text-align="auto" data-id="label-text" variant="body1" mode="secondary" class="label"></descope-text>
        <div class="content-wrapper">
          <descope-text st-text-align="auto" data-id="value-text" variant="body1" mode="primary" class="value"></descope-text>
          <div class="btn-wrapper">
            <descope-badge mode="default" bordered="true" size="xs"></descope-badge>
            <descope-button size="xs" data-id="edit-btn" square="true" variant="link" mode="primary">
              <slot name="edit-icon"></slot>
            </descope-button>
            <descope-button size="xs" data-id="delete-btn" square="true" variant="link" mode="primary">
              <slot name="delete-icon"></slot>
            </descope-button>
          </div>
        </div>
      </div>
		`;

    injectStyle(
      `
      :host {
					display: inline-flex;
          container-type: inline-size;
				}

        .root {
          display: flex;
          width: 100%;
          height: 100%;
          align-items: center;
        }
        
        ::slotted(*) {
          display: flex;
          align-items: center;
          justify-content: center;
        }

        @container (max-width: 529px) {
          .root {
            flex-wrap: wrap;
          }
        }

        .btn-wrapper {
          display: flex;
          justify-content: space-between;
          align-items: center;
          flex-grow: 0;
        }

        .content-wrapper {
          display: flex;
          flex-grow: 1;
          align-items: center;
        }

        descope-text::part(text-wrapper) {
          text-overflow: ellipsis;
          overflow: hidden;
          white-space: nowrap;
          width: initial;
        }

        descope-text {
          display: inline-flex;
          max-width: 100%;
          min-width: 0;
        }

        .label {
          flex-grow: 1;
          width: 100%;
        }

        .value {
          flex-grow: 1;
        }

        descope-badge {
          margin-inline-end: 10px;
        }

        .hidden {
          visibility: hidden;
        }

        descope-text[data-id="label-text"].required:after {
          content: '*';
          color: var(${TextClass.cssVarList.textColor});
        }

        :host([readonly="true"]) descope-button {
          visibility: hidden;
        }
          `,
      this
    );

    this.deleteButton = this.shadowRoot.querySelector('descope-button[data-id="delete-btn"]');
    this.editButton = this.shadowRoot.querySelector('descope-button[data-id="edit-btn"]');
    this.badge = this.shadowRoot.querySelector('descope-badge');
    this.labelText = this.shadowRoot.querySelector('descope-text[data-id="label-text"]');
    this.valueText = this.shadowRoot.querySelector('descope-text[data-id="value-text"]');
  }

  onLabelChange() {
    this.labelText.innerText = this.label;
    this.labelText.setAttribute('title', this.label);
  }

  onValueOrPlaceholderChange() {
    const text = this.value || this.placeholder;
    const mode = this.value ? 'primary' : 'secondary';

    this.valueText.innerText = text;
    this.valueText.setAttribute('title', text);
    this.valueText.setAttribute('mode', mode);
  }

  onBadgeLabelChange() {
    if (!this.badgeLabel) {
      this.badge.style.display = 'none';
    } else {
      this.badge.innerText = this.badgeLabel;
      this.badge.style.display = '';
    }
  }

  onBadgeTooltipTextChange() {
    this.badge.setAttribute('title', this.badgeTooltipText || this.badgeLabel);
  }

  onIsRequiredChange() {
    this.labelText.classList.toggle('required', this.isRequired);
  }

  get label() {
    return this.getAttribute('label') || '';
  }

  get value() {
    return this.getAttribute('value') || '';
  }

  get placeholder() {
    return this.getAttribute('placeholder') || '';
  }

  get isRequired() {
    return this.getAttribute('required') === 'true';
  }

  get badgeLabel() {
    return this.getAttribute('badge-label') || '';
  }

  get badgeTooltipText() {
    return this.getAttribute('badge-tooltip-text') || '';
  }

  init() {
    this.onLabelChange();
    this.onValueOrPlaceholderChange();
    this.onIsRequiredChange();
    this.onBadgeLabelChange();
    this.onBadgeTooltipTextChange();
    this.handleDeleteButtonVisibility();

    this.deleteButton.addEventListener('click', () =>
      this.dispatchEvent(new CustomEvent('delete-clicked', { bubbles: true, composed: true }))
    );

    this.editButton.addEventListener('click', () =>
      this.dispatchEvent(new CustomEvent('edit-clicked', { bubbles: true, composed: true }))
    );

    this.setDefaultChildren();
  }

  #addIcon(src, slotName) {
    const icon = document.createElement('descope-icon');
    icon.setAttribute('src', src);
    icon.setAttribute('src-dark', src);
    icon.setAttribute('slot', slotName);
    this.appendChild(icon);
  }

  setDefaultChildren() {
    if (this.children.length) return;
    this.#addIcon(deleteIcon, 'delete-icon');
    this.#addIcon(editIcon, 'edit-icon');
  }

  static get observedAttributes() {
    return [
      'label',
      'value',
      'placeholder',
      'required',
      'badge-label',
      'badge-tooltip-text',
    ].concat(super.observedAttributes);
  }

  handleDeleteButtonVisibility() {
    this.deleteButton.classList.toggle('hidden', this.isRequired || !this.value);
  }

  attributeChangedCallback(name, oldValue, newValue) {
    super.attributeChangedCallback?.(name, oldValue, newValue);

    if (oldValue === newValue) {
      return;
    }

    if (name === 'label') {
      this.onLabelChange();
    } else if (name === 'value' || name === 'placeholder') {
      this.onValueOrPlaceholderChange();
    } else if (name === 'required') {
      this.onIsRequiredChange();
    } else if (name === 'badge-label') {
      this.onBadgeLabelChange();
    } else if (name === 'badge-tooltip-text') {
      this.onBadgeTooltipTextChange();
    }

    if (name === 'value' || name === 'required') {
      this.handleDeleteButtonVisibility();
    }
  }
}

const { host, textFields, buttons, badge, labelText, contentWrapper } = {
  host: { selector: () => ':host' },
  textFields: { selector: 'descope-text' },
  labelText: { selector: 'descope-text[data-id="label-text"]' },
  buttons: { selector: 'descope-button' },
  badge: { selector: 'descope-badge' },
  contentWrapper: { selector: ' .content-wrapper' },
};

export const UserAttributeClass = compose(
  createStyleMixin({
    mappings: {
      hostWidth: { ...host, property: 'width' },
      hostMinWidth: { ...host, property: 'min-width' },
      hostMaxWidth: { ...host, property: 'max-width' },
      hostDirection: [
        { ...host, property: 'direction' },
        { ...textFields, property: TextClass.cssVarList.hostDirection },
        { ...buttons, property: ButtonClass.cssVarList.hostDirection },
        { ...badge, property: BadgeClass.cssVarList.hostDirection },
      ],
      labelMinWidth: { ...labelText, property: 'min-width' },
      contentMinWidth: { ...contentWrapper, property: 'min-width' },
      badgeMaxWidth: { ...badge, property: 'max-width' },
      itemsGap: [{ property: 'gap' }, { ...contentWrapper, property: 'gap' }],
    },
  }),
  draggableMixin,
  componentNameValidationMixin
)(RawUserAttribute);
