/**
 * DS Button - Web Component
 *
 * Usage:
 *   <ds-button variant="primary" size="default">Click me</ds-button>
 *   <ds-button variant="outline" disabled>Disabled</ds-button>
 *   <ds-button variant="ghost" size="icon"><svg>...</svg></ds-button>
 *
 * Attributes:
 *   - variant: primary | secondary | outline | ghost | destructive | success | link
 *   - size: sm | default | lg | icon | icon-sm | icon-lg
 *   - disabled: boolean
 *   - loading: boolean
 *   - type: button | submit | reset
 */

class DsButton extends HTMLElement {
  static get observedAttributes() {
    return ['variant', 'size', 'disabled', 'loading', 'type', 'tabindex', 'aria-label', 'aria-expanded', 'aria-pressed'];
  }

  constructor() {
    super();
    this.attachShadow({ mode: 'open' });
  }

  connectedCallback() {
    this.render();
    this.setupEventListeners();
  }

  disconnectedCallback() {
    this.cleanupEventListeners();
  }

  attributeChangedCallback() {
    if (this.shadowRoot.innerHTML) {
      this.render();
    }
  }

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

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

  get disabled() {
    return this.hasAttribute('disabled');
  }

  get loading() {
    return this.hasAttribute('loading');
  }

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

  setupEventListeners() {
    const button = this.shadowRoot.querySelector('button');

    // Store handler references for cleanup
    this.clickHandler = (e) => {
      if (this.disabled || this.loading) {
        e.preventDefault();
        e.stopPropagation();
        return;
      }
      this.dispatchEvent(new CustomEvent('ds-click', {
        bubbles: true,
        composed: true,
        detail: { originalEvent: e }
      }));
    };

    this.keydownHandler = (e) => {
      // Enter or Space to activate button
      if ((e.key === 'Enter' || e.key === ' ') && !this.disabled && !this.loading) {
        e.preventDefault();
        button.click();
      }
    };

    this.focusHandler = (e) => {
      // Delegate focus to internal button
      if (e.target === this && !this.disabled) {
        button.focus();
      }
    };

    button.addEventListener('click', this.clickHandler);
    this.addEventListener('keydown', this.keydownHandler);
    this.addEventListener('focus', this.focusHandler);
  }

  cleanupEventListeners() {
    const button = this.shadowRoot?.querySelector('button');
    if (button && this.clickHandler) {
      button.removeEventListener('click', this.clickHandler);
      delete this.clickHandler;
    }
    if (this.keydownHandler) {
      this.removeEventListener('keydown', this.keydownHandler);
      delete this.keydownHandler;
    }
    if (this.focusHandler) {
      this.removeEventListener('focus', this.focusHandler);
      delete this.focusHandler;
    }
  }

  getVariantClass() {
    const variants = {
      primary: 'ds-btn--primary',
      secondary: 'ds-btn--secondary',
      outline: 'ds-btn--outline',
      ghost: 'ds-btn--ghost',
      destructive: 'ds-btn--destructive',
      success: 'ds-btn--success',
      link: 'ds-btn--link'
    };
    return variants[this.variant] || variants.primary;
  }

  getSizeClass() {
    const sizes = {
      sm: 'ds-btn--sm',
      default: '',
      lg: 'ds-btn--lg',
      icon: 'ds-btn--icon',
      'icon-sm': 'ds-btn--icon-sm',
      'icon-lg': 'ds-btn--icon-lg'
    };
    return sizes[this.size] || '';
  }

  render() {
    const variantClass = this.getVariantClass();
    const sizeClass = this.getSizeClass();
    const disabledAttr = this.disabled || this.loading ? 'disabled' : '';
    const tabindex = this.disabled ? '-1' : (this.getAttribute('tabindex') || '0');

    // ARIA attributes delegation
    const ariaLabel = this.getAttribute('aria-label') ? `aria-label="${this.getAttribute('aria-label')}"` : '';
    const ariaExpanded = this.getAttribute('aria-expanded') ? `aria-expanded="${this.getAttribute('aria-expanded')}"` : '';
    const ariaPressed = this.getAttribute('aria-pressed') ? `aria-pressed="${this.getAttribute('aria-pressed')}"` : '';
    const ariaAttrs = `${ariaLabel} ${ariaExpanded} ${ariaPressed}`.trim();

    this.shadowRoot.innerHTML = `
      <style>

        :host {
          display: inline-block;
        }

        button {
          width: 100%;
        }

        button:focus-visible {
          outline: 2px solid var(--primary);
          outline-offset: 2px;
        }

        .loading-spinner {
          display: inline-block;
          width: 1rem;
          height: 1rem;
          border: 2px solid currentColor;
          border-top-color: transparent;
          border-radius: 50%;
          animation: spin 0.75s linear infinite;
        }

        @keyframes spin {
          to { transform: rotate(360deg); }
        }
      </style>
      <button
        class="ds-btn ${variantClass} ${sizeClass}"
        type="${this.type}"
        tabindex="${tabindex}"
        ${disabledAttr}
        ${ariaAttrs}
      >
        ${this.loading ? '<span class="loading-spinner"></span>' : ''}
        <slot></slot>
      </button>
    `;
  }
}

customElements.define('ds-button', DsButton);

export default DsButton;
